@nocobase/app-cli-distribution 0.0.0-stage → 0.1.0-beta.0
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/LICENSE.txt +129 -0
- package/README.md +79 -2
- package/dist/artifacts.d.ts +72 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +239 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/download-tokens.d.ts +57 -0
- package/dist/download-tokens.d.ts.map +1 -0
- package/dist/download-tokens.js +66 -0
- package/dist/download-tokens.js.map +1 -0
- package/dist/http.d.ts +3 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +19 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +41 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +318 -0
- package/dist/install.js.map +1 -0
- package/dist/routes.d.ts +29 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +199 -0
- package/dist/routes.js.map +1 -0
- package/dist/schemas.d.ts +17 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +25 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +50 -3
package/dist/routes.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { DIST_ACCEPT_NPM, DIST_TARGET_PATTERN, distAccepts, DistArtifactSchema, DistManifestSchema, DistNpmPackageSchema, DistResolutionSchema, HEADERS, isDistNpmPackage, ProtocolError, UNIVERSAL_TARGET, } from '@nocobase/agent-protocol';
|
|
3
|
+
import { apiErrorResponse, apiErrorResponses, apiValidator, dataResponse, cliRoute, describeRoute, resolver, } from '@nocobase/app-server/router';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { distributionRouter } from './http.js';
|
|
6
|
+
import { DistFileParams, DistTargetParams, DistTargetQuery, DownloadTokenSchema, } from './schemas.js';
|
|
7
|
+
/** `key=value` lines a POSIX shell reads without a JSON parser. Values never contain a newline. */
|
|
8
|
+
export function artifactEnv(artifact) {
|
|
9
|
+
const parsed = DistArtifactSchema.parse(artifact);
|
|
10
|
+
return [
|
|
11
|
+
`product=${parsed.product}`,
|
|
12
|
+
`version=${parsed.version}`,
|
|
13
|
+
`target=${parsed.target}`,
|
|
14
|
+
`url=${parsed.url}`,
|
|
15
|
+
`sha256=${parsed.sha256}`,
|
|
16
|
+
`size=${parsed.size}`,
|
|
17
|
+
`channel=${parsed.channel}`,
|
|
18
|
+
// Only for the universal tarball, so the answer for a tarball built for the platform stays as it was.
|
|
19
|
+
...(parsed.universal === true ? ['universal=true'] : []),
|
|
20
|
+
'',
|
|
21
|
+
].join('\n');
|
|
22
|
+
}
|
|
23
|
+
/** The same lines for an npm answer, led by `kind=npm`; only a caller that sent `accept=npm` reads them. */
|
|
24
|
+
export function npmPackageEnv(npm) {
|
|
25
|
+
const parsed = DistNpmPackageSchema.parse(npm);
|
|
26
|
+
return [
|
|
27
|
+
`kind=${parsed.kind}`,
|
|
28
|
+
`product=${parsed.product}`,
|
|
29
|
+
`version=${parsed.version}`,
|
|
30
|
+
`package=${parsed.package}`,
|
|
31
|
+
`channel=${parsed.channel}`,
|
|
32
|
+
'',
|
|
33
|
+
].join('\n');
|
|
34
|
+
}
|
|
35
|
+
/** `artifactEnv` or `npmPackageEnv`, whichever the answer is. */
|
|
36
|
+
export function resolutionEnv(resolution) {
|
|
37
|
+
return isDistNpmPackage(resolution)
|
|
38
|
+
? npmPackageEnv(resolution)
|
|
39
|
+
: artifactEnv(resolution);
|
|
40
|
+
}
|
|
41
|
+
/** A token authorizes before file lookup, then binds/counts the actual artifact's platform. */
|
|
42
|
+
export function downloadTokenAdmission(tokens, artifacts) {
|
|
43
|
+
/** What a download token is asked for on this request: the manifest, a platform, or a tarball (which counts). */
|
|
44
|
+
return async (context) => {
|
|
45
|
+
const token = context.req.header(HEADERS.downloadToken);
|
|
46
|
+
if (!token)
|
|
47
|
+
return false;
|
|
48
|
+
const { product, target, version, file } = context.req.param();
|
|
49
|
+
if (version !== undefined && file !== undefined && product !== undefined) {
|
|
50
|
+
// Checked before the file is looked up, so an invalid token learns nothing about which files there are.
|
|
51
|
+
await tokens.admit(token, { product });
|
|
52
|
+
const found = await artifacts.file(product, version, file);
|
|
53
|
+
// The universal tarball serves every platform, so it downloads under whichever one the token is bound to.
|
|
54
|
+
await tokens.admit(token, {
|
|
55
|
+
product,
|
|
56
|
+
...(found.target === UNIVERSAL_TARGET ? {} : { target: found.target }),
|
|
57
|
+
download: true,
|
|
58
|
+
});
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
await tokens.admit(token, {
|
|
62
|
+
...(product === undefined ? {} : { product }),
|
|
63
|
+
...(target === undefined ? {} : { target }),
|
|
64
|
+
});
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function createDistributionRoutes(options) {
|
|
69
|
+
const products = options.products;
|
|
70
|
+
if (products !== 'all' && !Array.isArray(products))
|
|
71
|
+
throw new Error("products must explicitly be an array or 'all'.");
|
|
72
|
+
const router = distributionRouter();
|
|
73
|
+
const artifacts = options.artifacts;
|
|
74
|
+
const allowed = async (context, next) => {
|
|
75
|
+
for (const admission of options.admissions ?? []) {
|
|
76
|
+
if (await admission(context))
|
|
77
|
+
return next();
|
|
78
|
+
}
|
|
79
|
+
if (options.fallback)
|
|
80
|
+
return options.fallback(context, next);
|
|
81
|
+
throw new ProtocolError('UNAUTHORIZED', options.unauthorizedMessage ??
|
|
82
|
+
'A download credential or sign-in is required.');
|
|
83
|
+
};
|
|
84
|
+
const productAllowed = async (context, next) => {
|
|
85
|
+
const product = context.req.param('product');
|
|
86
|
+
if (product !== undefined &&
|
|
87
|
+
products !== 'all' &&
|
|
88
|
+
!products.includes(product))
|
|
89
|
+
throw new ProtocolError('NOT_FOUND', `This application serves no ${product} on the ${artifacts.channel} channel. Build it with nocobase cli build.`);
|
|
90
|
+
return next();
|
|
91
|
+
};
|
|
92
|
+
const downloadErrors = {
|
|
93
|
+
401: apiErrorResponse(401, 'A required download credential or signed-in identity is missing or invalid.'),
|
|
94
|
+
500: apiErrorResponse(500),
|
|
95
|
+
};
|
|
96
|
+
if (options.mint !== undefined) {
|
|
97
|
+
const mint = options.mint;
|
|
98
|
+
router.post('/downloadTokens', mint.guard, describeRoute(options.openapi?.mint ?? {
|
|
99
|
+
tags: ['CliDistribution'],
|
|
100
|
+
summary: 'Create a CLI download token',
|
|
101
|
+
operationId: 'cliDistributionMint',
|
|
102
|
+
...cliRoute(false),
|
|
103
|
+
responses: {
|
|
104
|
+
201: dataResponse(DownloadTokenSchema),
|
|
105
|
+
...apiErrorResponses,
|
|
106
|
+
},
|
|
107
|
+
}), async (context) => {
|
|
108
|
+
return context.json({ data: await mint.tokens.create(mint.createdBy(context)) }, 201);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
router.get('/manifest', allowed, productAllowed, describeRoute(options.openapi?.manifest ?? {
|
|
112
|
+
tags: ['CliDistribution'],
|
|
113
|
+
summary: 'Get the distribution manifest',
|
|
114
|
+
operationId: 'cliDistributionManifest',
|
|
115
|
+
...cliRoute(false),
|
|
116
|
+
responses: { 200: dataResponse(DistManifestSchema), ...downloadErrors },
|
|
117
|
+
}), async (context) => {
|
|
118
|
+
const manifest = await artifacts.manifest();
|
|
119
|
+
return context.json({
|
|
120
|
+
data: products !== 'all'
|
|
121
|
+
? {
|
|
122
|
+
...manifest,
|
|
123
|
+
products: Object.fromEntries(Object.entries(manifest.products).filter(([product]) => products.includes(product))),
|
|
124
|
+
}
|
|
125
|
+
: manifest,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
router.get('/products/:product/targets/:target', allowed, productAllowed, describeRoute(options.openapi?.resolve ?? {
|
|
129
|
+
tags: ['CliDistribution'],
|
|
130
|
+
summary: 'Resolve a CLI artifact',
|
|
131
|
+
operationId: 'cliDistributionResolve',
|
|
132
|
+
...cliRoute(false),
|
|
133
|
+
responses: {
|
|
134
|
+
200: {
|
|
135
|
+
description: 'The resolved artifact or npm package.',
|
|
136
|
+
content: {
|
|
137
|
+
'application/json': {
|
|
138
|
+
schema: resolver(z.object({ data: DistResolutionSchema })),
|
|
139
|
+
},
|
|
140
|
+
'text/plain': { schema: { type: 'string' } },
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
404: apiErrorResponse(404),
|
|
144
|
+
...downloadErrors,
|
|
145
|
+
},
|
|
146
|
+
}), apiValidator('param', DistTargetParams), apiValidator('query', DistTargetQuery), async (context) => {
|
|
147
|
+
const { product, target } = context.req.valid('param');
|
|
148
|
+
const query = context.req.valid('query');
|
|
149
|
+
// An npm answer only to a caller that asked for it: everyone else is answered exactly as before it existed.
|
|
150
|
+
const npm = distAccepts(query.accept, DIST_ACCEPT_NPM) &&
|
|
151
|
+
DIST_TARGET_PATTERN.test(target)
|
|
152
|
+
? await artifacts.npmPackage(product)
|
|
153
|
+
: null;
|
|
154
|
+
const resolution = npm ?? (await artifacts.resolve(product, target));
|
|
155
|
+
if (query.format === 'env')
|
|
156
|
+
return context.text(resolutionEnv(resolution), 200, {
|
|
157
|
+
'cache-control': 'no-store',
|
|
158
|
+
});
|
|
159
|
+
return context.json({ data: resolution }, 200, {
|
|
160
|
+
'cache-control': 'no-store',
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
router.get('/products/:product/versions/:version/files/:file', allowed, productAllowed, describeRoute(options.openapi?.file ?? {
|
|
164
|
+
tags: ['CliDistribution'],
|
|
165
|
+
summary: 'Download a CLI artifact',
|
|
166
|
+
operationId: 'cliDistributionFile',
|
|
167
|
+
...cliRoute(false),
|
|
168
|
+
responses: {
|
|
169
|
+
200: {
|
|
170
|
+
description: 'The artifact file.',
|
|
171
|
+
content: {
|
|
172
|
+
'application/gzip': {
|
|
173
|
+
schema: { type: 'string', format: 'binary' },
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
headers: {
|
|
177
|
+
'x-checksum-sha256': {
|
|
178
|
+
schema: { type: 'string' },
|
|
179
|
+
description: 'The SHA-256 checksum.',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
404: apiErrorResponse(404),
|
|
184
|
+
...downloadErrors,
|
|
185
|
+
},
|
|
186
|
+
}), apiValidator('param', DistFileParams), async (context) => {
|
|
187
|
+
const { product, version, file: name } = context.req.valid('param');
|
|
188
|
+
const file = await artifacts.file(product, version, name);
|
|
189
|
+
const stream = Readable.toWeb(file.open());
|
|
190
|
+
return context.body(stream, 200, {
|
|
191
|
+
'content-type': 'application/gzip',
|
|
192
|
+
'content-length': String(file.size),
|
|
193
|
+
'x-checksum-sha256': file.sha256,
|
|
194
|
+
'cache-control': 'private, max-age=31536000, immutable',
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
return router;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { DownloadToken } from './download-tokens.js';
|
|
3
|
+
export declare const DistTargetParams: z.ZodType<{
|
|
4
|
+
product: string;
|
|
5
|
+
target: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const DistFileParams: z.ZodType<{
|
|
8
|
+
product: string;
|
|
9
|
+
version: string;
|
|
10
|
+
file: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const DistTargetQuery: z.ZodType<{
|
|
13
|
+
format?: 'json' | 'env' | undefined;
|
|
14
|
+
accept?: string | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const DownloadTokenSchema: z.ZodType<DownloadToken>;
|
|
17
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACrC,CAAC;AACxC,eAAO,MAAM,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd,CAIC,CAAC;AAEH,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAMC,CAAC;AAEH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CASvD,CAAC"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const id = z.string().min(1).max(200);
|
|
3
|
+
const dateTime = z.string().meta({ format: 'date-time' });
|
|
4
|
+
export const DistTargetParams = z.object({ product: id, target: id });
|
|
5
|
+
export const DistFileParams = z.object({
|
|
6
|
+
product: id,
|
|
7
|
+
version: id.describe('The version to read or restore.'),
|
|
8
|
+
file: id.describe('The file to upload.'),
|
|
9
|
+
});
|
|
10
|
+
export const DistTargetQuery = z.object({
|
|
11
|
+
format: z.enum(['json', 'env']).optional(),
|
|
12
|
+
accept: z.string().max(200).optional().meta({
|
|
13
|
+
description: 'The other answers the caller understands, comma-separated. `npm`: when the application has no tarball of the product but names its npm package, answer that package and exact version (`kind: npm`) instead of 404. Unknown values are ignored.',
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
export const DownloadTokenSchema = z.object({
|
|
17
|
+
token: z.string().meta({
|
|
18
|
+
description: 'The download token, shown only in this answer; the install script downloads the CLI with it.',
|
|
19
|
+
}),
|
|
20
|
+
expiresAt: dateTime,
|
|
21
|
+
maxDownloads: z.number().int().meta({
|
|
22
|
+
description: 'How many tarball downloads it allows, retries included.',
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACtC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAC3B,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,cAAc,GAItB,CAAC,CAAC,MAAM,CAAC;IACZ,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IACvD,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAGvB,CAAC,CAAC,MAAM,CAAC;IACZ,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC;QAC1C,WAAW,EACT,iPAAiP;KACpP,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAA6B,CAAC,CAAC,MAAM,CAAC;IACpE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;QACrB,WAAW,EACT,8FAA8F;KACjG,CAAC;IACF,SAAS,EAAE,QAAQ;IACnB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QAClC,WAAW,EAAE,yDAAyD;KACvE,CAAC;CACH,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/app-cli-distribution",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Composable server-side CLI artifact distribution and installation.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"prettier": "@nocobase/dev-config/prettier",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=24.0.0"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"hono": "^4.13.2",
|
|
28
|
+
"zod": "^4.6.6",
|
|
29
|
+
"@nocobase/agent-protocol": "^0.1.0-beta.19",
|
|
30
|
+
"@nocobase/app-cli-client": "^0.1.0-beta.21"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@nocobase/app-server": "^5.0.0-beta.5"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^24.0.0",
|
|
37
|
+
"typescript": "^6.0.3",
|
|
38
|
+
"eslint": "^10.0.0",
|
|
39
|
+
"prettier": "^3.9.6",
|
|
40
|
+
"vitest": "^4.1.10",
|
|
41
|
+
"@nocobase/dev-config": "0.1.0-beta.25"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.json",
|
|
45
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"lint": "eslint . --max-warnings 0",
|
|
48
|
+
"lint:fix": "eslint . --fix --max-warnings 0",
|
|
49
|
+
"format": "prettier . --write",
|
|
50
|
+
"format:check": "prettier . --check",
|
|
51
|
+
"fix": "pnpm lint:fix && pnpm format"
|
|
52
|
+
}
|
|
6
53
|
}
|