mirror of
https://github.com/morten-olsen/mini-loader.git
synced 2026-02-08 01:36:26 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c5249956e | ||
|
|
b5d8cf3a51 | ||
|
|
5154fbb4a5 | ||
|
|
59d6faaafc |
5
.devcontainer/devcontainer.json
Normal file
5
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"features": {
|
||||
}
|
||||
}
|
||||
60
.github/workflows/release.yml
vendored
60
.github/workflows/release.yml
vendored
@@ -91,33 +91,33 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
# release-npm:
|
||||
# if: github.ref == 'refs/heads/main'
|
||||
# runs-on: ubuntu-latest
|
||||
# needs: [build, update-release-draft]
|
||||
# permissions:
|
||||
# contents: read
|
||||
# packages: write
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# - run: corepack enable
|
||||
# - uses: actions/setup-node@v3
|
||||
# with:
|
||||
# cache: '${{ env.NODE_CACHE }}'
|
||||
# node-version: '${{ env.NODE_VERSION }}'
|
||||
# scope: '${{ env.NODE_SCOPE }}'
|
||||
# - uses: actions/download-artifact@v3
|
||||
# with:
|
||||
# name: lib
|
||||
# path: ./
|
||||
# - run: |
|
||||
# pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
# pnpm install
|
||||
# git config user.name "Github Actions Bot"
|
||||
# git config user.email "<>"
|
||||
# node scripts/set-version.ts $(git describe --tag --abbrev=0)
|
||||
# pnpm publish -r --publish-branch main --access public --no-git-checks
|
||||
# env:
|
||||
# NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
release-npm:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, update-release-draft]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: corepack enable
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: '${{ env.NODE_CACHE }}'
|
||||
node-version: '${{ env.NODE_VERSION }}'
|
||||
scope: '${{ env.NODE_SCOPE }}'
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: lib
|
||||
path: ./
|
||||
- run: |
|
||||
pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
pnpm install
|
||||
git config user.name "Github Actions Bot"
|
||||
git config user.email "<>"
|
||||
node scripts/set-version.mjs $(git describe --tag --abbrev=0)
|
||||
pnpm publish -r --publish-branch main --access public --no-git-checks
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
@@ -15,14 +15,19 @@ npm install -g @morten-olsen/mini-loader-cli
|
||||
Now, let's write a basic script that outputs a single artifact named “hello”. Create a new file with the following JavaScript code:
|
||||
|
||||
```javascript
|
||||
import { artifacts } from "@morten-olsen/mini-loader";
|
||||
import { artifacts } from '@morten-olsen/mini-loader';
|
||||
|
||||
const run = async () => {
|
||||
artifacts.create('hello', 'world');
|
||||
};
|
||||
|
||||
run();
|
||||
```
|
||||
|
||||
Save this file as `script.mjs`.
|
||||
Save this file as `script.js`.
|
||||
|
||||
#### A Note on Dependencies
|
||||
|
||||
In this script, we're using the `@morten-olsen/mini-loader` package, which might not be installed in your local environment. No worries though, as mini loader can automatically download necessary packages when preparing the script. Alternatively, for a more structured approach (especially if you're using TypeScript), you can initialize a Node.js project and install the dependencies for complete access to typings.
|
||||
|
||||
### Step 3: Run the Script Locally
|
||||
@@ -30,7 +35,7 @@ In this script, we're using the `@morten-olsen/mini-loader` package, which might
|
||||
To validate that your script is functioning correctly, execute it locally using the following command:
|
||||
|
||||
```bash
|
||||
mini-loader local run script.mjs -ai
|
||||
mini-loader local run script.js -ai
|
||||
```
|
||||
|
||||
The `-ai` flag instructs the CLI to automatically download any referenced packages when bundling the script.
|
||||
|
||||
@@ -58,7 +58,7 @@ mini-loader artifacts ls
|
||||
To download a specific artifact:
|
||||
|
||||
```bash
|
||||
mini-loader artifacts pull <id> > myfile.txt
|
||||
mini-loader artifacts pull <id> myfile.txt
|
||||
```
|
||||
|
||||
Replace `<id>` with the identifier of the artifact you wish to download.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader-repo",
|
||||
"private": "true",
|
||||
"license": "GPL-3.0",
|
||||
"packageManager": "pnpm@8.10.4",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
@@ -11,7 +12,6 @@
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@react-native-community/eslint-config": "^3.2.0",
|
||||
"eslint": "^8.53.0",
|
||||
@@ -23,5 +23,10 @@
|
||||
"@pnpm/find-workspace-packages": "^6.0.9",
|
||||
"@types/node": "^20.10.8",
|
||||
"ts-node": "^10.9.2"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
1
packages/cli/README.md
Normal file
1
packages/cli/README.md
Normal file
@@ -0,0 +1 @@
|
||||
[Go to documentation](https://github.com/morten-olsen/mini-loader)
|
||||
@@ -3,6 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"main": "./dist/esm/index.js",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"license": "GPL-3.0",
|
||||
"bin": {
|
||||
"mini-loader": "./bin/index.mjs"
|
||||
},
|
||||
@@ -27,6 +28,7 @@
|
||||
"@rollup/plugin-sucrase": "^5.0.2",
|
||||
"@trpc/client": "^10.45.0",
|
||||
"commander": "^11.1.0",
|
||||
"env-paths": "^3.0.0",
|
||||
"inquirer": "^9.2.12",
|
||||
"ora": "^8.0.1",
|
||||
"rollup": "^4.9.4",
|
||||
@@ -40,5 +42,10 @@
|
||||
"@morten-olsen/mini-loader-server": "workspace:^",
|
||||
"@types/inquirer": "^9.0.7",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,20 @@ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
||||
import superjson from 'superjson';
|
||||
import type { Runtime } from '@morten-olsen/mini-loader-server';
|
||||
import type { RootRouter } from '@morten-olsen/mini-loader-server';
|
||||
import { Context } from '../context/context.js';
|
||||
|
||||
const createClient = () => {
|
||||
const createClient = (context: Context) => {
|
||||
if (!context.host || !context.token) {
|
||||
throw new Error('Not signed in');
|
||||
}
|
||||
const client = createTRPCProxyClient<RootRouter>({
|
||||
transformer: superjson,
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: 'http://localhost:4500/trpc',
|
||||
url: `${context.host}/trpc`,
|
||||
headers: {
|
||||
authorization: `Bearer ${context.token}`,
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const list = new Command('list');
|
||||
|
||||
@@ -20,8 +22,10 @@ list
|
||||
.option('-a, --limit <limit>', 'Limit', '1000')
|
||||
.action(async () => {
|
||||
const { runId, loadId, offset, limit } = list.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const artifacts = await step('Getting artifacts', async () => {
|
||||
return await client.artifacts.find.query({
|
||||
|
||||
34
packages/cli/src/commands/artifacts/artifacts.pull.ts
Normal file
34
packages/cli/src/commands/artifacts/artifacts.pull.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { dirname, resolve } from 'path';
|
||||
import { mkdir, writeFile } from 'fs/promises';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const pull = new Command('pull');
|
||||
|
||||
pull
|
||||
.description('Download artifact')
|
||||
.argument('<artifact-id>', 'Artifact ID')
|
||||
.argument('<file>', 'File to save')
|
||||
.action(async (id, file) => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const target = resolve(file);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient(context);
|
||||
});
|
||||
const artifact = await step('Getting artifact', async () => {
|
||||
const result = await client.artifacts.get.query(id);
|
||||
if (!result) {
|
||||
throw new Error('Artifact not found');
|
||||
}
|
||||
return result;
|
||||
});
|
||||
await mkdir(dirname(target), { recursive: true });
|
||||
const data = Buffer.from(artifact.data, 'base64').toString('utf-8');
|
||||
await writeFile(target, data, 'utf-8');
|
||||
});
|
||||
|
||||
export { pull };
|
||||
61
packages/cli/src/commands/artifacts/artifacts.remove.ts
Normal file
61
packages/cli/src/commands/artifacts/artifacts.remove.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import inquirer from 'inquirer';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const remove = new Command('remove');
|
||||
|
||||
const toInt = (value?: string) => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
return parseInt(value, 10);
|
||||
};
|
||||
|
||||
remove
|
||||
.alias('ls')
|
||||
.description('List logs')
|
||||
.option('-r, --run-id <runId>', 'Run ID')
|
||||
.option('-l, --load-id <loadId>', 'Load ID')
|
||||
.option('-o, --offset <offset>', 'Offset')
|
||||
.option('-a, --limit <limit>', 'Limit', '1000')
|
||||
.action(async () => {
|
||||
const { runId, loadId, offset, limit } = remove.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient(context);
|
||||
});
|
||||
const response = await step('Preparing to delete', async () => {
|
||||
return await client.artifacts.prepareRemove.query({
|
||||
runId,
|
||||
loadId,
|
||||
offset: toInt(offset),
|
||||
limit: toInt(limit),
|
||||
});
|
||||
});
|
||||
|
||||
if (!response.ids.length) {
|
||||
console.log('No logs to delete');
|
||||
return;
|
||||
}
|
||||
const { confirm } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: `Are you sure you want to delete ${response.ids.length} logs?`,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
await step('Deleting artifacts', async () => {
|
||||
await client.artifacts.remove.mutate(response);
|
||||
});
|
||||
});
|
||||
|
||||
export { remove };
|
||||
@@ -1,7 +1,11 @@
|
||||
import { Command } from 'commander';
|
||||
import { list } from './artifacts.list.js';
|
||||
import { remove } from './artifacts.remove.js';
|
||||
import { pull } from './artifacts.pull.js';
|
||||
|
||||
const artifacts = new Command('artifacts');
|
||||
artifacts.addCommand(list);
|
||||
artifacts.addCommand(remove);
|
||||
artifacts.addCommand(pull);
|
||||
|
||||
export { artifacts };
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import { Command } from 'commander';
|
||||
import inquerer from 'inquirer';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const login = new Command('login');
|
||||
|
||||
login.description('Login to your account');
|
||||
login.action(async () => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const { host, token } = await inquerer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'host',
|
||||
message: 'Enter the host of your server',
|
||||
default: 'http://localhost:4500',
|
||||
default: context.host ?? 'http://localhost:4500',
|
||||
},
|
||||
{
|
||||
type: 'password',
|
||||
@@ -19,7 +24,25 @@ login.action(async () => {
|
||||
},
|
||||
]);
|
||||
|
||||
console.log(host, token);
|
||||
const healthResponse = await step('Getting auth status', async () => {
|
||||
return await fetch(`${host}/health`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
if (!healthResponse.ok) {
|
||||
throw new Error('Invalid token');
|
||||
}
|
||||
const health = await healthResponse.json();
|
||||
if (!health.authorized) {
|
||||
throw new Error('Invalid token');
|
||||
}
|
||||
|
||||
await step('Saving login', async () => {
|
||||
await context.saveLogin(host, token);
|
||||
});
|
||||
});
|
||||
|
||||
export { login };
|
||||
|
||||
10
packages/cli/src/commands/contexts/contexts.current.ts
Normal file
10
packages/cli/src/commands/contexts/contexts.current.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Command } from 'commander';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const current = new Command('current');
|
||||
current.action(async () => {
|
||||
const config = new Config();
|
||||
console.log(config.context);
|
||||
});
|
||||
|
||||
export { current };
|
||||
11
packages/cli/src/commands/contexts/contexts.list.ts
Normal file
11
packages/cli/src/commands/contexts/contexts.list.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Command } from 'commander';
|
||||
import { Context } from '../../context/context.js';
|
||||
|
||||
const list = new Command('list');
|
||||
list.alias('ls').description('List contexts');
|
||||
list.action(async () => {
|
||||
const contexts = await Context.list();
|
||||
console.table(contexts);
|
||||
});
|
||||
|
||||
export { list };
|
||||
12
packages/cli/src/commands/contexts/contexts.ts
Normal file
12
packages/cli/src/commands/contexts/contexts.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Command } from 'commander';
|
||||
import { list } from './contexts.list.js';
|
||||
import { use } from './contexts.use.js';
|
||||
import { current } from './contexts.current.js';
|
||||
|
||||
const contexts = new Command('contexts');
|
||||
contexts.description('Manage contexts');
|
||||
contexts.addCommand(list);
|
||||
contexts.addCommand(use);
|
||||
contexts.addCommand(current);
|
||||
|
||||
export { contexts };
|
||||
11
packages/cli/src/commands/contexts/contexts.use.ts
Normal file
11
packages/cli/src/commands/contexts/contexts.use.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Command } from 'commander';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const use = new Command('use');
|
||||
|
||||
use.argument('<name>').action(async (name) => {
|
||||
const config = new Config();
|
||||
await config.setContext(name);
|
||||
});
|
||||
|
||||
export { use };
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const list = new Command('list');
|
||||
|
||||
@@ -8,11 +10,13 @@ list
|
||||
.alias('ls')
|
||||
.description('List loads')
|
||||
.action(async () => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const loads = step('Getting data', async () => {
|
||||
await client.loads.find.query({});
|
||||
const loads = await step('Getting data', async () => {
|
||||
return await client.loads.find.query({});
|
||||
});
|
||||
console.table(loads);
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ import { resolve } from 'path';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { bundle } from '../../bundler/bundler.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const push = new Command('push');
|
||||
|
||||
@@ -14,9 +16,11 @@ push
|
||||
.option('-ai, --auto-install', 'Auto install dependencies', false)
|
||||
.action(async (script) => {
|
||||
const opts = push.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const location = resolve(script);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const code = await step('Bundling', async () => {
|
||||
return await bundle({ entry: location, autoInstall: opts.autoInstall });
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const list = new Command('list');
|
||||
|
||||
@@ -22,8 +24,10 @@ list
|
||||
.option('-s, --sort <order>', 'Sort', 'desc')
|
||||
.action(async () => {
|
||||
const { runId, loadId, severities, offset, limit, order } = list.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const logs = await step('Getting logs', async () => {
|
||||
return await client.logs.find.query({
|
||||
@@ -35,7 +39,7 @@ list
|
||||
order,
|
||||
});
|
||||
});
|
||||
console.table(logs.reverse());
|
||||
console.table(logs);
|
||||
});
|
||||
|
||||
export { list };
|
||||
|
||||
65
packages/cli/src/commands/logs/logs.remove.ts
Normal file
65
packages/cli/src/commands/logs/logs.remove.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import inquirer from 'inquirer';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const remove = new Command('remove');
|
||||
|
||||
const toInt = (value?: string) => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
return parseInt(value, 10);
|
||||
};
|
||||
|
||||
remove
|
||||
.alias('ls')
|
||||
.description('List logs')
|
||||
.option('-r, --run-id <runId>', 'Run ID')
|
||||
.option('-l, --load-id <loadId>', 'Load ID')
|
||||
.option('--severities <severities...>', 'Severities')
|
||||
.option('-o, --offset <offset>', 'Offset')
|
||||
.option('-a, --limit <limit>', 'Limit', '1000')
|
||||
.option('-s, --sort <order>', 'Sort', 'desc')
|
||||
.action(async () => {
|
||||
const { runId, loadId, severities, offset, limit, order } = remove.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient(context);
|
||||
});
|
||||
const response = await step('Preparing to delete', async () => {
|
||||
return await client.logs.prepareRemove.query({
|
||||
runId,
|
||||
loadId,
|
||||
severities,
|
||||
offset: toInt(offset),
|
||||
limit: toInt(limit),
|
||||
order,
|
||||
});
|
||||
});
|
||||
|
||||
if (!response.ids.length) {
|
||||
console.log('No logs to delete');
|
||||
return;
|
||||
}
|
||||
const { confirm } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: `Are you sure you want to delete ${response.ids.length} logs?`,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
await step('Deleting logs', async () => {
|
||||
await client.logs.remove.mutate(response);
|
||||
});
|
||||
});
|
||||
|
||||
export { remove };
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Command } from 'commander';
|
||||
import { list } from './logs.list.js';
|
||||
import { remove } from './logs.remove.js';
|
||||
|
||||
const logs = new Command('logs');
|
||||
logs.addCommand(list);
|
||||
logs.addCommand(remove);
|
||||
|
||||
export { logs };
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const create = new Command('create');
|
||||
|
||||
@@ -8,8 +10,10 @@ create
|
||||
.description('Create a new run')
|
||||
.argument('load-id', 'Load ID')
|
||||
.action(async (loadId) => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
await step('Creating run', async () => {
|
||||
await client.runs.create.mutate({ loadId });
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const list = new Command('create');
|
||||
const list = new Command('list');
|
||||
|
||||
list
|
||||
.alias('ls')
|
||||
.description('Find a run')
|
||||
.argument('[load-id]', 'Load ID')
|
||||
.action(async (loadId) => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const runs = await step('Getting runs', async () => {
|
||||
return await client.runs.find.query({ loadId });
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const list = new Command('list');
|
||||
|
||||
@@ -18,8 +20,10 @@ list
|
||||
.option('-a, --limit <limit>', 'Limit', '1000')
|
||||
.action(async () => {
|
||||
const { offset, limit } = list.opts();
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
const secrets = await step('Getting secrets', async () => {
|
||||
return await client.secrets.find.query({
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const remove = new Command('remove');
|
||||
|
||||
@@ -8,8 +10,10 @@ remove
|
||||
.alias('rm')
|
||||
.argument('<id>')
|
||||
.action(async (id) => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
await step('Removing', async () => {
|
||||
await client.secrets.remove.mutate({
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command } from 'commander';
|
||||
import { createClient } from '../../client/client.js';
|
||||
import { step } from '../../utils/step.js';
|
||||
import { Context } from '../../context/context.js';
|
||||
import { Config } from '../../config/config.js';
|
||||
|
||||
const set = new Command('set');
|
||||
|
||||
@@ -8,8 +10,10 @@ set
|
||||
.argument('<id>')
|
||||
.argument('[value]')
|
||||
.action(async (id, value) => {
|
||||
const config = new Config();
|
||||
const context = new Context(config.context);
|
||||
const client = await step('Connecting to server', async () => {
|
||||
return createClient();
|
||||
return createClient(context);
|
||||
});
|
||||
await step('Setting secret', async () => {
|
||||
await client.secrets.set.mutate({
|
||||
|
||||
44
packages/cli/src/config/config.ts
Normal file
44
packages/cli/src/config/config.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import envPaths from 'env-paths';
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { mkdir } from 'fs/promises';
|
||||
import { join, dirname } from 'path';
|
||||
|
||||
type ConfigValues = {
|
||||
context?: string;
|
||||
};
|
||||
|
||||
class Config {
|
||||
#location: string;
|
||||
#config?: ConfigValues;
|
||||
|
||||
constructor() {
|
||||
const paths = envPaths('mini-loader');
|
||||
this.#location = join(paths.config, 'config.json');
|
||||
if (existsSync(this.#location)) {
|
||||
this.#config = JSON.parse(readFileSync(this.#location, 'utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
public get context() {
|
||||
return this.#config?.context || 'default';
|
||||
}
|
||||
|
||||
public setContext = (context: string) => {
|
||||
this.#config = {
|
||||
...(this.#config || {}),
|
||||
context,
|
||||
};
|
||||
this.save();
|
||||
};
|
||||
|
||||
public save = async () => {
|
||||
if (!this.#config) {
|
||||
return;
|
||||
}
|
||||
const json = JSON.stringify(this.#config);
|
||||
mkdir(dirname(this.#location), { recursive: true });
|
||||
writeFileSync(this.#location, json);
|
||||
};
|
||||
}
|
||||
|
||||
export { Config };
|
||||
59
packages/cli/src/context/context.ts
Normal file
59
packages/cli/src/context/context.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import envPaths from 'env-paths';
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { mkdir, readdir } from 'fs/promises';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
type ContextValues = {
|
||||
host: string;
|
||||
token: string;
|
||||
};
|
||||
|
||||
class Context {
|
||||
#location: string;
|
||||
#config?: ContextValues;
|
||||
|
||||
constructor(name: string) {
|
||||
const paths = envPaths('mini-loader');
|
||||
this.#location = join(paths.config, 'contexts', name);
|
||||
if (existsSync(this.#location)) {
|
||||
this.#config = JSON.parse(readFileSync(this.#location, 'utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
public get host() {
|
||||
return this.#config?.host;
|
||||
}
|
||||
|
||||
public get token() {
|
||||
return this.#config?.token;
|
||||
}
|
||||
|
||||
public saveLogin = (host: string, token: string) => {
|
||||
this.#config = {
|
||||
...(this.#config || {}),
|
||||
host,
|
||||
token,
|
||||
};
|
||||
this.save();
|
||||
};
|
||||
|
||||
public save = async () => {
|
||||
if (!this.#config) {
|
||||
return;
|
||||
}
|
||||
const json = JSON.stringify(this.#config);
|
||||
mkdir(dirname(this.#location), { recursive: true });
|
||||
writeFileSync(this.#location, json);
|
||||
};
|
||||
|
||||
public static list = async () => {
|
||||
const paths = envPaths('mini-loader');
|
||||
const location = join(paths.config, 'contexts');
|
||||
if (!existsSync(location)) {
|
||||
return [];
|
||||
}
|
||||
return await readdir(location);
|
||||
};
|
||||
}
|
||||
|
||||
export { Context };
|
||||
@@ -6,6 +6,7 @@ import { artifacts } from './commands/artifacts/artifacts.js';
|
||||
import { secrets } from './commands/secrets/secrets.js';
|
||||
import { local } from './commands/local/local.js';
|
||||
import { auth } from './commands/auth/auth.js';
|
||||
import { contexts } from './commands/contexts/contexts.js';
|
||||
|
||||
program.addCommand(loads);
|
||||
program.addCommand(runs);
|
||||
@@ -14,5 +15,6 @@ program.addCommand(artifacts);
|
||||
program.addCommand(secrets);
|
||||
program.addCommand(local);
|
||||
program.addCommand(auth);
|
||||
program.addCommand(contexts);
|
||||
|
||||
await program.parseAsync();
|
||||
|
||||
@@ -4,10 +4,10 @@ const step = async <T>(message: string, fn: () => Promise<T>): Promise<T> => {
|
||||
const spinner = ora(message).start();
|
||||
try {
|
||||
const result = await fn();
|
||||
spinner.succeed();
|
||||
await spinner.succeed();
|
||||
return result;
|
||||
} catch (err) {
|
||||
spinner.fail();
|
||||
await spinner.fail();
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader-configs",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -8,5 +9,10 @@
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
"license": "GPL-3.0",
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader-examples",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"main": "./dist/esm/index.js",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"scripts": {
|
||||
@@ -21,5 +23,10 @@
|
||||
"@morten-olsen/mini-loader": "workspace:^",
|
||||
"@types/node": "^20.10.8",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import { artifacts, logger } from '@morten-olsen/mini-loader';
|
||||
|
||||
logger.info('Hello world');
|
||||
const run = async () => {
|
||||
await logger.info('Hello world');
|
||||
await artifacts.create('foo', 'bar');
|
||||
};
|
||||
|
||||
artifacts.create('foo', 'bar');
|
||||
run();
|
||||
|
||||
1
packages/mini-loader/README.md
Normal file
1
packages/mini-loader/README.md
Normal file
@@ -0,0 +1 @@
|
||||
[Go to documentation](https://github.com/morten-olsen/mini-loader)
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"main": "./dist/esm/index.js",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"scripts": {
|
||||
@@ -19,5 +20,10 @@
|
||||
"@morten-olsen/mini-loader-configs": "workspace:^",
|
||||
"@types/node": "^20.10.8",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ type ArtifactCreateEvent = {
|
||||
};
|
||||
};
|
||||
|
||||
const create = (name: string, data: Buffer | string) => {
|
||||
send({
|
||||
const create = async (name: string, data: Buffer | string) => {
|
||||
await send({
|
||||
type: 'artifact:create',
|
||||
payload: {
|
||||
name,
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { workerData } from 'worker_threads';
|
||||
import { existsSync } from 'fs';
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
const get = <T>() => {
|
||||
return workerData as T;
|
||||
const path = process.env.INPUT_PATH;
|
||||
const hasInput = path ? existsSync(path) : false;
|
||||
|
||||
const get = () => {
|
||||
if (!hasInput || !path) {
|
||||
return undefined;
|
||||
}
|
||||
return readFile(path, 'utf-8');
|
||||
};
|
||||
|
||||
const input = {
|
||||
|
||||
@@ -9,31 +9,31 @@ type LoggerEvent = {
|
||||
};
|
||||
};
|
||||
|
||||
const sendLog = (event: LoggerEvent['payload']) => {
|
||||
send({
|
||||
const sendLog = async (event: LoggerEvent['payload']) => {
|
||||
await send({
|
||||
type: 'log',
|
||||
payload: event,
|
||||
});
|
||||
};
|
||||
|
||||
const info = (message: string, data?: unknown) => {
|
||||
sendLog({
|
||||
const info = async (message: string, data?: unknown) => {
|
||||
await sendLog({
|
||||
severity: 'info',
|
||||
message,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
const warn = (message: string, data?: unknown) => {
|
||||
sendLog({
|
||||
const warn = async (message: string, data?: unknown) => {
|
||||
await sendLog({
|
||||
severity: 'warning',
|
||||
message,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
const error = (message: string, data?: unknown) => {
|
||||
sendLog({
|
||||
const error = async (message: string, data?: unknown) => {
|
||||
await sendLog({
|
||||
severity: 'error',
|
||||
message,
|
||||
data,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { workerData } from 'worker_threads';
|
||||
const secretData = JSON.parse(process.env.SECRETS || '{}');
|
||||
|
||||
const get = (id: string) => {
|
||||
const items = workerData?.secrets ?? {};
|
||||
return items[id];
|
||||
return secretData[id];
|
||||
};
|
||||
|
||||
const secrets = {
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
import { parentPort } from 'worker_threads';
|
||||
import { Socket, createConnection } from 'net';
|
||||
|
||||
const send = (data: any) => {
|
||||
const connect = () =>
|
||||
new Promise<Socket>((resolve, reject) => {
|
||||
const current = createConnection(process.env.HOST_SOCKET!);
|
||||
|
||||
current.on('connect', () => {
|
||||
resolve(current);
|
||||
});
|
||||
current.on('error', (error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
const send = async (data: any) =>
|
||||
new Promise<void>(async (resolve, reject) => {
|
||||
const connection = await connect();
|
||||
const cleaned = JSON.parse(JSON.stringify(data));
|
||||
parentPort?.postMessage(cleaned);
|
||||
};
|
||||
connection.write(JSON.stringify(cleaned), 'utf-8', (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export { send };
|
||||
|
||||
1
packages/runner/README.md
Normal file
1
packages/runner/README.md
Normal file
@@ -0,0 +1 @@
|
||||
[Go to documentation](https://github.com/morten-olsen/mini-loader)
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader-runner",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"main": "./dist/esm/index.js",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"scripts": {
|
||||
@@ -16,12 +17,18 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@morten-olsen/mini-loader-configs": "workspace:^",
|
||||
"@morten-olsen/mini-loader": "workspace:^",
|
||||
"@morten-olsen/mini-loader-configs": "workspace:^",
|
||||
"@types/node": "^20.10.8",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"eventemitter3": "^5.0.1"
|
||||
"eventemitter3": "^5.0.1",
|
||||
"nanoid": "^5.0.4"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
import { Worker } from 'worker_threads';
|
||||
import os from 'os';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { Event } from '@morten-olsen/mini-loader';
|
||||
import { join } from 'path';
|
||||
import { createServer } from 'http';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { chmod, mkdir, rm, writeFile } from 'fs/promises';
|
||||
|
||||
type RunEvents = {
|
||||
message: (event: Event) => void;
|
||||
@@ -10,29 +15,75 @@ type RunEvents = {
|
||||
|
||||
type RunOptions = {
|
||||
script: string;
|
||||
input?: unknown;
|
||||
input?: Buffer | string;
|
||||
secrets?: Record<string, string>;
|
||||
};
|
||||
|
||||
const run = async ({ script, input, secrets }: RunOptions) => {
|
||||
const dataDir = join(os.tmpdir(), 'mini-loader', nanoid());
|
||||
await mkdir(dataDir, { recursive: true });
|
||||
await chmod(dataDir, 0o700);
|
||||
const hostSocket = join(dataDir, 'host');
|
||||
const server = createServer();
|
||||
const inputLocation = join(dataDir, 'input');
|
||||
|
||||
if (input) {
|
||||
await writeFile(inputLocation, input);
|
||||
}
|
||||
|
||||
const emitter = new EventEmitter<RunEvents>();
|
||||
|
||||
server.on('connection', (socket) => {
|
||||
socket.on('data', (data) => {
|
||||
const message = JSON.parse(data.toString());
|
||||
emitter.emit('message', message);
|
||||
});
|
||||
});
|
||||
server.listen(hostSocket);
|
||||
|
||||
const worker = new Worker(script, {
|
||||
eval: true,
|
||||
env: secrets,
|
||||
stdin: false,
|
||||
stdout: false,
|
||||
stderr: false,
|
||||
env: {
|
||||
HOST_SOCKET: hostSocket,
|
||||
SECRETS: JSON.stringify(secrets),
|
||||
INPUT_PATH: inputLocation,
|
||||
},
|
||||
workerData: {
|
||||
input,
|
||||
secrets,
|
||||
},
|
||||
});
|
||||
|
||||
const promise = new Promise<void>((resolve, reject) => {
|
||||
worker.on('message', (message: Event) => {
|
||||
emitter.emit('message', message);
|
||||
worker.stdout?.on('data', (data) => {
|
||||
emitter.emit('message', {
|
||||
type: 'log',
|
||||
payload: {
|
||||
severity: 'info',
|
||||
message: data.toString(),
|
||||
},
|
||||
});
|
||||
worker.on('exit', () => {
|
||||
});
|
||||
|
||||
worker.stderr?.on('data', (data) => {
|
||||
emitter.emit('message', {
|
||||
type: 'log',
|
||||
payload: {
|
||||
severity: 'error',
|
||||
message: data.toString(),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
const promise = new Promise<void>((resolve, reject) => {
|
||||
worker.on('exit', async () => {
|
||||
server.close();
|
||||
await rm(dataDir, { recursive: true, force: true });
|
||||
resolve();
|
||||
});
|
||||
worker.on('error', (error) => {
|
||||
worker.on('error', async (error) => {
|
||||
server.close();
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
1
packages/server/README.md
Normal file
1
packages/server/README.md
Normal file
@@ -0,0 +1 @@
|
||||
[Go to documentation](https://github.com/morten-olsen/mini-loader)
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@morten-olsen/mini-loader-server",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"main": "./dist/esm/index.js",
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"bin": {
|
||||
@@ -38,5 +39,10 @@
|
||||
"sqlite3": "^5.1.7",
|
||||
"superjson": "^2.2.1",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
@@ -27,5 +27,9 @@ program.addCommand(createToken);
|
||||
|
||||
await program.parseAsync(process.argv);
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
export type { Runtime } from './runtime/runtime.js';
|
||||
export type { RootRouter } from './router/router.js';
|
||||
|
||||
@@ -18,6 +18,13 @@ class ArtifactRepo extends EventEmitter<ArtifactRepoEvents> {
|
||||
this.#options = options;
|
||||
}
|
||||
|
||||
public get = async (id: string) => {
|
||||
const { database } = this.#options;
|
||||
const db = await database.instance;
|
||||
const result = await db('artifacts').where({ id }).first();
|
||||
return result || null;
|
||||
};
|
||||
|
||||
public add = async (options: AddArtifactOptions) => {
|
||||
const { database } = this.#options;
|
||||
const db = await database.instance;
|
||||
@@ -59,8 +66,9 @@ class ArtifactRepo extends EventEmitter<ArtifactRepoEvents> {
|
||||
query.limit(options.limit);
|
||||
}
|
||||
|
||||
const ids = await query;
|
||||
const token = ids.map((id) => Buffer.from(id.id).toString('base64')).join('|');
|
||||
const result = await query;
|
||||
const ids = result.map((row) => row.id);
|
||||
const token = ids.map((id) => Buffer.from(id).toString('base64')).join('|');
|
||||
const hash = createHash('sha256').update(token).digest('hex');
|
||||
return {
|
||||
ids,
|
||||
|
||||
@@ -56,8 +56,9 @@ class LogRepo extends EventEmitter<LogRepoEvents> {
|
||||
query.whereIn('severity', options.severities);
|
||||
}
|
||||
|
||||
const ids = await query;
|
||||
const token = ids.map((id) => Buffer.from(id.id).toString('base64')).join('|');
|
||||
const result = await query;
|
||||
const ids = result.map((row) => row.id);
|
||||
const token = ids.map((id) => Buffer.from(id).toString('base64')).join('|');
|
||||
const hash = createHash('sha256').update(token).digest('hex');
|
||||
return {
|
||||
ids,
|
||||
|
||||
@@ -11,12 +11,21 @@ const find = publicProcedure.input(findArtifactsSchema).query(async ({ input, ct
|
||||
return result;
|
||||
});
|
||||
|
||||
const get = publicProcedure.input(z.string()).query(async ({ input, ctx }) => {
|
||||
const { runtime } = ctx;
|
||||
const { repos } = runtime;
|
||||
const { artifacts } = repos;
|
||||
|
||||
const result = await artifacts.get(input);
|
||||
return result;
|
||||
});
|
||||
|
||||
const prepareRemove = publicProcedure.input(findArtifactsSchema).query(async ({ input, ctx }) => {
|
||||
const { runtime } = ctx;
|
||||
const { repos } = runtime;
|
||||
const { artifacts } = repos;
|
||||
|
||||
await artifacts.prepareRemove(input);
|
||||
return await artifacts.prepareRemove(input);
|
||||
});
|
||||
|
||||
const remove = publicProcedure
|
||||
@@ -35,6 +44,7 @@ const remove = publicProcedure
|
||||
});
|
||||
|
||||
const artifactsRouter = router({
|
||||
get,
|
||||
find,
|
||||
remove,
|
||||
prepareRemove,
|
||||
|
||||
@@ -16,7 +16,7 @@ const prepareRemove = publicProcedure.input(findLogsSchema).query(async ({ input
|
||||
const { repos } = runtime;
|
||||
const { logs } = repos;
|
||||
|
||||
await logs.prepareRemove(input);
|
||||
return await logs.prepareRemove(input);
|
||||
});
|
||||
|
||||
const remove = publicProcedure
|
||||
|
||||
@@ -14,7 +14,8 @@ const createContext = async ({ runtime }: ContextOptions) => {
|
||||
if (!authorization) {
|
||||
throw new Error('No authorization header');
|
||||
}
|
||||
await auth.validateToken(authorization);
|
||||
const [, token] = authorization.split(' ');
|
||||
await auth.validateToken(token);
|
||||
return {
|
||||
runtime,
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ class RunnerInstance extends EventEmitter<RunnerInstanceEvents> {
|
||||
const { runs, secrets } = repos;
|
||||
try {
|
||||
const { script: scriptHash, input } = await runs.getById(id);
|
||||
const scriptLocation = resolve(config.files.location, 'script', `${scriptHash}.js`);
|
||||
const scriptLocation = resolve(config.files.location, 'scripts', `${scriptHash}.js`);
|
||||
const script = await readFile(scriptLocation, 'utf-8');
|
||||
const allSecrets = await secrets.getAll();
|
||||
await runs.started(id);
|
||||
|
||||
@@ -10,6 +10,19 @@ const createServer = async (runtime: Runtime) => {
|
||||
return { hello: 'world' };
|
||||
});
|
||||
|
||||
server.get('/health', async (req) => {
|
||||
let authorized = false;
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
if (authorization) {
|
||||
const [, token] = authorization.split(' ');
|
||||
await runtime.auth.validateToken(token);
|
||||
authorized = true;
|
||||
}
|
||||
} catch (error) {}
|
||||
return { authorized, status: 'ok' };
|
||||
});
|
||||
|
||||
server.register(fastifyTRPCPlugin, {
|
||||
prefix: '/trpc',
|
||||
trpcOptions: {
|
||||
|
||||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@@ -60,6 +60,9 @@ importers:
|
||||
commander:
|
||||
specifier: ^11.1.0
|
||||
version: 11.1.0
|
||||
env-paths:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
inquirer:
|
||||
specifier: ^9.2.12
|
||||
version: 9.2.12
|
||||
@@ -132,6 +135,9 @@ importers:
|
||||
eventemitter3:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
nanoid:
|
||||
specifier: ^5.0.4
|
||||
version: 5.0.4
|
||||
devDependencies:
|
||||
'@morten-olsen/mini-loader':
|
||||
specifier: workspace:^
|
||||
@@ -2206,6 +2212,11 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/env-paths@3.0.0:
|
||||
resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/err-code@2.0.3:
|
||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||
requiresBuild: true
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { findWorkspacePackages } from '@pnpm/find-workspace-packages';
|
||||
import { writeFile } from 'fs/promises';
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
|
||||
const sharedData = JSON.parse(await readFile(join(process.cwd(), 'scripts/shared-data.json')));
|
||||
|
||||
const version = process.argv[2];
|
||||
if (!version) {
|
||||
throw new Error('Version is required');
|
||||
@@ -11,6 +13,9 @@ const packages = await findWorkspacePackages(process.cwd());
|
||||
|
||||
for (const { manifest, dir } of packages) {
|
||||
console.log(dir, version);
|
||||
for (let [key, value] of Object.entries(sharedData || {})) {
|
||||
manifest[key] = value;
|
||||
}
|
||||
manifest.version = version;
|
||||
await writeFile(join(dir, 'package.json'), JSON.stringify(manifest, null, 2));
|
||||
}
|
||||
|
||||
8
scripts/shared-data.json
Normal file
8
scripts/shared-data.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"license": "GPL-3.0",
|
||||
"homepage": "https://github.com/morten-olsen/mini-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/morten-olsen/mini-loader"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user