@elaraai/e3-api-server 0.0.2-beta.4 → 0.0.2-beta.40
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 +145 -30
- package/dist/src/async-operation-state.d.ts +37 -0
- package/dist/src/async-operation-state.d.ts.map +1 -0
- package/dist/src/async-operation-state.js +118 -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 +38 -8
- 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 +8 -2
- package/dist/src/errors.js.map +1 -1
- package/dist/src/handlers/dataflow.d.ts +43 -0
- package/dist/src/handlers/dataflow.d.ts.map +1 -0
- package/dist/src/handlers/dataflow.js +363 -0
- package/dist/src/handlers/dataflow.js.map +1 -0
- package/dist/src/handlers/datasets.d.ts +38 -0
- package/dist/src/handlers/datasets.d.ts.map +1 -0
- package/dist/src/handlers/datasets.js +222 -0
- package/dist/src/handlers/datasets.js.map +1 -0
- package/dist/src/handlers/index.d.ts +11 -0
- package/dist/src/handlers/index.d.ts.map +1 -0
- package/dist/src/handlers/index.js +11 -0
- package/dist/src/handlers/index.js.map +1 -0
- package/dist/src/handlers/packages.d.ts +18 -0
- package/dist/src/handlers/packages.d.ts.map +1 -0
- package/dist/src/handlers/packages.js +51 -0
- package/dist/src/handlers/packages.js.map +1 -0
- package/dist/src/handlers/repository.d.ts +24 -0
- package/dist/src/handlers/repository.d.ts.map +1 -0
- package/dist/src/handlers/repository.js +79 -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/orchestrator-manager.d.ts +45 -0
- package/dist/src/orchestrator-manager.d.ts.map +1 -0
- package/dist/src/orchestrator-manager.js +150 -0
- package/dist/src/orchestrator-manager.js.map +1 -0
- package/dist/src/routes/data.d.ts +21 -0
- package/dist/src/routes/data.d.ts.map +1 -0
- package/dist/src/routes/data.js +125 -0
- package/dist/src/routes/data.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 +59 -83
- 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 +54 -287
- package/dist/src/routes/executions.js.map +1 -1
- package/dist/src/routes/index.d.ts +15 -0
- package/dist/src/routes/index.d.ts.map +1 -0
- package/dist/src/routes/index.js +15 -0
- package/dist/src/routes/index.js.map +1 -0
- package/dist/src/routes/objects.d.ts +8 -0
- package/dist/src/routes/objects.d.ts.map +1 -0
- package/dist/src/routes/objects.js +38 -0
- package/dist/src/routes/objects.js.map +1 -0
- package/dist/src/routes/package-transfer.d.ts +23 -0
- package/dist/src/routes/package-transfer.d.ts.map +1 -0
- package/dist/src/routes/package-transfer.js +168 -0
- package/dist/src/routes/package-transfer.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 +18 -109
- 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/transfer.d.ts +19 -0
- package/dist/src/routes/transfer.d.ts.map +1 -0
- package/dist/src/routes/transfer.js +124 -0
- package/dist/src/routes/transfer.js.map +1 -0
- 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 +266 -19
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +1385 -731
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +238 -2
- package/dist/src/types.js.map +1 -1
- package/package.json +16 -4
|
@@ -0,0 +1,168 @@
|
|
|
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, unlink, stat } 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 } from '@elaraai/east';
|
|
11
|
+
import { packageImport, packageExport, PackageNotFoundError, } from '@elaraai/e3-core';
|
|
12
|
+
import { PackageTransferInitRequestType, PackageTransferInitResponseType, PackageJobResponseType, PackageImportStatusType, PackageExportStatusType, } from '@elaraai/e3-types';
|
|
13
|
+
import { decodeBody, sendSuccess, sendError } from '../beast2.js';
|
|
14
|
+
import { errorToVariant } from '../errors.js';
|
|
15
|
+
const STAGING_DIR = join(tmpdir(), 'e3-transfers');
|
|
16
|
+
/**
|
|
17
|
+
* Create package transfer routes.
|
|
18
|
+
*
|
|
19
|
+
* Returns two Hono apps:
|
|
20
|
+
* - `repoApi`: Authenticated routes at repo level — mount at /api/repos/:repo
|
|
21
|
+
* (POST /import, POST /import/:id, GET /import/:id, GET /export/:id)
|
|
22
|
+
* - `pkgApi`: Authenticated routes at package level — mount at /api/repos/:repo/packages
|
|
23
|
+
* (POST /:name/:version/export)
|
|
24
|
+
*
|
|
25
|
+
* Unauthenticated data routes (upload/download bytes) are handled by the
|
|
26
|
+
* generic data endpoints in `data.ts`.
|
|
27
|
+
*/
|
|
28
|
+
export function createPackageTransferRoutes(storage, getRepoPath, transferBackend) {
|
|
29
|
+
const repoApi = new Hono();
|
|
30
|
+
const pkgApi = new Hono();
|
|
31
|
+
const MAX_PACKAGE_SIZE = 5n * 1024n * 1024n * 1024n; // 5 GB
|
|
32
|
+
// =========================================================================
|
|
33
|
+
// Repo-level routes (mounted at /api/repos/:repo)
|
|
34
|
+
// =========================================================================
|
|
35
|
+
// POST /api/repos/:repo/import — Init import
|
|
36
|
+
repoApi.post('/import', async (c) => {
|
|
37
|
+
const repo = c.req.param('repo');
|
|
38
|
+
const { size } = await decodeBody(c, PackageTransferInitRequestType);
|
|
39
|
+
if (size <= 0n || size > MAX_PACKAGE_SIZE) {
|
|
40
|
+
return sendError(PackageTransferInitResponseType, variant('internal', {
|
|
41
|
+
message: `Invalid size: must be between 1 and ${MAX_PACKAGE_SIZE} bytes`,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
const transferId = randomUUID();
|
|
45
|
+
await transferBackend.packageImport.create(transferId, {
|
|
46
|
+
repo,
|
|
47
|
+
size,
|
|
48
|
+
status: variant('created', null),
|
|
49
|
+
createdAt: new Date(),
|
|
50
|
+
});
|
|
51
|
+
await mkdir(STAGING_DIR, { recursive: true });
|
|
52
|
+
const uploadUrl = await transferBackend.packageImport.getUploadUrl(transferId, repo);
|
|
53
|
+
// Resolve relative URL against the request origin
|
|
54
|
+
const origin = new URL(c.req.url).origin;
|
|
55
|
+
const resolvedUrl = uploadUrl.startsWith('/') ? `${origin}${uploadUrl}` : uploadUrl;
|
|
56
|
+
return sendSuccess(PackageTransferInitResponseType, { id: transferId, uploadUrl: resolvedUrl });
|
|
57
|
+
});
|
|
58
|
+
// POST /api/repos/:repo/import/:id — Trigger import
|
|
59
|
+
repoApi.post('/import/:id', async (c) => {
|
|
60
|
+
const id = c.req.param('id');
|
|
61
|
+
const record = await transferBackend.packageImport.get(id);
|
|
62
|
+
if (!record) {
|
|
63
|
+
return sendError(PackageJobResponseType, variant('internal', { message: 'transfer not found' }));
|
|
64
|
+
}
|
|
65
|
+
const repoPath = getRepoPath(record.repo);
|
|
66
|
+
const stagingPath = join(STAGING_DIR, `${id}.zip.partial`);
|
|
67
|
+
try {
|
|
68
|
+
const result = await packageImport(storage, repoPath, stagingPath);
|
|
69
|
+
await transferBackend.packageImport.updateStatus(id, variant('completed', {
|
|
70
|
+
name: result.name,
|
|
71
|
+
version: result.version,
|
|
72
|
+
packageHash: result.packageHash,
|
|
73
|
+
objectCount: BigInt(result.objectCount),
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
+
await transferBackend.packageImport.updateStatus(id, variant('failed', { message }));
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await unlink(stagingPath).catch(() => { });
|
|
82
|
+
}
|
|
83
|
+
return sendSuccess(PackageJobResponseType, { id });
|
|
84
|
+
});
|
|
85
|
+
// GET /api/repos/:repo/import/:id — Poll import status
|
|
86
|
+
repoApi.get('/import/:id', async (c) => {
|
|
87
|
+
const id = c.req.param('id');
|
|
88
|
+
const record = await transferBackend.packageImport.get(id);
|
|
89
|
+
if (!record) {
|
|
90
|
+
return sendError(PackageImportStatusType, variant('internal', { message: 'import job not found' }));
|
|
91
|
+
}
|
|
92
|
+
const { type, value } = record.status;
|
|
93
|
+
if (type === 'processing' || type === 'created' || type === 'uploaded') {
|
|
94
|
+
return sendSuccess(PackageImportStatusType, variant('processing', null));
|
|
95
|
+
}
|
|
96
|
+
if (type === 'failed') {
|
|
97
|
+
return sendSuccess(PackageImportStatusType, variant('failed', { message: value.message }));
|
|
98
|
+
}
|
|
99
|
+
if (type === 'completed') {
|
|
100
|
+
return sendSuccess(PackageImportStatusType, variant('completed', value));
|
|
101
|
+
}
|
|
102
|
+
return sendError(PackageImportStatusType, variant('internal', { message: 'unknown status' }));
|
|
103
|
+
});
|
|
104
|
+
// GET /api/repos/:repo/export/:id — Poll export status
|
|
105
|
+
repoApi.get('/export/:id', async (c) => {
|
|
106
|
+
const id = c.req.param('id');
|
|
107
|
+
const record = await transferBackend.packageExport.get(id);
|
|
108
|
+
if (!record) {
|
|
109
|
+
return sendError(PackageExportStatusType, variant('internal', { message: 'export job not found' }));
|
|
110
|
+
}
|
|
111
|
+
const { type, value } = record.status;
|
|
112
|
+
if (type === 'processing') {
|
|
113
|
+
return sendSuccess(PackageExportStatusType, variant('processing', null));
|
|
114
|
+
}
|
|
115
|
+
if (type === 'failed') {
|
|
116
|
+
return sendSuccess(PackageExportStatusType, variant('failed', { message: value.message }));
|
|
117
|
+
}
|
|
118
|
+
if (type === 'completed') {
|
|
119
|
+
const downloadUrl = await transferBackend.packageExport.getDownloadUrl(id, record.repo);
|
|
120
|
+
// Resolve relative URL against the request origin
|
|
121
|
+
const origin = new URL(c.req.url).origin;
|
|
122
|
+
const resolvedUrl = downloadUrl.startsWith('/') ? `${origin}${downloadUrl}` : downloadUrl;
|
|
123
|
+
return sendSuccess(PackageExportStatusType, variant('completed', {
|
|
124
|
+
downloadUrl: resolvedUrl,
|
|
125
|
+
size: value.size,
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
return sendError(PackageExportStatusType, variant('internal', { message: 'unknown status' }));
|
|
129
|
+
});
|
|
130
|
+
// =========================================================================
|
|
131
|
+
// Package-level routes (mounted at /api/repos/:repo/packages)
|
|
132
|
+
// =========================================================================
|
|
133
|
+
// POST /api/repos/:repo/packages/:name/:version/export — Trigger export
|
|
134
|
+
pkgApi.post('/:name/:version/export', async (c) => {
|
|
135
|
+
const repo = c.req.param('repo');
|
|
136
|
+
const repoPath = getRepoPath(repo);
|
|
137
|
+
const name = c.req.param('name');
|
|
138
|
+
const version = c.req.param('version');
|
|
139
|
+
const id = randomUUID();
|
|
140
|
+
await transferBackend.packageExport.create(id, {
|
|
141
|
+
repo,
|
|
142
|
+
name,
|
|
143
|
+
version,
|
|
144
|
+
status: variant('processing', null),
|
|
145
|
+
createdAt: new Date(),
|
|
146
|
+
});
|
|
147
|
+
await mkdir(STAGING_DIR, { recursive: true });
|
|
148
|
+
const zipPath = join(STAGING_DIR, `${id}.zip`);
|
|
149
|
+
try {
|
|
150
|
+
await packageExport(storage, repoPath, name, version, zipPath);
|
|
151
|
+
const fileStat = await stat(zipPath);
|
|
152
|
+
await transferBackend.packageExport.updateStatus(id, variant('completed', {
|
|
153
|
+
size: BigInt(fileStat.size),
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
await unlink(zipPath).catch(() => { });
|
|
158
|
+
if (err instanceof PackageNotFoundError) {
|
|
159
|
+
return sendError(PackageJobResponseType, errorToVariant(err));
|
|
160
|
+
}
|
|
161
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
162
|
+
await transferBackend.packageExport.updateStatus(id, variant('failed', { message }));
|
|
163
|
+
}
|
|
164
|
+
return sendSuccess(PackageJobResponseType, { id });
|
|
165
|
+
});
|
|
166
|
+
return { repoApi, pkgApi };
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=package-transfer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-transfer.js","sourceRoot":"","sources":["../../../src/routes/package-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
|
-
|
|
6
|
+
import type { StorageBackend } from '@elaraai/e3-core';
|
|
7
|
+
export declare function createPackageRoutes(storage: StorageBackend, getRepoPath: (repo: string) => string): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
7
8
|
//# sourceMappingURL=packages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packages.d.ts","sourceRoot":"","sources":["../../../src/routes/packages.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"packages.d.ts","sourceRoot":"","sources":["../../../src/routes/packages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOvD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,8EA8BtC"}
|
|
@@ -2,122 +2,31 @@
|
|
|
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
|
-
|
|
11
|
-
import { PackageObjectType } from '@elaraai/e3-types';
|
|
12
|
-
import { sendSuccess, sendError } from '../beast2.js';
|
|
13
|
-
import { errorToVariant } from '../errors.js';
|
|
14
|
-
import { PackageListItemType, PackageImportResultType } from '../types.js';
|
|
15
|
-
export function createPackageRoutes(repoPath) {
|
|
6
|
+
import { listPackages, getPackage, deletePackage, } from '../handlers/packages.js';
|
|
7
|
+
export function createPackageRoutes(storage, getRepoPath) {
|
|
16
8
|
const app = new Hono();
|
|
17
|
-
// GET /api/packages - List all packages
|
|
9
|
+
// GET /api/repos/:repo/packages - List all packages
|
|
18
10
|
app.get('/', async (c) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
name: pkg.name,
|
|
23
|
-
version: pkg.version,
|
|
24
|
-
}));
|
|
25
|
-
return sendSuccess(c, ArrayType(PackageListItemType), result);
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
return sendError(c, ArrayType(PackageListItemType), errorToVariant(err));
|
|
29
|
-
}
|
|
11
|
+
const repo = c.req.param('repo');
|
|
12
|
+
const repoPath = getRepoPath(repo);
|
|
13
|
+
return listPackages(storage, repoPath);
|
|
30
14
|
});
|
|
31
|
-
// GET /api/packages/:name/:version - Get package details
|
|
15
|
+
// GET /api/repos/:repo/packages/:name/:version - Get package details
|
|
32
16
|
app.get('/:name/:version', async (c) => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
const pkg = await packageRead(repoPath, name, version);
|
|
40
|
-
return sendSuccess(c, PackageObjectType, pkg);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
return sendError(c, PackageObjectType, errorToVariant(err));
|
|
44
|
-
}
|
|
17
|
+
const repo = c.req.param('repo');
|
|
18
|
+
const repoPath = getRepoPath(repo);
|
|
19
|
+
const name = c.req.param('name');
|
|
20
|
+
const version = c.req.param('version');
|
|
21
|
+
return getPackage(storage, repoPath, name, version);
|
|
45
22
|
});
|
|
46
|
-
//
|
|
47
|
-
app.post('/', async (c) => {
|
|
48
|
-
try {
|
|
49
|
-
// Read raw body as zip bytes
|
|
50
|
-
const contentType = c.req.header('content-type');
|
|
51
|
-
let archive;
|
|
52
|
-
if (contentType === 'application/beast2') {
|
|
53
|
-
// BEAST2 encoded blob
|
|
54
|
-
const { decodeBody } = await import('../beast2.js');
|
|
55
|
-
archive = await decodeBody(c, BlobType);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// Raw zip bytes
|
|
59
|
-
const buffer = await c.req.arrayBuffer();
|
|
60
|
-
archive = new Uint8Array(buffer);
|
|
61
|
-
}
|
|
62
|
-
// Write to temp file
|
|
63
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-import-'));
|
|
64
|
-
const tempPath = path.join(tempDir, 'package.zip');
|
|
65
|
-
try {
|
|
66
|
-
await fs.writeFile(tempPath, archive);
|
|
67
|
-
const result = await packageImport(repoPath, tempPath);
|
|
68
|
-
return sendSuccess(c, PackageImportResultType, {
|
|
69
|
-
name: result.name,
|
|
70
|
-
version: result.version,
|
|
71
|
-
packageHash: result.packageHash,
|
|
72
|
-
objectCount: BigInt(result.objectCount),
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
finally {
|
|
76
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
return sendError(c, PackageImportResultType, errorToVariant(err));
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
// GET /api/packages/:name/:version/export - Export package as zip
|
|
84
|
-
app.get('/:name/:version/export', async (c) => {
|
|
85
|
-
try {
|
|
86
|
-
const name = c.req.param('name');
|
|
87
|
-
const version = c.req.param('version');
|
|
88
|
-
if (!name || !version) {
|
|
89
|
-
return sendError(c, BlobType, errorToVariant(new Error('Missing name or version parameter')));
|
|
90
|
-
}
|
|
91
|
-
// Export to temp file
|
|
92
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-export-'));
|
|
93
|
-
const tempPath = path.join(tempDir, 'package.zip');
|
|
94
|
-
try {
|
|
95
|
-
await packageExport(repoPath, name, version, tempPath);
|
|
96
|
-
const archive = await fs.readFile(tempPath);
|
|
97
|
-
return sendSuccess(c, BlobType, new Uint8Array(archive));
|
|
98
|
-
}
|
|
99
|
-
finally {
|
|
100
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch (err) {
|
|
104
|
-
return sendError(c, BlobType, errorToVariant(err));
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
// DELETE /api/packages/:name/:version - Remove a package
|
|
23
|
+
// DELETE /api/repos/:repo/packages/:name/:version - Remove a package
|
|
108
24
|
app.delete('/:name/:version', async (c) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
await packageRemove(repoPath, name, version);
|
|
116
|
-
return sendSuccess(c, NullType, null);
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
return sendError(c, NullType, errorToVariant(err));
|
|
120
|
-
}
|
|
25
|
+
const repo = c.req.param('repo');
|
|
26
|
+
const repoPath = getRepoPath(repo);
|
|
27
|
+
const name = c.req.param('name');
|
|
28
|
+
const version = c.req.param('version');
|
|
29
|
+
return deletePackage(storage, repoPath, name, version);
|
|
121
30
|
});
|
|
122
31
|
return app;
|
|
123
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packages.js","sourceRoot":"","sources":["../../../src/routes/packages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"packages.js","sourceRoot":"","sources":["../../../src/routes/packages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,MAAM,UAAU,mBAAmB,CACjC,OAAuB,EACvB,WAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,oDAAoD;IACpD,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,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,qEAAqE;IACrE,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,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,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAE,CAAC;QACxC,OAAO,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,qEAAqE;IACrE,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxC,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,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QAClC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAE,CAAC;QACxC,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
5
|
import { Hono } from 'hono';
|
|
6
|
-
|
|
6
|
+
import type { StorageBackend } from '@elaraai/e3-core';
|
|
7
|
+
export declare function createRepositoryRoutes(storage: StorageBackend, getRepoPath: (repo: string) => string): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
7
8
|
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/routes/repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/routes/repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,8EA2BtC"}
|
|
@@ -2,65 +2,30 @@
|
|
|
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 path from 'node:path';
|
|
7
5
|
import { Hono } from 'hono';
|
|
8
|
-
import {
|
|
9
|
-
import { decodeBody
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
export function createRepositoryRoutes(repoPath) {
|
|
6
|
+
import { getStatus, startGc, getGcStatus } from '../handlers/repository.js';
|
|
7
|
+
import { decodeBody } from '../beast2.js';
|
|
8
|
+
import { GcRequestType } from '../types.js';
|
|
9
|
+
export function createRepositoryRoutes(storage, getRepoPath) {
|
|
13
10
|
const app = new Hono();
|
|
14
|
-
// GET /api/status - Get repository status
|
|
11
|
+
// GET /api/repos/:repo/status - Get repository status
|
|
15
12
|
app.get('/status', async (c) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let objectCount = 0;
|
|
20
|
-
try {
|
|
21
|
-
const subdirs = await fs.readdir(objectsDir);
|
|
22
|
-
for (const subdir of subdirs) {
|
|
23
|
-
if (subdir.length === 2) {
|
|
24
|
-
const files = await fs.readdir(path.join(objectsDir, subdir));
|
|
25
|
-
objectCount += files.length;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
// objects dir doesn't exist
|
|
31
|
-
}
|
|
32
|
-
// Count packages and workspaces
|
|
33
|
-
const packages = await packageList(repoPath);
|
|
34
|
-
const workspaces = await workspaceList(repoPath);
|
|
35
|
-
const status = {
|
|
36
|
-
path: repoPath,
|
|
37
|
-
objectCount: BigInt(objectCount),
|
|
38
|
-
packageCount: BigInt(packages.length),
|
|
39
|
-
workspaceCount: BigInt(workspaces.length),
|
|
40
|
-
};
|
|
41
|
-
return sendSuccess(c, RepositoryStatusType, status);
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
return sendError(c, RepositoryStatusType, errorToVariant(err));
|
|
45
|
-
}
|
|
13
|
+
const repo = c.req.param('repo');
|
|
14
|
+
const repoPath = getRepoPath(repo);
|
|
15
|
+
return getStatus(storage, repoPath);
|
|
46
16
|
});
|
|
47
|
-
// POST /api/gc -
|
|
17
|
+
// POST /api/repos/:repo/gc - Start garbage collection (async)
|
|
48
18
|
app.post('/gc', async (c) => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
return sendError(c, GcResultType, errorToVariant(err));
|
|
63
|
-
}
|
|
19
|
+
const repo = c.req.param('repo');
|
|
20
|
+
const repoPath = getRepoPath(repo);
|
|
21
|
+
const options = await decodeBody(c, GcRequestType);
|
|
22
|
+
const minAge = options.minAge?.type === 'some' ? Number(options.minAge.value) : undefined;
|
|
23
|
+
return startGc(storage, repoPath, { dryRun: options.dryRun, minAge });
|
|
24
|
+
});
|
|
25
|
+
// GET /api/repos/:repo/gc/:executionId - Get GC status
|
|
26
|
+
app.get('/gc/:executionId', (c) => {
|
|
27
|
+
const executionId = c.req.param('executionId');
|
|
28
|
+
return getGcStatus(executionId);
|
|
64
29
|
});
|
|
65
30
|
return app;
|
|
66
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/routes/repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/routes/repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,UAAU,sBAAsB,CACpC,OAAuB,EACvB,WAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,sDAAsD;IACtD,GAAG,CAAC,GAAG,CAAC,SAAS,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,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,GAAG,CAAC,IAAI,CAAC,KAAK,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,OAAO,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,EAAE;QAChC,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAE,CAAC;QAChD,OAAO,WAAW,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
5
|
import { Hono } from 'hono';
|
|
6
|
-
|
|
6
|
+
import type { StorageBackend } from '@elaraai/e3-core';
|
|
7
|
+
export declare function createTaskRoutes(storage: StorageBackend, getRepoPath: (repo: string) => string): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
7
8
|
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/routes/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/routes/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,8EA+BtC"}
|
package/dist/src/routes/tasks.js
CHANGED
|
@@ -3,55 +3,31 @@
|
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
5
|
import { Hono } from 'hono';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import { sendSuccess, sendError } from '../beast2.js';
|
|
9
|
-
import { errorToVariant } from '../errors.js';
|
|
10
|
-
import { TaskInfoType, TaskDetailsType } from '../types.js';
|
|
11
|
-
export function createTaskRoutes(repoPath) {
|
|
6
|
+
import { listTasks, getTask, listExecutions } from '../handlers/tasks.js';
|
|
7
|
+
export function createTaskRoutes(storage, getRepoPath) {
|
|
12
8
|
const app = new Hono();
|
|
13
|
-
// GET /api/workspaces/:ws/tasks - List tasks
|
|
9
|
+
// GET /api/repos/:repo/workspaces/:ws/tasks - List tasks
|
|
14
10
|
app.get('/', async (c) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
// workspaceListTasks returns string[] of task names
|
|
21
|
-
const taskNames = await workspaceListTasks(repoPath, workspace);
|
|
22
|
-
// Get hash for each task
|
|
23
|
-
const result = await Promise.all(taskNames.map(async (name) => {
|
|
24
|
-
const hash = await workspaceGetTaskHash(repoPath, workspace, name);
|
|
25
|
-
return { name, hash };
|
|
26
|
-
}));
|
|
27
|
-
return sendSuccess(c, ArrayType(TaskInfoType), result);
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
return sendError(c, ArrayType(TaskInfoType), errorToVariant(err));
|
|
31
|
-
}
|
|
11
|
+
const repo = c.req.param('repo');
|
|
12
|
+
const repoPath = getRepoPath(repo);
|
|
13
|
+
const ws = c.req.param('ws');
|
|
14
|
+
return listTasks(storage, repoPath, ws);
|
|
32
15
|
});
|
|
33
|
-
// GET /api/workspaces/:ws/tasks/:
|
|
34
|
-
app.get('/:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
inputs: task.inputs,
|
|
49
|
-
output: task.output,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
return sendError(c, TaskDetailsType, errorToVariant(err));
|
|
54
|
-
}
|
|
16
|
+
// GET /api/repos/:repo/workspaces/:ws/tasks/:task - Get task details
|
|
17
|
+
app.get('/:task', async (c) => {
|
|
18
|
+
const repo = c.req.param('repo');
|
|
19
|
+
const repoPath = getRepoPath(repo);
|
|
20
|
+
const ws = c.req.param('ws');
|
|
21
|
+
const taskName = c.req.param('task');
|
|
22
|
+
return getTask(storage, repoPath, ws, taskName);
|
|
23
|
+
});
|
|
24
|
+
// GET /api/repos/:repo/workspaces/:ws/tasks/:task/executions - List execution history
|
|
25
|
+
app.get('/:task/executions', async (c) => {
|
|
26
|
+
const repo = c.req.param('repo');
|
|
27
|
+
const repoPath = getRepoPath(repo);
|
|
28
|
+
const ws = c.req.param('ws');
|
|
29
|
+
const taskName = c.req.param('task');
|
|
30
|
+
return listExecutions(storage, repoPath, ws, taskName);
|
|
55
31
|
});
|
|
56
32
|
return app;
|
|
57
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/routes/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/routes/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,UAAU,gBAAgB,CAC9B,OAAuB,EACvB,WAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,yDAAyD;IACzD,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,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC9B,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,qEAAqE;IACrE,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,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,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QACtC,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,sFAAsF;IACtF,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,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,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;QACtC,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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 { type StorageBackend, type TransferBackend } from '@elaraai/e3-core';
|
|
7
|
+
/**
|
|
8
|
+
* Create dataset transfer routes.
|
|
9
|
+
*
|
|
10
|
+
* Returns an `api` Hono app with authenticated routes (init upload, commit)
|
|
11
|
+
* mounted at /api/repos/:repo/workspaces/:ws/datasets.
|
|
12
|
+
*
|
|
13
|
+
* Unauthenticated data routes (upload/download bytes) are handled by the
|
|
14
|
+
* generic data endpoints in `data.ts`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createTransferRoutes(storage: StorageBackend, getRepoPath: (repo: string) => string, transferBackend: TransferBackend): {
|
|
17
|
+
api: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=transfer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../../../src/routes/transfer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAM1B;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EACrC,eAAe,EAAE,eAAe;;EAyHjC"}
|