@elaraai/e3-api-server 0.0.2-beta.12 → 0.0.2-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -29
- package/dist/src/async-operation-state.d.ts +63 -0
- package/dist/src/async-operation-state.d.ts.map +1 -0
- package/dist/src/async-operation-state.js +193 -0
- package/dist/src/async-operation-state.js.map +1 -0
- package/dist/src/auth/device.d.ts +26 -0
- package/dist/src/auth/device.d.ts.map +1 -0
- package/dist/src/auth/device.js +227 -0
- package/dist/src/auth/device.js.map +1 -0
- package/dist/src/auth/discovery.d.ts +23 -0
- package/dist/src/auth/discovery.d.ts.map +1 -0
- package/dist/src/auth/discovery.js +40 -0
- package/dist/src/auth/discovery.js.map +1 -0
- package/dist/src/auth/index.d.ts +56 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +69 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/keys.d.ts +55 -0
- package/dist/src/auth/keys.d.ts.map +1 -0
- package/dist/src/auth/keys.js +78 -0
- package/dist/src/auth/keys.js.map +1 -0
- package/dist/src/beast2.d.ts +15 -3
- package/dist/src/beast2.d.ts.map +1 -1
- package/dist/src/beast2.js +30 -4
- package/dist/src/beast2.js.map +1 -1
- package/dist/src/cli.js +58 -6
- package/dist/src/cli.js.map +1 -1
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +5 -2
- package/dist/src/errors.js.map +1 -1
- package/dist/src/execution-state.d.ts +54 -0
- package/dist/src/execution-state.d.ts.map +1 -0
- package/dist/src/execution-state.js +150 -0
- package/dist/src/execution-state.js.map +1 -0
- package/dist/src/handlers/dataflow.d.ts +49 -0
- package/dist/src/handlers/dataflow.d.ts.map +1 -0
- package/dist/src/handlers/dataflow.js +371 -0
- package/dist/src/handlers/dataflow.js.map +1 -0
- package/dist/src/handlers/datasets.d.ts +23 -0
- package/dist/src/handlers/datasets.d.ts.map +1 -0
- package/dist/src/handlers/datasets.js +113 -0
- package/dist/src/handlers/datasets.js.map +1 -0
- package/dist/src/handlers/index.d.ts +12 -0
- package/dist/src/handlers/index.d.ts.map +1 -0
- package/dist/src/handlers/index.js +12 -0
- package/dist/src/handlers/index.js.map +1 -0
- package/dist/src/handlers/packages.d.ts +26 -0
- package/dist/src/handlers/packages.d.ts.map +1 -0
- package/dist/src/handlers/packages.js +101 -0
- package/dist/src/handlers/packages.js.map +1 -0
- package/dist/src/handlers/repos.d.ts +11 -0
- package/dist/src/handlers/repos.d.ts.map +1 -0
- package/dist/src/handlers/repos.js +52 -0
- package/dist/src/handlers/repos.js.map +1 -0
- package/dist/src/handlers/repository.d.ts +35 -0
- package/dist/src/handlers/repository.d.ts.map +1 -0
- package/dist/src/handlers/repository.js +142 -0
- package/dist/src/handlers/repository.js.map +1 -0
- package/dist/src/handlers/tasks.d.ts +18 -0
- package/dist/src/handlers/tasks.d.ts.map +1 -0
- package/dist/src/handlers/tasks.js +134 -0
- package/dist/src/handlers/tasks.js.map +1 -0
- package/dist/src/handlers/workspaces.d.ts +34 -0
- package/dist/src/handlers/workspaces.d.ts.map +1 -0
- package/dist/src/handlers/workspaces.js +225 -0
- package/dist/src/handlers/workspaces.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware/auth.d.ts +51 -0
- package/dist/src/middleware/auth.d.ts.map +1 -0
- package/dist/src/middleware/auth.js +158 -0
- package/dist/src/middleware/auth.js.map +1 -0
- package/dist/src/routes/datasets.d.ts +2 -1
- package/dist/src/routes/datasets.d.ts.map +1 -1
- package/dist/src/routes/datasets.js +50 -85
- package/dist/src/routes/datasets.js.map +1 -1
- package/dist/src/routes/executions.d.ts +2 -1
- package/dist/src/routes/executions.d.ts.map +1 -1
- package/dist/src/routes/executions.js +60 -286
- package/dist/src/routes/executions.js.map +1 -1
- package/dist/src/routes/index.d.ts +11 -0
- package/dist/src/routes/index.d.ts.map +1 -0
- package/dist/src/routes/index.js +11 -0
- package/dist/src/routes/index.js.map +1 -0
- package/dist/src/routes/packages.d.ts +2 -1
- package/dist/src/routes/packages.d.ts.map +1 -1
- package/dist/src/routes/packages.js +42 -105
- package/dist/src/routes/packages.js.map +1 -1
- package/dist/src/routes/repository.d.ts +2 -1
- package/dist/src/routes/repository.d.ts.map +1 -1
- package/dist/src/routes/repository.js +19 -54
- package/dist/src/routes/repository.js.map +1 -1
- package/dist/src/routes/tasks.d.ts +2 -1
- package/dist/src/routes/tasks.d.ts.map +1 -1
- package/dist/src/routes/tasks.js +22 -46
- package/dist/src/routes/tasks.js.map +1 -1
- package/dist/src/routes/workspaces.d.ts +2 -1
- package/dist/src/routes/workspaces.d.ts.map +1 -1
- package/dist/src/routes/workspaces.js +45 -116
- package/dist/src/routes/workspaces.js.map +1 -1
- package/dist/src/server.d.ts +24 -3
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +178 -19
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +486 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +209 -2
- package/dist/src/types.js.map +1 -1
- package/package.json +15 -3
|
@@ -2,131 +2,60 @@
|
|
|
2
2
|
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
|
-
import * as fs from 'node:fs/promises';
|
|
6
|
-
import * as os from 'node:os';
|
|
7
|
-
import * as path from 'node:path';
|
|
8
5
|
import { Hono } from 'hono';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
import { errorToVariant } from '../errors.js';
|
|
14
|
-
import { WorkspaceInfoType, CreateWorkspaceType, DeployRequestType } from '../types.js';
|
|
15
|
-
export function createWorkspaceRoutes(repoPath) {
|
|
6
|
+
import { listWorkspaces, createWorkspace, getWorkspace, getWorkspaceStatus, deleteWorkspace, deployWorkspace, exportWorkspace, } from '../handlers/workspaces.js';
|
|
7
|
+
import { decodeBody } from '../beast2.js';
|
|
8
|
+
import { CreateWorkspaceType, DeployRequestType } from '../types.js';
|
|
9
|
+
export function createWorkspaceRoutes(storage, getRepoPath) {
|
|
16
10
|
const app = new Hono();
|
|
17
|
-
// GET /api/workspaces - List all workspaces
|
|
11
|
+
// GET /api/repos/:repo/workspaces - List all workspaces
|
|
18
12
|
app.get('/', async (c) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const state = await workspaceGetState(repoPath, name);
|
|
23
|
-
if (state) {
|
|
24
|
-
return {
|
|
25
|
-
name,
|
|
26
|
-
deployed: true,
|
|
27
|
-
packageName: some(state.packageName),
|
|
28
|
-
packageVersion: some(state.packageVersion),
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
return {
|
|
33
|
-
name,
|
|
34
|
-
deployed: false,
|
|
35
|
-
packageName: none,
|
|
36
|
-
packageVersion: none,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
}));
|
|
40
|
-
return sendSuccess(c, ArrayType(WorkspaceInfoType), result);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
return sendError(c, ArrayType(WorkspaceInfoType), errorToVariant(err));
|
|
44
|
-
}
|
|
13
|
+
const repo = c.req.param('repo');
|
|
14
|
+
const repoPath = getRepoPath(repo);
|
|
15
|
+
return listWorkspaces(storage, repoPath);
|
|
45
16
|
});
|
|
46
|
-
// POST /api/workspaces - Create a new workspace
|
|
17
|
+
// POST /api/repos/:repo/workspaces - Create a new workspace
|
|
47
18
|
app.post('/', async (c) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
name: body.name,
|
|
53
|
-
deployed: false,
|
|
54
|
-
packageName: none,
|
|
55
|
-
packageVersion: none,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
catch (err) {
|
|
59
|
-
return sendError(c, WorkspaceInfoType, errorToVariant(err));
|
|
60
|
-
}
|
|
19
|
+
const repo = c.req.param('repo');
|
|
20
|
+
const repoPath = getRepoPath(repo);
|
|
21
|
+
const body = await decodeBody(c, CreateWorkspaceType);
|
|
22
|
+
return createWorkspace(storage, repoPath, body.name);
|
|
61
23
|
});
|
|
62
|
-
// GET /api/workspaces/:
|
|
63
|
-
app.get('/:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Workspace exists but not deployed - return error
|
|
69
|
-
return sendError(c, WorkspaceStateType, errorToVariant(new Error(`Workspace '${name}' is not deployed`)));
|
|
70
|
-
}
|
|
71
|
-
return sendSuccess(c, WorkspaceStateType, state);
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
return sendError(c, WorkspaceStateType, errorToVariant(err));
|
|
75
|
-
}
|
|
24
|
+
// GET /api/repos/:repo/workspaces/:ws - Get workspace state
|
|
25
|
+
app.get('/:ws', async (c) => {
|
|
26
|
+
const repo = c.req.param('repo');
|
|
27
|
+
const repoPath = getRepoPath(repo);
|
|
28
|
+
const ws = c.req.param('ws');
|
|
29
|
+
return getWorkspace(storage, repoPath, ws);
|
|
76
30
|
});
|
|
77
|
-
//
|
|
78
|
-
app.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
return sendError(c, NullType, errorToVariant(err));
|
|
86
|
-
}
|
|
31
|
+
// GET /api/repos/:repo/workspaces/:ws/status - Get comprehensive workspace status
|
|
32
|
+
app.get('/:ws/status', (c) => {
|
|
33
|
+
const repo = c.req.param('repo');
|
|
34
|
+
const repoPath = getRepoPath(repo);
|
|
35
|
+
const ws = c.req.param('ws');
|
|
36
|
+
return getWorkspaceStatus(storage, repoPath, ws);
|
|
87
37
|
});
|
|
88
|
-
//
|
|
89
|
-
app.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
const body = await decodeBody(c, DeployRequestType);
|
|
96
|
-
const { name: pkgName, version: maybeVersion } = parsePackageRef(body.packageRef);
|
|
97
|
-
const pkgVersion = maybeVersion ?? await packageGetLatestVersion(repoPath, pkgName);
|
|
98
|
-
if (!pkgVersion) {
|
|
99
|
-
return sendError(c, NullType, errorToVariant(new Error(`Package not found: ${pkgName}`)));
|
|
100
|
-
}
|
|
101
|
-
await workspaceDeploy(repoPath, name, pkgName, pkgVersion);
|
|
102
|
-
return sendSuccess(c, NullType, null);
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
return sendError(c, NullType, errorToVariant(err));
|
|
106
|
-
}
|
|
38
|
+
// DELETE /api/repos/:repo/workspaces/:ws - Remove a workspace
|
|
39
|
+
app.delete('/:ws', async (c) => {
|
|
40
|
+
const repo = c.req.param('repo');
|
|
41
|
+
const repoPath = getRepoPath(repo);
|
|
42
|
+
const ws = c.req.param('ws');
|
|
43
|
+
return deleteWorkspace(storage, repoPath, ws);
|
|
107
44
|
});
|
|
108
|
-
//
|
|
109
|
-
app.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
finally {
|
|
124
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
catch (err) {
|
|
128
|
-
return sendError(c, BlobType, errorToVariant(err));
|
|
129
|
-
}
|
|
45
|
+
// POST /api/repos/:repo/workspaces/:ws/deploy - Deploy a package to a workspace
|
|
46
|
+
app.post('/:ws/deploy', async (c) => {
|
|
47
|
+
const repo = c.req.param('repo');
|
|
48
|
+
const repoPath = getRepoPath(repo);
|
|
49
|
+
const ws = c.req.param('ws');
|
|
50
|
+
const body = await decodeBody(c, DeployRequestType);
|
|
51
|
+
return deployWorkspace(storage, repoPath, ws, body.packageRef);
|
|
52
|
+
});
|
|
53
|
+
// GET /api/repos/:repo/workspaces/:ws/export - Export workspace as a package zip
|
|
54
|
+
app.get('/:ws/export', async (c) => {
|
|
55
|
+
const repo = c.req.param('repo');
|
|
56
|
+
const repoPath = getRepoPath(repo);
|
|
57
|
+
const ws = c.req.param('ws');
|
|
58
|
+
return exportWorkspace(storage, repoPath, ws);
|
|
130
59
|
});
|
|
131
60
|
return app;
|
|
132
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,GAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,UAAU,qBAAqB,CACnC,OAAuB,EACvB,WAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,wDAAwD;IACxD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAC5D,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACtD,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,kFAAkF;IAClF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACpD,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,iFAAiF;IACjF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/src/server.d.ts
CHANGED
|
@@ -3,18 +3,32 @@
|
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
5
|
import { type ServerType } from '@hono/node-server';
|
|
6
|
+
import { type AuthConfig } from './middleware/auth.js';
|
|
7
|
+
import { type OidcConfig } from './auth/index.js';
|
|
8
|
+
export type { AuthConfig } from './middleware/auth.js';
|
|
9
|
+
export type { OidcConfig } from './auth/index.js';
|
|
6
10
|
/**
|
|
7
11
|
* Server configuration options.
|
|
12
|
+
*
|
|
13
|
+
* Must specify exactly one of:
|
|
14
|
+
* - reposDir: Multi-repo mode - serves multiple repositories from subdirectories
|
|
15
|
+
* - singleRepoPath: Single-repo mode - serves a single repository at /repos/default
|
|
8
16
|
*/
|
|
9
17
|
export interface ServerConfig {
|
|
10
|
-
/**
|
|
11
|
-
|
|
18
|
+
/** Directory containing repositories (multi-repo mode) */
|
|
19
|
+
reposDir?: string;
|
|
20
|
+
/** Path to a single repository (single-repo mode, access via /repos/default) */
|
|
21
|
+
singleRepoPath?: string;
|
|
12
22
|
/** HTTP port (default: 3000) */
|
|
13
23
|
port?: number;
|
|
14
24
|
/** Bind address (default: "localhost") */
|
|
15
25
|
host?: string;
|
|
16
26
|
/** Enable CORS for cross-origin requests (default: false) */
|
|
17
27
|
cors?: boolean;
|
|
28
|
+
/** Optional JWT authentication config (for external JWKS validation) */
|
|
29
|
+
auth?: AuthConfig;
|
|
30
|
+
/** Optional OIDC provider config (enables built-in auth server) */
|
|
31
|
+
oidc?: OidcConfig;
|
|
18
32
|
}
|
|
19
33
|
/**
|
|
20
34
|
* Server instance handle.
|
|
@@ -32,8 +46,15 @@ export interface Server {
|
|
|
32
46
|
/**
|
|
33
47
|
* Create an e3 API server.
|
|
34
48
|
*
|
|
49
|
+
* The server operates in multi-repo mode, serving multiple repositories
|
|
50
|
+
* from subdirectories of the configured reposDir.
|
|
51
|
+
*
|
|
52
|
+
* URL structure:
|
|
53
|
+
* - GET /api/repos - List available repositories
|
|
54
|
+
* - /api/repos/:repo/... - Repository-specific endpoints
|
|
55
|
+
*
|
|
35
56
|
* @param config - Server configuration
|
|
36
57
|
* @returns Server instance
|
|
37
58
|
*/
|
|
38
|
-
export declare function createServer(config: ServerConfig): Server
|
|
59
|
+
export declare function createServer(config: ServerConfig): Promise<Server>;
|
|
39
60
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/src/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAyC,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAYzF,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,mEAAmE;IACnE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,uBAAuB;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,iCAAiC;IACjC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAoPxE"}
|
package/dist/src/server.js
CHANGED
|
@@ -2,44 +2,203 @@
|
|
|
2
2
|
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
|
+
import * as path from 'node:path';
|
|
5
6
|
import { Hono } from 'hono';
|
|
6
7
|
import { cors } from 'hono/cors';
|
|
7
8
|
import { serve } from '@hono/node-server';
|
|
8
|
-
import {
|
|
9
|
+
import { LocalStorage, repoInit, RepositoryNotFoundError } from '@elaraai/e3-core';
|
|
10
|
+
import { createAuthMiddleware } from './middleware/auth.js';
|
|
11
|
+
import { createOidcProvider } from './auth/index.js';
|
|
12
|
+
import { listRepos } from './handlers/repos.js';
|
|
13
|
+
import { startRepoDelete, getRepoDeleteStatus } from './handlers/repository.js';
|
|
14
|
+
import { sendError, sendSuccessWithStatus } from './beast2.js';
|
|
15
|
+
import { StringType, NullType, variant } from '@elaraai/east';
|
|
9
16
|
import { createPackageRoutes } from './routes/packages.js';
|
|
10
17
|
import { createWorkspaceRoutes } from './routes/workspaces.js';
|
|
11
18
|
import { createDatasetRoutes } from './routes/datasets.js';
|
|
12
19
|
import { createTaskRoutes } from './routes/tasks.js';
|
|
13
20
|
import { createExecutionRoutes } from './routes/executions.js';
|
|
21
|
+
import { createRepositoryRoutes } from './routes/repository.js';
|
|
14
22
|
/**
|
|
15
23
|
* Create an e3 API server.
|
|
16
24
|
*
|
|
25
|
+
* The server operates in multi-repo mode, serving multiple repositories
|
|
26
|
+
* from subdirectories of the configured reposDir.
|
|
27
|
+
*
|
|
28
|
+
* URL structure:
|
|
29
|
+
* - GET /api/repos - List available repositories
|
|
30
|
+
* - /api/repos/:repo/... - Repository-specific endpoints
|
|
31
|
+
*
|
|
17
32
|
* @param config - Server configuration
|
|
18
33
|
* @returns Server instance
|
|
19
34
|
*/
|
|
20
|
-
export function createServer(config) {
|
|
21
|
-
const {
|
|
35
|
+
export async function createServer(config) {
|
|
36
|
+
const { reposDir, singleRepoPath, port = 3000, host = 'localhost', cors: enableCors = false, auth, oidc } = config;
|
|
37
|
+
// Validate config: exactly one of reposDir or singleRepoPath must be specified
|
|
38
|
+
if (reposDir && singleRepoPath) {
|
|
39
|
+
throw new Error('Cannot specify both reposDir and singleRepoPath');
|
|
40
|
+
}
|
|
41
|
+
if (!reposDir && !singleRepoPath) {
|
|
42
|
+
throw new Error('Must specify either reposDir or singleRepoPath');
|
|
43
|
+
}
|
|
44
|
+
const isSingleRepoMode = !!singleRepoPath;
|
|
45
|
+
// Single storage instance shared across all requests
|
|
46
|
+
const storage = new LocalStorage();
|
|
47
|
+
// Helper to compute repo path from repo name
|
|
48
|
+
// In single-repo mode, middleware validates 'default' before routes are called
|
|
49
|
+
const getRepoPath = (repoName) => {
|
|
50
|
+
if (isSingleRepoMode) {
|
|
51
|
+
// Middleware ensures repoName === 'default' before we get here
|
|
52
|
+
return singleRepoPath;
|
|
53
|
+
}
|
|
54
|
+
return path.join(reposDir, repoName);
|
|
55
|
+
};
|
|
22
56
|
const app = new Hono();
|
|
23
57
|
// Enable CORS if configured
|
|
24
58
|
if (enableCors) {
|
|
25
59
|
app.use('*', cors({ origin: '*' }));
|
|
26
60
|
}
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
61
|
+
// Create OIDC provider if configured (built-in auth server)
|
|
62
|
+
let oidcProvider;
|
|
63
|
+
if (oidc) {
|
|
64
|
+
oidcProvider = createOidcProvider(oidc);
|
|
65
|
+
// Mount OIDC routes at root (/.well-known/*, /oauth2/*, /device)
|
|
66
|
+
app.route('/', oidcProvider.routes);
|
|
67
|
+
}
|
|
68
|
+
// Apply auth middleware to all repo-specific routes if configured
|
|
69
|
+
// If OIDC is enabled but auth is not separately configured, use OIDC keys for validation
|
|
70
|
+
if (auth) {
|
|
71
|
+
const authMiddleware = await createAuthMiddleware(auth);
|
|
72
|
+
app.use('/api/repos/:repo/*', authMiddleware);
|
|
73
|
+
}
|
|
74
|
+
else if (oidcProvider) {
|
|
75
|
+
// Use the OIDC provider's keys for JWT validation
|
|
76
|
+
const authMiddleware = await createAuthMiddleware({
|
|
77
|
+
jwksUrl: `${oidc.baseUrl}/.well-known/jwks.json`,
|
|
78
|
+
issuer: oidc.baseUrl,
|
|
79
|
+
audience: oidc.baseUrl,
|
|
80
|
+
// Provide keys directly to avoid HTTP fetch to self
|
|
81
|
+
_internalKeys: oidcProvider.keys,
|
|
82
|
+
});
|
|
83
|
+
app.use('/api/repos/:repo/*', authMiddleware);
|
|
84
|
+
}
|
|
85
|
+
// Single-repo mode: validate repo name and handle disabled operations
|
|
86
|
+
// Runs AFTER auth middleware (so unauthorized users get 401, not 404/405)
|
|
87
|
+
if (isSingleRepoMode) {
|
|
88
|
+
app.use('/api/repos/:repo/*', async (c, next) => {
|
|
89
|
+
const method = c.req.method;
|
|
90
|
+
// PUT (create repo) is always disabled in single-repo mode
|
|
91
|
+
if (method === 'PUT') {
|
|
92
|
+
return c.json({
|
|
93
|
+
error: 'method_not_allowed',
|
|
94
|
+
message: 'Repository creation is disabled in single-repo mode'
|
|
95
|
+
}, 405);
|
|
96
|
+
}
|
|
97
|
+
// For DELETE (remove repo), check if it's the 'default' repo
|
|
98
|
+
if (method === 'DELETE') {
|
|
99
|
+
// DELETE on 'default' → 405 (deletion disabled)
|
|
100
|
+
// DELETE on other repos → 404 (repo doesn't exist)
|
|
101
|
+
const repo = c.req.param('repo');
|
|
102
|
+
if (repo === 'default') {
|
|
103
|
+
return c.json({
|
|
104
|
+
error: 'method_not_allowed',
|
|
105
|
+
message: 'Repository deletion is disabled in single-repo mode'
|
|
106
|
+
}, 405);
|
|
107
|
+
}
|
|
108
|
+
return c.json({ error: 'not_found', message: `Repository '${repo}' not found` }, 404);
|
|
109
|
+
}
|
|
110
|
+
// For other methods (GET, POST, etc.), validate repo name
|
|
111
|
+
const repo = c.req.param('repo');
|
|
112
|
+
if (repo !== 'default') {
|
|
113
|
+
return c.json({ error: 'not_found', message: `Repository '${repo}' not found` }, 404);
|
|
114
|
+
}
|
|
115
|
+
await next();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// Validate repository exists before processing requests (multi-repo mode only)
|
|
119
|
+
// In single-repo mode, this is handled by the middleware above
|
|
120
|
+
// Skip validation for PUT/DELETE on /api/repos/:repo (repo create/remove)
|
|
121
|
+
// Skip validation for /api/repos/:repo/delete/* (repo deletion status - repo may already be deleted)
|
|
122
|
+
if (!isSingleRepoMode) {
|
|
123
|
+
app.use('/api/repos/:repo/*', async (c, next) => {
|
|
124
|
+
// Skip validation for repo create/remove operations at the repo level
|
|
125
|
+
// These operate on repos that may not exist yet (PUT) or are being deleted (DELETE)
|
|
126
|
+
const method = c.req.method;
|
|
127
|
+
const path = c.req.path;
|
|
128
|
+
// Check if this is the base repo path (no subpath after repo name)
|
|
129
|
+
const repoPathMatch = path.match(/^\/api\/repos\/[^/]+$/);
|
|
130
|
+
if (repoPathMatch && (method === 'PUT' || method === 'DELETE')) {
|
|
131
|
+
await next();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Skip validation for delete status endpoint (repo may already be deleted)
|
|
135
|
+
const deleteStatusMatch = path.match(/^\/api\/repos\/[^/]+\/delete\/[^/]+$/);
|
|
136
|
+
if (deleteStatusMatch) {
|
|
137
|
+
await next();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const repo = c.req.param('repo');
|
|
141
|
+
const repoPath = getRepoPath(repo);
|
|
142
|
+
try {
|
|
143
|
+
await storage.validateRepository(repoPath);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
if (err instanceof RepositoryNotFoundError) {
|
|
147
|
+
return sendError(NullType, variant('repository_not_found', { repo }));
|
|
148
|
+
}
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
await next();
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// GET /api/repos - List available repositories
|
|
155
|
+
app.get('/api/repos', async (c) => {
|
|
156
|
+
if (isSingleRepoMode) {
|
|
157
|
+
return c.json(['default']);
|
|
158
|
+
}
|
|
159
|
+
return listRepos(reposDir);
|
|
160
|
+
});
|
|
161
|
+
// PUT /api/repos/:repo - Create a new repository (multi-repo mode only)
|
|
162
|
+
// Note: Single-repo mode handler is registered earlier and takes precedence
|
|
163
|
+
if (!isSingleRepoMode) {
|
|
164
|
+
app.put('/api/repos/:repo', (c) => {
|
|
165
|
+
const repo = c.req.param('repo');
|
|
166
|
+
const repoPath = path.join(reposDir, repo);
|
|
167
|
+
const result = repoInit(repoPath);
|
|
168
|
+
if (!result.success) {
|
|
169
|
+
if (result.alreadyExists) {
|
|
170
|
+
return sendError(StringType, variant('internal', { message: `Repository '${repo}' already exists` }));
|
|
171
|
+
}
|
|
172
|
+
return sendError(StringType, variant('internal', { message: result.error?.message ?? 'Unknown error' }));
|
|
173
|
+
}
|
|
174
|
+
return sendSuccessWithStatus(StringType, repo, 201);
|
|
175
|
+
});
|
|
176
|
+
// DELETE /api/repos/:repo - Remove a repository (async, multi-repo mode only)
|
|
177
|
+
app.delete('/api/repos/:repo', (c) => {
|
|
178
|
+
const repo = c.req.param('repo');
|
|
179
|
+
const repoPath = path.join(reposDir, repo);
|
|
180
|
+
return startRepoDelete(repoPath);
|
|
181
|
+
});
|
|
182
|
+
// GET /api/repos/:repo/delete/:executionId - Get repo delete status
|
|
183
|
+
app.get('/api/repos/:repo/delete/:executionId', (c) => {
|
|
184
|
+
const executionId = c.req.param('executionId');
|
|
185
|
+
return getRepoDeleteStatus(executionId);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// Mount repository-specific routes
|
|
189
|
+
// Each route file creates a sub-app that uses getRepoPath to resolve the repo
|
|
190
|
+
// Repository status and GC: /api/repos/:repo/status, /api/repos/:repo/gc
|
|
191
|
+
app.route('/api/repos/:repo', createRepositoryRoutes(storage, getRepoPath));
|
|
192
|
+
// Package routes: /api/repos/:repo/packages/*
|
|
193
|
+
app.route('/api/repos/:repo/packages', createPackageRoutes(storage, getRepoPath));
|
|
194
|
+
// Workspace routes: /api/repos/:repo/workspaces/*
|
|
195
|
+
app.route('/api/repos/:repo/workspaces', createWorkspaceRoutes(storage, getRepoPath));
|
|
196
|
+
// Dataset routes: /api/repos/:repo/workspaces/:ws/datasets/*
|
|
197
|
+
app.route('/api/repos/:repo/workspaces/:ws/datasets', createDatasetRoutes(storage, getRepoPath));
|
|
198
|
+
// Task routes: /api/repos/:repo/workspaces/:ws/tasks/*
|
|
199
|
+
app.route('/api/repos/:repo/workspaces/:ws/tasks', createTaskRoutes(storage, getRepoPath));
|
|
200
|
+
// Execution/Dataflow routes: /api/repos/:repo/workspaces/:ws/dataflow/*
|
|
201
|
+
app.route('/api/repos/:repo/workspaces/:ws/dataflow', createExecutionRoutes(storage, getRepoPath));
|
|
43
202
|
let httpServer = null;
|
|
44
203
|
let actualPort = port;
|
|
45
204
|
const server = {
|
package/dist/src/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAmB,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|