@elaraai/e3-api-server 0.0.2-beta.5 → 0.0.2-beta.51

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.
Files changed (123) hide show
  1. package/README.md +145 -30
  2. package/dist/src/async-operation-state.d.ts +37 -0
  3. package/dist/src/async-operation-state.d.ts.map +1 -0
  4. package/dist/src/async-operation-state.js +118 -0
  5. package/dist/src/async-operation-state.js.map +1 -0
  6. package/dist/src/auth/device.d.ts +26 -0
  7. package/dist/src/auth/device.d.ts.map +1 -0
  8. package/dist/src/auth/device.js +227 -0
  9. package/dist/src/auth/device.js.map +1 -0
  10. package/dist/src/auth/discovery.d.ts +23 -0
  11. package/dist/src/auth/discovery.d.ts.map +1 -0
  12. package/dist/src/auth/discovery.js +40 -0
  13. package/dist/src/auth/discovery.js.map +1 -0
  14. package/dist/src/auth/index.d.ts +56 -0
  15. package/dist/src/auth/index.d.ts.map +1 -0
  16. package/dist/src/auth/index.js +69 -0
  17. package/dist/src/auth/index.js.map +1 -0
  18. package/dist/src/auth/keys.d.ts +55 -0
  19. package/dist/src/auth/keys.d.ts.map +1 -0
  20. package/dist/src/auth/keys.js +78 -0
  21. package/dist/src/auth/keys.js.map +1 -0
  22. package/dist/src/beast2.d.ts +15 -3
  23. package/dist/src/beast2.d.ts.map +1 -1
  24. package/dist/src/beast2.js +38 -8
  25. package/dist/src/beast2.js.map +1 -1
  26. package/dist/src/cli.js +58 -6
  27. package/dist/src/cli.js.map +1 -1
  28. package/dist/src/errors.d.ts.map +1 -1
  29. package/dist/src/errors.js +8 -2
  30. package/dist/src/errors.js.map +1 -1
  31. package/dist/src/handlers/dataflow.d.ts +43 -0
  32. package/dist/src/handlers/dataflow.d.ts.map +1 -0
  33. package/dist/src/handlers/dataflow.js +363 -0
  34. package/dist/src/handlers/dataflow.js.map +1 -0
  35. package/dist/src/handlers/datasets.d.ts +39 -0
  36. package/dist/src/handlers/datasets.d.ts.map +1 -0
  37. package/dist/src/handlers/datasets.js +223 -0
  38. package/dist/src/handlers/datasets.js.map +1 -0
  39. package/dist/src/handlers/index.d.ts +11 -0
  40. package/dist/src/handlers/index.d.ts.map +1 -0
  41. package/dist/src/handlers/index.js +11 -0
  42. package/dist/src/handlers/index.js.map +1 -0
  43. package/dist/src/handlers/packages.d.ts +18 -0
  44. package/dist/src/handlers/packages.d.ts.map +1 -0
  45. package/dist/src/handlers/packages.js +51 -0
  46. package/dist/src/handlers/packages.js.map +1 -0
  47. package/dist/src/handlers/repository.d.ts +24 -0
  48. package/dist/src/handlers/repository.d.ts.map +1 -0
  49. package/dist/src/handlers/repository.js +79 -0
  50. package/dist/src/handlers/repository.js.map +1 -0
  51. package/dist/src/handlers/tasks.d.ts +18 -0
  52. package/dist/src/handlers/tasks.d.ts.map +1 -0
  53. package/dist/src/handlers/tasks.js +134 -0
  54. package/dist/src/handlers/tasks.js.map +1 -0
  55. package/dist/src/handlers/workspaces.d.ts +34 -0
  56. package/dist/src/handlers/workspaces.d.ts.map +1 -0
  57. package/dist/src/handlers/workspaces.js +225 -0
  58. package/dist/src/handlers/workspaces.js.map +1 -0
  59. package/dist/src/index.d.ts +3 -0
  60. package/dist/src/index.d.ts.map +1 -1
  61. package/dist/src/index.js +6 -0
  62. package/dist/src/index.js.map +1 -1
  63. package/dist/src/middleware/auth.d.ts +51 -0
  64. package/dist/src/middleware/auth.d.ts.map +1 -0
  65. package/dist/src/middleware/auth.js +158 -0
  66. package/dist/src/middleware/auth.js.map +1 -0
  67. package/dist/src/orchestrator-manager.d.ts +45 -0
  68. package/dist/src/orchestrator-manager.d.ts.map +1 -0
  69. package/dist/src/orchestrator-manager.js +150 -0
  70. package/dist/src/orchestrator-manager.js.map +1 -0
  71. package/dist/src/routes/data.d.ts +21 -0
  72. package/dist/src/routes/data.d.ts.map +1 -0
  73. package/dist/src/routes/data.js +123 -0
  74. package/dist/src/routes/data.js.map +1 -0
  75. package/dist/src/routes/datasets.d.ts +2 -1
  76. package/dist/src/routes/datasets.d.ts.map +1 -1
  77. package/dist/src/routes/datasets.js +59 -83
  78. package/dist/src/routes/datasets.js.map +1 -1
  79. package/dist/src/routes/executions.d.ts +2 -1
  80. package/dist/src/routes/executions.d.ts.map +1 -1
  81. package/dist/src/routes/executions.js +54 -287
  82. package/dist/src/routes/executions.js.map +1 -1
  83. package/dist/src/routes/index.d.ts +15 -0
  84. package/dist/src/routes/index.d.ts.map +1 -0
  85. package/dist/src/routes/index.js +15 -0
  86. package/dist/src/routes/index.js.map +1 -0
  87. package/dist/src/routes/objects.d.ts +8 -0
  88. package/dist/src/routes/objects.d.ts.map +1 -0
  89. package/dist/src/routes/objects.js +38 -0
  90. package/dist/src/routes/objects.js.map +1 -0
  91. package/dist/src/routes/package-transfer.d.ts +23 -0
  92. package/dist/src/routes/package-transfer.d.ts.map +1 -0
  93. package/dist/src/routes/package-transfer.js +152 -0
  94. package/dist/src/routes/package-transfer.js.map +1 -0
  95. package/dist/src/routes/packages.d.ts +2 -1
  96. package/dist/src/routes/packages.d.ts.map +1 -1
  97. package/dist/src/routes/packages.js +18 -109
  98. package/dist/src/routes/packages.js.map +1 -1
  99. package/dist/src/routes/repository.d.ts +2 -1
  100. package/dist/src/routes/repository.d.ts.map +1 -1
  101. package/dist/src/routes/repository.js +19 -54
  102. package/dist/src/routes/repository.js.map +1 -1
  103. package/dist/src/routes/tasks.d.ts +2 -1
  104. package/dist/src/routes/tasks.d.ts.map +1 -1
  105. package/dist/src/routes/tasks.js +22 -46
  106. package/dist/src/routes/tasks.js.map +1 -1
  107. package/dist/src/routes/transfer.d.ts +19 -0
  108. package/dist/src/routes/transfer.d.ts.map +1 -0
  109. package/dist/src/routes/transfer.js +124 -0
  110. package/dist/src/routes/transfer.js.map +1 -0
  111. package/dist/src/routes/workspaces.d.ts +2 -1
  112. package/dist/src/routes/workspaces.d.ts.map +1 -1
  113. package/dist/src/routes/workspaces.js +83 -112
  114. package/dist/src/routes/workspaces.js.map +1 -1
  115. package/dist/src/server.d.ts +24 -3
  116. package/dist/src/server.d.ts.map +1 -1
  117. package/dist/src/server.js +270 -19
  118. package/dist/src/server.js.map +1 -1
  119. package/dist/src/types.d.ts +765 -1222
  120. package/dist/src/types.d.ts.map +1 -1
  121. package/dist/src/types.js +65 -407
  122. package/dist/src/types.js.map +1 -1
  123. package/package.json +16 -4
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import { Hono } from 'hono';
6
+ import { mkdir, readFile, unlink } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { tmpdir } from 'node:os';
9
+ import { randomUUID } from 'node:crypto';
10
+ import { variant, NullType } from '@elaraai/east';
11
+ import { urlPathToTreePath } from '@elaraai/e3-types';
12
+ import { computeHash, workspaceSetDatasetByHash, } from '@elaraai/e3-core';
13
+ import { decodeBody, sendSuccess, sendError } from '../beast2.js';
14
+ import { TransferUploadRequestType, TransferUploadResponseType, TransferDoneResponseType } from '../types.js';
15
+ const STAGING_DIR = join(tmpdir(), 'e3-transfers');
16
+ /**
17
+ * Create dataset transfer routes.
18
+ *
19
+ * Returns an `api` Hono app with authenticated routes (init upload, commit)
20
+ * mounted at /api/repos/:repo/workspaces/:ws/datasets.
21
+ *
22
+ * Unauthenticated data routes (upload/download bytes) are handled by the
23
+ * generic data endpoints in `data.ts`.
24
+ */
25
+ export function createTransferRoutes(storage, getRepoPath, transferBackend) {
26
+ const api = new Hono();
27
+ /**
28
+ * Extract dataset path from the request URL wildcard.
29
+ * The route is mounted at /api/repos/:repo/workspaces/:ws/datasets
30
+ * so a request to .../datasets/inputs/config/upload yields path "inputs/config".
31
+ */
32
+ function extractDatasetPath(c, suffix) {
33
+ const fullPath = c.req.path;
34
+ const repo = c.req.param('repo');
35
+ const ws = c.req.param('ws');
36
+ const datasetsPrefix = `/api/repos/${encodeURIComponent(repo)}/workspaces/${encodeURIComponent(ws)}/datasets/`;
37
+ let pathStr = fullPath.startsWith(datasetsPrefix) ? fullPath.slice(datasetsPrefix.length) : '';
38
+ // Strip trailing suffix (e.g. "/upload" or "/upload/<id>")
39
+ if (pathStr.endsWith(suffix)) {
40
+ pathStr = pathStr.slice(0, -suffix.length);
41
+ }
42
+ // Remove trailing slash
43
+ if (pathStr.endsWith('/')) {
44
+ pathStr = pathStr.slice(0, -1);
45
+ }
46
+ return pathStr;
47
+ }
48
+ // =========================================================================
49
+ // Authenticated API routes (mounted at /api/repos/:repo/workspaces/:ws/datasets)
50
+ // =========================================================================
51
+ // POST routes use catch-all wildcard and dispatch based on URL suffix:
52
+ // - .../datasets/<path>/upload → init transfer
53
+ // - .../datasets/<path>/upload/<id> → commit transfer
54
+ api.post('/*', async (c) => {
55
+ const fullPath = c.req.path;
56
+ // Check for commit: .../upload/<uuid>
57
+ const commitMatch = fullPath.match(/\/upload\/([0-9a-f-]{36})$/);
58
+ if (commitMatch) {
59
+ return handleCommit(c, commitMatch[1]);
60
+ }
61
+ // Check for init: .../upload
62
+ if (fullPath.endsWith('/upload')) {
63
+ return handleInit(c);
64
+ }
65
+ // Not a transfer route — return 404
66
+ return new Response('Not found', { status: 404 });
67
+ });
68
+ async function handleInit(c) {
69
+ const repo = c.req.param('repo');
70
+ const ws = c.req.param('ws');
71
+ const repoPath = getRepoPath(repo);
72
+ const pathStr = extractDatasetPath(c, '/upload');
73
+ const { hash, size } = await decodeBody(c, TransferUploadRequestType);
74
+ // Dedup check — object already verified when originally stored
75
+ if (await storage.objects.exists(repoPath, hash)) {
76
+ const treePath = urlPathToTreePath(pathStr);
77
+ await workspaceSetDatasetByHash(storage, repoPath, ws, treePath, hash, new Map());
78
+ return sendSuccess(TransferUploadResponseType, variant('completed', null));
79
+ }
80
+ // Create transfer record in backend
81
+ const transferId = randomUUID();
82
+ await transferBackend.datasetUpload.create(transferId, { repo, workspace: ws, path: pathStr, hash, size });
83
+ // Create staging slot in OS temp dir
84
+ await mkdir(STAGING_DIR, { recursive: true });
85
+ const uploadUrl = await transferBackend.datasetUpload.getUploadUrl(transferId, repo, hash);
86
+ // Resolve relative URL against the request origin
87
+ const origin = new URL(c.req.url).origin;
88
+ const resolvedUrl = uploadUrl.startsWith('/') ? `${origin}${uploadUrl}` : uploadUrl;
89
+ return sendSuccess(TransferUploadResponseType, variant('upload', { id: transferId, uploadUrl: resolvedUrl }));
90
+ }
91
+ async function handleCommit(c, id) {
92
+ const transfer = await transferBackend.datasetUpload.get(id);
93
+ if (!transfer) {
94
+ return sendError(NullType, variant('internal', { message: 'transfer not found' }));
95
+ }
96
+ const repoPath = getRepoPath(transfer.repo);
97
+ const stagingPath = join(STAGING_DIR, `${id}.beast2.partial`);
98
+ try {
99
+ // Read from staging to verify size and hash
100
+ const data = await readFile(stagingPath);
101
+ if (BigInt(data.byteLength) !== transfer.size) {
102
+ await unlink(stagingPath).catch(() => { });
103
+ return sendSuccess(TransferDoneResponseType, variant('error', { message: `size mismatch: expected ${transfer.size}, got ${data.byteLength}` }));
104
+ }
105
+ const actualHash = computeHash(data);
106
+ if (actualHash !== transfer.hash) {
107
+ await unlink(stagingPath).catch(() => { });
108
+ return sendSuccess(TransferDoneResponseType, variant('error', { message: `hash mismatch: expected ${transfer.hash}, got ${actualHash}` }));
109
+ }
110
+ // Write through storage abstraction (re-hashes internally, that's fine)
111
+ await storage.objects.write(repoPath, data);
112
+ await unlink(stagingPath).catch(() => { });
113
+ // Update dataset ref
114
+ const treePath = urlPathToTreePath(transfer.path);
115
+ await workspaceSetDatasetByHash(storage, repoPath, transfer.workspace, treePath, actualHash, new Map());
116
+ return sendSuccess(TransferDoneResponseType, variant('completed', null));
117
+ }
118
+ finally {
119
+ await transferBackend.datasetUpload.delete(id);
120
+ }
121
+ }
122
+ return { api };
123
+ }
124
+ //# sourceMappingURL=transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../../src/routes/transfer.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,6 @@
3
3
  * Licensed under BSL 1.1. See LICENSE for details.
4
4
  */
5
5
  import { Hono } from 'hono';
6
- export declare function createWorkspaceRoutes(repoPath: string): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
6
+ import type { StorageBackend, TransferBackend } from '@elaraai/e3-core';
7
+ export declare function createWorkspaceRoutes(storage: StorageBackend, getRepoPath: (repo: string) => string, transferBackend?: TransferBackend): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
7
8
  //# sourceMappingURL=workspaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgB5B,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,8EAyHrD"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAexE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EACrC,eAAe,CAAC,EAAE,eAAe,8EAsGlC"}
@@ -2,131 +2,102 @@
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 { ArrayType, BlobType, NullType, some, none } from '@elaraai/east';
10
- import { WorkspaceStateType, parsePackageRef } from '@elaraai/e3-types';
11
- import { workspaceList, workspaceCreate, workspaceRemove, workspaceGetState, workspaceDeploy, workspaceExport, packageGetLatestVersion, } from '@elaraai/e3-core';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { variant, some } from '@elaraai/east';
8
+ import { workspaceGetState } from '@elaraai/e3-core';
9
+ import { PackageJobResponseType } from '@elaraai/e3-types';
10
+ import { listWorkspaces, createWorkspace, getWorkspace, getWorkspaceStatus, deleteWorkspace, deployWorkspace, exportWorkspace, } from '../handlers/workspaces.js';
12
11
  import { decodeBody, sendSuccess, sendError } from '../beast2.js';
13
- import { errorToVariant } from '../errors.js';
14
- import { WorkspaceInfoType, CreateWorkspaceType, DeployRequestType } from '../types.js';
15
- export function createWorkspaceRoutes(repoPath) {
12
+ import { WorkspaceCreateRequestType, WorkspaceDeployRequestType, WorkspaceExportRequestType } from '../types.js';
13
+ export function createWorkspaceRoutes(storage, getRepoPath, transferBackend) {
16
14
  const app = new Hono();
17
- // GET /api/workspaces - List all workspaces
15
+ // GET /api/repos/:repo/workspaces - List all workspaces
18
16
  app.get('/', async (c) => {
19
- try {
20
- const workspaces = await workspaceList(repoPath);
21
- const result = await Promise.all(workspaces.map(async (name) => {
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
- }
17
+ const repo = c.req.param('repo');
18
+ const repoPath = getRepoPath(repo);
19
+ return listWorkspaces(storage, repoPath);
45
20
  });
46
- // POST /api/workspaces - Create a new workspace
21
+ // POST /api/repos/:repo/workspaces - Create a new workspace
47
22
  app.post('/', async (c) => {
48
- try {
49
- const body = await decodeBody(c, CreateWorkspaceType);
50
- await workspaceCreate(repoPath, body.name);
51
- return sendSuccess(c, WorkspaceInfoType, {
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
- }
23
+ const repo = c.req.param('repo');
24
+ const repoPath = getRepoPath(repo);
25
+ const body = await decodeBody(c, WorkspaceCreateRequestType);
26
+ return createWorkspace(storage, repoPath, body.name);
61
27
  });
62
- // GET /api/workspaces/:name - Get workspace state
63
- app.get('/:name', async (c) => {
64
- try {
65
- const name = c.req.param('name');
66
- const state = await workspaceGetState(repoPath, name);
67
- if (!state) {
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
- }
28
+ // GET /api/repos/:repo/workspaces/:ws - Get workspace state
29
+ app.get('/:ws', async (c) => {
30
+ const repo = c.req.param('repo');
31
+ const repoPath = getRepoPath(repo);
32
+ const ws = c.req.param('ws');
33
+ return getWorkspace(storage, repoPath, ws);
76
34
  });
77
- // DELETE /api/workspaces/:name - Remove a workspace
78
- app.delete('/:name', async (c) => {
79
- try {
80
- const name = c.req.param('name');
81
- await workspaceRemove(repoPath, name);
82
- return sendSuccess(c, NullType, null);
83
- }
84
- catch (err) {
85
- return sendError(c, NullType, errorToVariant(err));
86
- }
35
+ // GET /api/repos/:repo/workspaces/:ws/status - Get comprehensive workspace status
36
+ app.get('/:ws/status', (c) => {
37
+ const repo = c.req.param('repo');
38
+ const repoPath = getRepoPath(repo);
39
+ const ws = c.req.param('ws');
40
+ return getWorkspaceStatus(storage, repoPath, ws);
87
41
  });
88
- // POST /api/workspaces/:name/deploy - Deploy a package to a workspace
89
- app.post('/:name/deploy', async (c) => {
90
- try {
91
- const name = c.req.param('name');
92
- if (!name) {
93
- return sendError(c, NullType, errorToVariant(new Error('Missing workspace name parameter')));
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
- }
42
+ // DELETE /api/repos/:repo/workspaces/:ws - Remove a workspace
43
+ app.delete('/:ws', async (c) => {
44
+ const repo = c.req.param('repo');
45
+ const repoPath = getRepoPath(repo);
46
+ const ws = c.req.param('ws');
47
+ return deleteWorkspace(storage, repoPath, ws);
107
48
  });
108
- // GET /api/workspaces/:name/export - Export workspace as a package zip
109
- app.get('/:name/export', async (c) => {
110
- try {
111
- const name = c.req.param('name');
112
- if (!name) {
113
- return sendError(c, BlobType, errorToVariant(new Error('Missing workspace name parameter')));
114
- }
115
- // Export to temp file
116
- const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-ws-export-'));
117
- const tempPath = path.join(tempDir, 'workspace.zip');
49
+ // POST /api/repos/:repo/workspaces/:ws/deploy - Deploy a package to a workspace
50
+ app.post('/:ws/deploy', async (c) => {
51
+ const repo = c.req.param('repo');
52
+ const repoPath = getRepoPath(repo);
53
+ const ws = c.req.param('ws');
54
+ const body = await decodeBody(c, WorkspaceDeployRequestType);
55
+ return deployWorkspace(storage, repoPath, ws, body.packageRef);
56
+ });
57
+ // POST /api/repos/:repo/workspaces/:ws/export - Trigger async workspace export
58
+ if (transferBackend) {
59
+ app.post('/:ws/export', async (c) => {
60
+ const repo = c.req.param('repo');
61
+ const repoPath = getRepoPath(repo);
62
+ const ws = c.req.param('ws');
63
+ // Determine name and version from request body or deployed package
64
+ let requestName;
65
+ let requestVersion;
118
66
  try {
119
- await workspaceExport(repoPath, name, tempPath);
120
- const archive = await fs.readFile(tempPath);
121
- return sendSuccess(c, BlobType, new Uint8Array(archive));
67
+ const body = await decodeBody(c, WorkspaceExportRequestType);
68
+ if (body.name?.type === 'some')
69
+ requestName = body.name.value;
70
+ if (body.version?.type === 'some')
71
+ requestVersion = body.version.value;
122
72
  }
123
- finally {
124
- await fs.rm(tempDir, { recursive: true, force: true });
73
+ catch {
74
+ // No body or invalid use defaults
125
75
  }
126
- }
127
- catch (err) {
128
- return sendError(c, BlobType, errorToVariant(err));
129
- }
76
+ const state = await workspaceGetState(storage, repoPath, ws);
77
+ if (!state) {
78
+ return sendError(PackageJobResponseType, variant('internal', { message: 'workspace not found or not deployed' }));
79
+ }
80
+ const exportName = requestName ?? state.packageName;
81
+ const exportVersion = requestVersion ?? `${state.packageVersion}-${Date.now().toString(36)}`;
82
+ const id = randomUUID();
83
+ await transferBackend.packageExport.create(id, {
84
+ repo,
85
+ name: exportName,
86
+ version: exportVersion,
87
+ workspace: some(ws),
88
+ status: variant('processing', variant('pending', null)),
89
+ createdAt: new Date(),
90
+ });
91
+ await transferBackend.packageExport.execute(id, repo);
92
+ return sendSuccess(PackageJobResponseType, { id });
93
+ });
94
+ }
95
+ // GET /api/repos/:repo/workspaces/:ws/export - Export workspace as a package zip
96
+ app.get('/:ws/export', async (c) => {
97
+ const repo = c.req.param('repo');
98
+ const repoPath = getRepoPath(repo);
99
+ const ws = c.req.param('ws');
100
+ return exportWorkspace(storage, repoPath, ws);
130
101
  });
131
102
  return app;
132
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../src/routes/workspaces.ts"],"names":[],"mappings":"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"}
@@ -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
- /** Path to e3 repository (required) */
11
- repo: string;
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
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ3D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;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;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAgFzD"}
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;AAezF,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,CAuVxE"}