@cellapp/cli 0.1.0 → 0.2.1
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 +1 -1
- package/NOTICE +1 -1
- package/README.md +25 -10
- package/dist/packages/cli/src/client.js +1 -1
- package/dist/packages/cli/src/data.js +42 -0
- package/dist/packages/cli/src/data.js.map +1 -0
- package/dist/packages/cli/src/deploy.js +28 -11
- package/dist/packages/cli/src/deploy.js.map +1 -1
- package/dist/packages/cli/src/main.js +23 -13
- package/dist/packages/cli/src/main.js.map +1 -1
- package/dist/packages/cli/src/origin.js +2 -1
- package/dist/packages/cli/src/origin.js.map +1 -1
- package/dist/packages/cli/src/update.js +57 -0
- package/dist/packages/cli/src/update.js.map +1 -0
- package/dist/packages/cli/src/version.js +2 -0
- package/dist/packages/cli/src/version.js.map +1 -0
- package/dist/packages/shared/src/data.js +103 -0
- package/dist/packages/shared/src/data.js.map +1 -0
- package/package.json +26 -7
- package/skills/cellapp-deploy/SKILL.md +35 -10
- package/skills/cellapp-deploy/examples/notes/README.md +21 -0
- package/skills/cellapp-deploy/examples/notes/app.ts +115 -0
- package/skills/cellapp-deploy/examples/notes/cellapp.data.json +22 -0
- package/skills/cellapp-deploy/examples/notes/index.html +40 -0
- package/skills/cellapp-deploy/examples/notes/notes.ts +37 -0
- package/skills/cellapp-deploy/examples/notes/package-lock.json +622 -0
- package/skills/cellapp-deploy/examples/notes/package.json +16 -0
- package/skills/cellapp-deploy/examples/notes/tsconfig.json +13 -0
package/LICENSE
CHANGED
package/NOTICE
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
Cellapp CLI and Agent Skill were initially extracted from the private Cellapp
|
|
2
2
|
monorepo at commit 018274858c6435f01e1a8dc10c88b4f679b8c4c3. The public
|
|
3
3
|
repository starts with a new history to avoid publishing private material.
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Cellapp CLI and Agent Skill
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Cellapp publishes static HTML applications from a local project. The CLI builds and uploads only the chosen static output directory. The Agent Skill guides an AI agent through the same process. The default control origin is `https://console.cellapp.ai`; use `--origin` or `CELLAPP_ORIGIN` for another service.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
Requires Node.js 22.12 or later. Install the CLI from the published
|
|
7
|
+
Requires Node.js 22.12 or later. Install the CLI from the published Cellapp package when available:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
npm install -g @cellapp/cli
|
|
@@ -17,21 +17,36 @@ Install the Agent Skill separately from this public GitHub repository:
|
|
|
17
17
|
npx skills add cellapp-ai/skills
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The installable Skill lives at [`skills/cellapp-deploy/SKILL.md`](skills/cellapp-deploy/SKILL.md). Installing the Skill does not install the CLI.
|
|
20
|
+
The installable Skill lives at [`skills/cellapp-deploy/SKILL.md`](skills/cellapp-deploy/SKILL.md). Installing the Skill does not install the CLI. Contributors can use `npm ci`, `npm run build`, and `npm run cli -- --help` from this repository.
|
|
21
|
+
|
|
22
|
+
The CLI checks for a newer stable npm release on its first run each local day. If one is available, it prints an upgrade hint to stderr. To upgrade, run `npm install -g @cellapp/cli@latest`. The check sends no credentials or project data, times out after two seconds, and does not stop a command when offline. Its last-attempt date is stored in `~/.config/cellapp/update-check.json` (or under `--config-dir`).
|
|
21
23
|
|
|
22
24
|
## Deploy
|
|
23
25
|
|
|
24
26
|
```sh
|
|
25
|
-
cellapp login
|
|
26
|
-
cellapp deploy --project /absolute/project --output dist --build 'npm run build'
|
|
27
|
-
cellapp apps
|
|
27
|
+
cellapp login
|
|
28
|
+
cellapp deploy --project /absolute/project --output dist --build 'npm run build'
|
|
29
|
+
cellapp apps
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Plain HTML directories do not need `--build`. Use `--spa` only if the site has client-side routes. The first deployment returns a `{app-slug}-{user-slug}.<apps-domain>` URL and an access key once; keep the key private. Add `--namespace <user-slug> --slug <app-slug>` on first deployment to choose it. The user slug must have at least three lowercase characters, digits or hyphens; reserved platform names are unavailable, and the combined host label must fit 63 characters. The owner console can change both slugs later; old addresses remain bound to the original application. Display names may repeat. Visitors first sign in with Cellapp. Restricted applications then require owner approval or access-key redemption; public applications admit any signed-in user. Rotating a key stops new redemptions and preserves existing user grants. `cellapp.json` stores the app association and pending deployment metadata without secrets. Credentials are stored in `~/.config/cellapp/` with private file permissions.
|
|
33
|
+
|
|
34
|
+
## Application data
|
|
35
|
+
|
|
36
|
+
Cellapp hosts each application's managed PostgreSQL tables separately from platform data. A linked project can define a non-secret `cellapp.data.json` manifest with tables and `none`, `all-admitted-users`, or `own-rows` policies. Start with [the runnable notes demo](skills/cellapp-deploy/examples/notes/README.md), which includes a buildable frontend, manifest, and CRUD page:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
cellapp data status --project /absolute/project
|
|
40
|
+
cellapp data plan --project /absolute/project
|
|
41
|
+
cellapp data apply --project /absolute/project
|
|
42
|
+
cellapp data verify --project /absolute/project
|
|
28
43
|
```
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
Table changes are versioned and applied separately from static deployments. Dropping a table or column requires `allowDestructive: true` in the manifest and `--allow-destructive` after reviewing the plan. The frontend can use `@supabase/supabase-js@2.117.3` with its own origin and the non-secret `cellapp-public` identifier for table select, insert, update, delete, equality filter, order, page range, and write-return. `/_cellapp/me` returns a stable application-scoped user ID. Supabase Auth, Realtime, Storage, RPC, custom servers, and direct PostgreSQL access are not supported. The publishable identifier never authorizes access; Cellapp checks login, admission, table grants, and row policies on every data request.
|
|
31
46
|
|
|
32
47
|
An existing `ohmyapp.json` and matching `~/.config/ohmyapp/` credential are copied safely on first use. The old files remain for recovery. `OHMYAPP_ORIGIN` and the `ohmyapp` command alias are supported during the transition; use `CELLAPP_ORIGIN` and `cellapp` for new setups.
|
|
33
48
|
|
|
34
|
-
The service hosts static content only. Frontend code and bundled values are readable by authorized visitors; never include private API credentials. Browser local data is not synchronized between devices.
|
|
49
|
+
The service hosts static content only. Frontend code and bundled values are readable by authorized visitors; never include private API credentials. Browser local-only data is not synchronized between devices; managed table data is.
|
|
35
50
|
|
|
36
51
|
## Development
|
|
37
52
|
|
|
@@ -45,4 +60,4 @@ npm run check:boundary
|
|
|
45
60
|
npm pack --dry-run --json
|
|
46
61
|
```
|
|
47
62
|
|
|
48
|
-
The [public HTTP contract](contracts/http-
|
|
63
|
+
The [public HTTP v2 contract](contracts/http-v2.json) describes the CLI, application access, and data boundary. [v1](contracts/http-v1.json) remains for older static-deploy clients. The CLI and Skill are MIT licensed; see [LICENSE](LICENSE). Contributions follow [CONTRIBUTING.md](CONTRIBUTING.md), and security reports follow [SECURITY.md](SECURITY.md).
|
|
@@ -73,7 +73,7 @@ export class Client {
|
|
|
73
73
|
}
|
|
74
74
|
const migrated = await readJSON(this.credentialFile);
|
|
75
75
|
if (migrated?.token !== legacy.token)
|
|
76
|
-
throw new Error('
|
|
76
|
+
throw new Error('Cellapp credential conflicts with legacy credential; resolve the files manually');
|
|
77
77
|
this.token = migrated.token;
|
|
78
78
|
}
|
|
79
79
|
async request(path, method = 'GET', body, binary = false) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { join, resolve } from 'node:path';
|
|
2
|
+
import { readJSON } from './client.js';
|
|
3
|
+
import { parseDataManifest } from '../../shared/src/data.js';
|
|
4
|
+
function plan(value) {
|
|
5
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
6
|
+
throw new Error('Unexpected data plan response');
|
|
7
|
+
const data = value;
|
|
8
|
+
if (!Number.isSafeInteger(data.version) || typeof data.digest !== 'string' || !/^[a-f0-9]{64}$/.test(data.digest) ||
|
|
9
|
+
!Array.isArray(data.operations) || data.operations.some(item => typeof item !== 'string') ||
|
|
10
|
+
typeof data.requiresDestructive !== 'boolean' || typeof data.alreadyApplied !== 'boolean')
|
|
11
|
+
throw new Error('Unexpected data plan response');
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
export async function runData(client, action, projectPath, project, explicitAppID, manifestPath, allowDestructive = false) {
|
|
15
|
+
if (!['plan', 'apply', 'status', 'verify', 'reconcile'].includes(action ?? ''))
|
|
16
|
+
throw new Error('Use data plan, apply, status, verify, or reconcile');
|
|
17
|
+
const operation = action;
|
|
18
|
+
const appID = explicitAppID ?? project?.appId;
|
|
19
|
+
if (!appID || !/^[a-f0-9]{32}$/.test(appID))
|
|
20
|
+
throw new Error('Link a project or provide a valid app ID');
|
|
21
|
+
const path = `/apps/${appID}/data`;
|
|
22
|
+
if (operation === 'status')
|
|
23
|
+
return { appId: appID, status: await client.request(path) };
|
|
24
|
+
if (operation === 'reconcile')
|
|
25
|
+
return { appId: appID, reconciliation: await client.request(`${path}/reconcile`, 'POST', {}) };
|
|
26
|
+
if (operation === 'verify')
|
|
27
|
+
return { appId: appID, verification: await client.request(`${path}/verify`, 'POST') };
|
|
28
|
+
const input = await readJSON(resolve(projectPath, manifestPath ?? 'cellapp.data.json'));
|
|
29
|
+
if (input === undefined)
|
|
30
|
+
throw new Error(`Data manifest not found: ${join(projectPath, manifestPath ?? 'cellapp.data.json')}`);
|
|
31
|
+
const manifest = parseDataManifest(input);
|
|
32
|
+
const preview = plan(await client.request(`${path}/plan`, 'POST', manifest));
|
|
33
|
+
if (operation === 'plan')
|
|
34
|
+
return { appId: appID, plan: preview };
|
|
35
|
+
if (preview.requiresDestructive && !allowDestructive)
|
|
36
|
+
throw new Error('Destructive table changes require --allow-destructive after reviewing data plan');
|
|
37
|
+
const applied = plan(await client.request(`${path}/apply`, 'POST', manifest));
|
|
38
|
+
if (applied.digest !== preview.digest)
|
|
39
|
+
throw new Error('Applied data digest differs from the reviewed plan; run data status');
|
|
40
|
+
return { appId: appID, tables: applied, verification: await client.request(`${path}/verify`, 'POST') };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../packages/cli/src/data.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { lstat, readdir, readFile, realpath } from 'node:fs/promises';
|
|
1
|
+
import { lstat, readdir, readFile, realpath, unlink } from 'node:fs/promises';
|
|
2
2
|
import { resolve, relative, join, isAbsolute } from 'node:path';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { manifest, sha256, validPath } from '../../shared/src/artifacts.js';
|
|
5
5
|
import { AppError, ensure } from '../../shared/src/errors.js';
|
|
6
|
-
import { randomKey, requestID, saveJSON } from './client.js';
|
|
6
|
+
import { randomKey, requestID, saveJSON, readJSON } from './client.js';
|
|
7
7
|
import { readProject } from './project.js';
|
|
8
8
|
export async function build(command, project) {
|
|
9
9
|
if (!command)
|
|
@@ -44,6 +44,9 @@ export async function deploy(client, directory, options, notify) {
|
|
|
44
44
|
let project = await readProject(projectPath);
|
|
45
45
|
if (project && project.origin !== client.origin)
|
|
46
46
|
throw new Error('Project belongs to another control origin');
|
|
47
|
+
if (project?.appId && (options.namespace !== undefined || options.slug !== undefined)) {
|
|
48
|
+
throw new Error('CLI slugs are set only when creating an application; change existing slugs in the owner console');
|
|
49
|
+
}
|
|
47
50
|
const output = options.output ?? project?.output;
|
|
48
51
|
ensure(output, 400, 'output_required', 'Specify --output with the static build directory');
|
|
49
52
|
const outPath = resolve(projectPath, output);
|
|
@@ -57,21 +60,30 @@ export async function deploy(client, directory, options, notify) {
|
|
|
57
60
|
ensure(!isAbsolute(actualRelative) && actualRelative !== '..' && !actualRelative.startsWith('../'), 400, 'invalid_output', 'Output resolves outside the project');
|
|
58
61
|
const limits = await client.request('/limits');
|
|
59
62
|
const files = await collect(outPath, limits);
|
|
60
|
-
project = { ...project, origin: client.origin, name: options.name ?? project?.name ?? 'My app', output, build: command, spa: options.spa ?? project?.spa ?? false, createRequestId: project?.createRequestId ?? requestID() };
|
|
61
|
-
|
|
63
|
+
project = { ...project, origin: client.origin, name: options.name ?? project?.name ?? 'My app', namespace: options.namespace ?? project?.namespace, slug: options.slug ?? project?.slug, output, build: command, spa: options.spa ?? project?.spa ?? false, createRequestId: project?.createRequestId ?? requestID() };
|
|
64
|
+
const keyPath = `${client.credentialFile}.create-${project.createRequestId}`;
|
|
65
|
+
let initialKey = (await readJSON(keyPath))?.key;
|
|
66
|
+
if (initialKey)
|
|
67
|
+
ensure(/^[a-f0-9]{64}$/.test(initialKey), 400, 'invalid_state', 'Pending application key is invalid');
|
|
62
68
|
if (!project.appId) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const body = { name: project.name, key: initialKey, requestId: project.createRequestId
|
|
69
|
+
initialKey ??= randomKey();
|
|
70
|
+
await saveJSON(keyPath, { key: initialKey }, true);
|
|
71
|
+
await saveJSON(configPath, project);
|
|
72
|
+
const body = { name: project.name, key: initialKey, requestId: project.createRequestId,
|
|
73
|
+
...(project.namespace ? { namespace: project.namespace } : {}), ...(project.slug ? { slug: project.slug } : {}) };
|
|
67
74
|
const create = () => client.request('/apps', 'POST', body);
|
|
68
75
|
let app;
|
|
69
76
|
try {
|
|
70
77
|
app = await create();
|
|
71
78
|
}
|
|
72
79
|
catch (e) {
|
|
73
|
-
if (e instanceof AppError)
|
|
80
|
+
if (e instanceof AppError) {
|
|
81
|
+
if (e.code === 'app_data_not_ready' && typeof e.details?.appId === 'string' && /^[a-f0-9]{32}$/.test(e.details.appId)) {
|
|
82
|
+
project.appId = e.details.appId;
|
|
83
|
+
await saveJSON(configPath, project);
|
|
84
|
+
}
|
|
74
85
|
throw e;
|
|
86
|
+
}
|
|
75
87
|
app = await create();
|
|
76
88
|
}
|
|
77
89
|
project.appId = app.id;
|
|
@@ -80,6 +92,8 @@ export async function deploy(client, directory, options, notify) {
|
|
|
80
92
|
const apps = await client.request('/apps');
|
|
81
93
|
const app = apps.find(a => a.id === project.appId);
|
|
82
94
|
ensure(app, 404, 'app_not_found', 'Linked app was deleted or belongs to another owner');
|
|
95
|
+
if (app.dataState !== 'ready')
|
|
96
|
+
await client.request(`/apps/${app.id}/data/reconcile`, 'POST', {});
|
|
83
97
|
const fingerprint = sha256(JSON.stringify({ files, spa: project.spa }));
|
|
84
98
|
if (project.pending && project.pending.fingerprint !== fingerprint)
|
|
85
99
|
project.pending = undefined;
|
|
@@ -102,7 +116,10 @@ export async function deploy(client, directory, options, notify) {
|
|
|
102
116
|
const result = await client.request(`${base}/${d.id}/publish`, 'POST', {});
|
|
103
117
|
delete project.pending;
|
|
104
118
|
await saveJSON(configPath, project);
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
if (initialKey)
|
|
120
|
+
await unlink(keyPath);
|
|
121
|
+
notify('静态应用已发布。');
|
|
122
|
+
return { ...result, namespace: app.namespace, slug: app.slug, aliasUrl: app.aliasUrl,
|
|
123
|
+
...(initialKey ? { accessKey: initialKey } : { keyUnchanged: true }) };
|
|
107
124
|
}
|
|
108
125
|
//# sourceMappingURL=deploy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../../packages/cli/src/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../../packages/cli/src/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAA2B,MAAM,+BAA+B,CAAC;AACrG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAU,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQ3C,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAA2B,EAAE,OAAe;IACtE,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,EAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAC,CAAC,CAAC;QACpG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,0BAA0B,IAAI,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACvJ,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,MAAc;IAC1D,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,sCAAsC,CAAC,CAAC;IACxG,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAY,EAAE,CAAC;IAC1B,KAAK,UAAU,KAAK,CAAC,SAAiB;QACpC,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvD,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,wBAAwB,GAAG,EAAE,CAAC,CAAC;YAC9E,IAAI,IAAI,CAAC,WAAW,EAAE;gBAAE,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;iBACrC,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,qCAAqC,GAAG,EAAE,CAAC,CAAC;gBACvF,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,mBAAmB,GAAG,EAAE,CAAC,CAAC;gBACnF,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;gBACzE,KAAK,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAClB,OAAO,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,SAAiB,EAAE,OAA2G,EAAE,MAA2B;IACtM,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACrD,IAAI,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC9G,IAAI,OAAO,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;QACtF,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAC;IACrH,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,EAAE,MAAM,CAAC;IACjD,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,iBAAiB,EAAE,kDAAkD,CAAC,CAAC;IAC3F,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,mCAAmC,CAAC,CAAC;IAC9G,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EAAE,KAAK,CAAC;IAChD,MAAM,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC7D,MAAM,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,cAAc,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,qCAAqC,CAAC,CAAC;IAClK,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAS,SAAS,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,GAAG,EAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,EAAE,GAAG,IAAI,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,EAAC,CAAC;IACrT,MAAM,OAAO,GAAG,GAAG,MAAM,CAAC,cAAc,WAAW,OAAO,CAAC,eAAe,EAAE,CAAC;IAC7E,IAAI,UAAU,GAAG,CAAC,MAAM,QAAQ,CAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC;IAC/D,IAAI,UAAU;QAAE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,oCAAoC,CAAC,CAAC;IACtH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,CAAC,OAAO,EAAE,EAAC,GAAG,EAAE,UAAU,EAAC,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,eAAe;YACnF,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAC,SAAS,EAAE,OAAO,CAAC,SAAS,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC;QAC/G,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAM,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YAAC,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,oBAAoB,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,QAAQ,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtH,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;oBAChC,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACtC,CAAC;gBACD,MAAM,CAAC,CAAC;YACV,CAAC;YACD,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAQ,OAAO,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,oDAAoD,CAAC,CAAC;IACxF,IAAI,GAAG,CAAC,SAAS,KAAK,OAAO;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAClG,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAC,CAAC,CAAC,CAAC;IACtE,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAChG,OAAO,CAAC,OAAO,KAAK,EAAC,SAAS,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,CAAC,gBAAgB,EAAC,CAAC;IAC7F,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,EAAE,cAAc,CAAC;IAC3C,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,OAAO,CAAe,IAAI,EAAE,MAAM,EAAE,EAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAC,CAAC,CAAC;IAChL,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAuC,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,oCAAoC,CAAC,CAAC;YACpG,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,kBAAkB,EAAE,uDAAuD,CAAC,CAAC;YACvH,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,UAAU,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAA4C,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACtH,OAAO,OAAO,CAAC,OAAO,CAAC;IACvB,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpC,IAAI,UAAU;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnB,OAAO,EAAC,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACjF,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAC,SAAS,EAAE,UAAU,EAAC,CAAC,CAAC,CAAC,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC,EAAC,CAAC;AACtE,CAAC"}
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseArgs } from 'node:util';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
|
-
import { Client, randomKey, readJSON, saveJSON } from './client.js';
|
|
4
|
+
import { Client, randomKey, requestID, readJSON, saveJSON } from './client.js';
|
|
5
5
|
import { deploy } from './deploy.js';
|
|
6
6
|
import { AppError } from '../../shared/src/errors.js';
|
|
7
7
|
import { readProject } from './project.js';
|
|
8
8
|
import { selectOrigin } from './origin.js';
|
|
9
|
+
import { runData } from './data.js';
|
|
10
|
+
import { checkForUpdates } from './update.js';
|
|
9
11
|
const { values, positionals } = parseArgs({ allowPositionals: true, options: {
|
|
10
12
|
origin: { type: 'string' }, project: { type: 'string', default: '.' }, output: { type: 'string' },
|
|
11
|
-
build: { type: 'string' }, name: { type: 'string' }, spa: { type: 'boolean' }, help: { type: 'boolean' },
|
|
13
|
+
build: { type: 'string' }, name: { type: 'string' }, namespace: { type: 'string' }, slug: { type: 'string' }, spa: { type: 'boolean' }, help: { type: 'boolean' },
|
|
12
14
|
'config-dir': { type: 'string' },
|
|
15
|
+
manifest: { type: 'string' }, 'allow-destructive': { type: 'boolean' },
|
|
13
16
|
} });
|
|
14
|
-
const [command, appId] = positionals;
|
|
17
|
+
const [command, appId, dataAppId] = positionals;
|
|
15
18
|
const notify = (s) => process.stderr.write(s + '\n');
|
|
16
19
|
try {
|
|
20
|
+
await checkForUpdates(values['config-dir'], notify);
|
|
17
21
|
if (values.help || !command) {
|
|
18
|
-
process.stdout.write('cellapp <login|logout|deploy|apps|link|reset-key|delete> [app-id] --origin https://
|
|
22
|
+
process.stdout.write('cellapp <login|logout|deploy|apps|link|reset-key|delete|data> [app-id] [--origin https://console.cellapp.ai]\nDeploy: --project . --output dist [--build "npm run build"] [--namespace user-slug] [--slug app-slug] [--spa]\nLink: link <app-id> --project . --output dist\nData: data <plan|apply|status|verify|reconcile> [app-id] --project . [--manifest cellapp.data.json] [--allow-destructive]\nDefault origin: https://console.cellapp.ai\n');
|
|
19
23
|
}
|
|
20
24
|
else {
|
|
21
25
|
const projectPath = resolve(values.project);
|
|
22
26
|
const newProject = await readJSON(join(projectPath, 'cellapp.json'));
|
|
23
27
|
const legacyProject = await readJSON(join(projectPath, 'ohmyapp.json'));
|
|
24
28
|
const origin = selectOrigin(values.origin, newProject, legacyProject, process.env);
|
|
25
|
-
if (!origin)
|
|
26
|
-
throw new Error('Specify --origin or CELLAPP_ORIGIN');
|
|
27
29
|
const project = await readProject(projectPath);
|
|
28
30
|
const client = new Client(origin, values['config-dir']);
|
|
29
31
|
await client.load();
|
|
@@ -43,25 +45,33 @@ try {
|
|
|
43
45
|
result = await deploy(client, projectPath, values, notify);
|
|
44
46
|
else if (command === 'apps')
|
|
45
47
|
result = await client.request('/apps');
|
|
48
|
+
else if (command === 'data')
|
|
49
|
+
result = await runData(client, appId, projectPath, project, dataAppId, values.manifest, values['allow-destructive']);
|
|
46
50
|
else {
|
|
47
51
|
if (!appId || !/^[a-f0-9]{32}$/.test(appId))
|
|
48
52
|
throw new Error('A valid app ID is required');
|
|
49
53
|
if (command === 'reset-key') {
|
|
50
54
|
const key = randomKey();
|
|
51
55
|
await client.request(`/apps/${appId}/key`, 'POST', { key });
|
|
52
|
-
result = {
|
|
56
|
+
result = { accessKey: key };
|
|
53
57
|
}
|
|
54
58
|
else if (command === 'delete')
|
|
55
59
|
result = await client.request(`/apps/${appId}`, 'DELETE');
|
|
56
60
|
else if (command === 'link') {
|
|
61
|
+
if (project && project.origin !== client.origin)
|
|
62
|
+
throw new Error('Project belongs to another control origin');
|
|
57
63
|
const apps = await client.request('/apps');
|
|
58
|
-
|
|
64
|
+
const app = apps.find(a => a.id === appId);
|
|
65
|
+
if (!app)
|
|
59
66
|
throw new Error('Application not owned by this credential');
|
|
60
|
-
if (
|
|
61
|
-
throw new Error('
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
if (project?.appId && project.appId !== appId)
|
|
68
|
+
throw new Error('Project is already linked to another application');
|
|
69
|
+
const output = values.output ?? project?.output;
|
|
70
|
+
if (!output)
|
|
71
|
+
throw new Error('Specify --output to link a new project');
|
|
72
|
+
const linked = { ...project, origin: client.origin, appId, name: project?.name ?? app.name, namespace: app.namespace, slug: app.slug, output, spa: project?.spa ?? false, createRequestId: project?.createRequestId ?? requestID() };
|
|
73
|
+
delete linked.pending;
|
|
74
|
+
await saveJSON(join(projectPath, 'cellapp.json'), linked);
|
|
65
75
|
result = { linked: appId };
|
|
66
76
|
}
|
|
67
77
|
else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../packages/cli/src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../packages/cli/src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export const DEFAULT_ORIGIN = 'https://console.cellapp.ai';
|
|
1
2
|
export function selectOrigin(explicit, current, legacy, environment) {
|
|
2
|
-
return explicit ?? current?.origin ?? environment.CELLAPP_ORIGIN ?? legacy?.origin ?? environment.OHMYAPP_ORIGIN;
|
|
3
|
+
return explicit ?? current?.origin ?? (environment.CELLAPP_ORIGIN || undefined) ?? legacy?.origin ?? (environment.OHMYAPP_ORIGIN || undefined) ?? DEFAULT_ORIGIN;
|
|
3
4
|
}
|
|
4
5
|
//# sourceMappingURL=origin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"origin.js","sourceRoot":"","sources":["../../../../packages/cli/src/origin.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,OAA4B,EAAE,MAA2B,EAAE,WAA8B;IAClJ,OAAO,QAAQ,IAAI,OAAO,EAAE,MAAM,IAAI,WAAW,CAAC,cAAc,IAAI,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"origin.js","sourceRoot":"","sources":["../../../../packages/cli/src/origin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAE3D,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,OAA4B,EAAE,MAA2B,EAAE,WAA8B;IAClJ,OAAO,QAAQ,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,IAAI,SAAS,CAAC,IAAI,MAAM,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,IAAI,SAAS,CAAC,IAAI,cAAc,CAAC;AACnK,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readJSON, saveJSON } from './client.js';
|
|
4
|
+
import { CLI_VERSION } from './version.js';
|
|
5
|
+
const REGISTRY_URL = 'https://registry.npmjs.org/@cellapp%2Fcli/latest';
|
|
6
|
+
function localDate(now) {
|
|
7
|
+
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
|
8
|
+
}
|
|
9
|
+
function stableVersion(value) {
|
|
10
|
+
if (typeof value !== 'string' || !/^\d+\.\d+\.\d+$/.test(value))
|
|
11
|
+
return undefined;
|
|
12
|
+
const parts = value.split('.').map(Number);
|
|
13
|
+
return parts.every(Number.isSafeInteger) ? parts : undefined;
|
|
14
|
+
}
|
|
15
|
+
export function isNewerVersion(latest, current) {
|
|
16
|
+
const next = stableVersion(latest);
|
|
17
|
+
const installed = stableVersion(current);
|
|
18
|
+
if (!next || !installed)
|
|
19
|
+
return false;
|
|
20
|
+
for (let i = 0; i < 3; i++) {
|
|
21
|
+
if (next[i] > installed[i])
|
|
22
|
+
return true;
|
|
23
|
+
if (next[i] < installed[i])
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
export async function checkForUpdates(configDirectory, notify, now = new Date(), fetcher = fetch) {
|
|
29
|
+
const statePath = join(configDirectory ?? join(homedir(), '.config', 'cellapp'), 'update-check.json');
|
|
30
|
+
const date = localDate(now);
|
|
31
|
+
try {
|
|
32
|
+
let state;
|
|
33
|
+
try {
|
|
34
|
+
state = await readJSON(statePath);
|
|
35
|
+
}
|
|
36
|
+
catch { /* Replace invalid local state. */ }
|
|
37
|
+
if (state && typeof state === 'object' && 'date' in state && state.date === date)
|
|
38
|
+
return;
|
|
39
|
+
// Record the attempt first so an offline machine does not retry on every command.
|
|
40
|
+
await saveJSON(statePath, { date }, true);
|
|
41
|
+
const response = await fetcher(REGISTRY_URL, {
|
|
42
|
+
headers: { Accept: 'application/json' },
|
|
43
|
+
redirect: 'error',
|
|
44
|
+
signal: AbortSignal.timeout(2_000),
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok)
|
|
47
|
+
return;
|
|
48
|
+
const metadata = await response.json();
|
|
49
|
+
if (!metadata || typeof metadata !== 'object' || !('version' in metadata))
|
|
50
|
+
return;
|
|
51
|
+
if (isNewerVersion(metadata.version, CLI_VERSION)) {
|
|
52
|
+
notify(`发现新版 @cellapp/cli ${metadata.version}(当前 ${CLI_VERSION})。运行 npm install -g @cellapp/cli@latest 更新。`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch { /* Update checks never change the requested command's result. */ }
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../packages/cli/src/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../../packages/cli/src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const identifier = /^[a-z][a-z0-9_]{0,62}$/;
|
|
3
|
+
const columnTypes = new Set(['text', 'uuid', 'bigint', 'boolean', 'timestamptz', 'jsonb']);
|
|
4
|
+
const modes = new Set(['none', 'all-admitted-users', 'own-rows']);
|
|
5
|
+
const systemColumns = new Set(['ctid', 'tableoid', 'xmin', 'cmin', 'xmax', 'cmax']);
|
|
6
|
+
function object(value, keys) {
|
|
7
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
8
|
+
throw new Error('Expected an object in data manifest');
|
|
9
|
+
const result = value;
|
|
10
|
+
if (Object.keys(result).some(key => !keys.includes(key)))
|
|
11
|
+
throw new Error('Unsupported field in data manifest');
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
function name(value) {
|
|
15
|
+
if (typeof value !== 'string' || !identifier.test(value))
|
|
16
|
+
throw new Error('Invalid data identifier');
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
function names(value, max) {
|
|
20
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > max)
|
|
21
|
+
throw new Error('Invalid data column list');
|
|
22
|
+
const result = value.map(name);
|
|
23
|
+
if (new Set(result).size !== result.length)
|
|
24
|
+
throw new Error('Duplicate data column');
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
function mode(value) {
|
|
28
|
+
if (value === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
if (typeof value !== 'string' || !modes.has(value))
|
|
31
|
+
throw new Error('Invalid data policy');
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
export function parseDataManifest(input) {
|
|
35
|
+
const root = object(input, ['version', 'allowDestructive', 'tables']);
|
|
36
|
+
if (!Number.isSafeInteger(root.version) || root.version < 1 || root.version > 1_000_000)
|
|
37
|
+
throw new Error('Invalid data manifest version');
|
|
38
|
+
if (root.allowDestructive !== undefined && typeof root.allowDestructive !== 'boolean')
|
|
39
|
+
throw new Error('Invalid destructive-change flag');
|
|
40
|
+
if (!Array.isArray(root.tables) || root.tables.length > 20)
|
|
41
|
+
throw new Error('Invalid data table list');
|
|
42
|
+
const tables = root.tables.map(value => {
|
|
43
|
+
const table = object(value, ['name', 'columns', 'primaryKey', 'indexes', 'policies']);
|
|
44
|
+
const tableName = name(table.name);
|
|
45
|
+
if (tableName === 'rpc')
|
|
46
|
+
throw new Error('Reserved data table name: rpc');
|
|
47
|
+
if (!Array.isArray(table.columns) || table.columns.length < 1 || table.columns.length > 30)
|
|
48
|
+
throw new Error('Invalid data columns');
|
|
49
|
+
const columns = table.columns.map(value => {
|
|
50
|
+
const column = object(value, ['name', 'type', 'nullable']);
|
|
51
|
+
if (typeof column.type !== 'string' || !columnTypes.has(column.type) || (column.nullable !== undefined && typeof column.nullable !== 'boolean'))
|
|
52
|
+
throw new Error('Unsupported data column');
|
|
53
|
+
const columnName = name(column.name);
|
|
54
|
+
if (systemColumns.has(columnName))
|
|
55
|
+
throw new Error(`Reserved PostgreSQL system column: ${columnName}`);
|
|
56
|
+
return { name: columnName, type: column.type, ...(column.nullable === undefined ? {} : { nullable: column.nullable }) };
|
|
57
|
+
});
|
|
58
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
59
|
+
if (columnNames.size !== columns.length)
|
|
60
|
+
throw new Error('Duplicate data column');
|
|
61
|
+
const primaryKey = names(table.primaryKey, 3);
|
|
62
|
+
if (primaryKey.some(key => !columnNames.has(key) || columns.find(column => column.name === key)?.nullable))
|
|
63
|
+
throw new Error('Invalid primary key');
|
|
64
|
+
if (table.indexes !== undefined && (!Array.isArray(table.indexes) || table.indexes.length > 10))
|
|
65
|
+
throw new Error('Invalid data indexes');
|
|
66
|
+
const indexes = table.indexes?.map(value => {
|
|
67
|
+
const index = object(value, ['columns', 'unique']);
|
|
68
|
+
const indexColumns = names(index.columns, 3);
|
|
69
|
+
if (indexColumns.some(column => !columnNames.has(column)) || (index.unique !== undefined && typeof index.unique !== 'boolean'))
|
|
70
|
+
throw new Error('Invalid data index');
|
|
71
|
+
return { columns: indexColumns, ...(index.unique === undefined ? {} : { unique: index.unique }) };
|
|
72
|
+
});
|
|
73
|
+
const policies = object(table.policies, ['select', 'insert', 'update', 'delete', 'ownerColumn']);
|
|
74
|
+
const parsedPolicies = { select: mode(policies.select), insert: mode(policies.insert), update: mode(policies.update), delete: mode(policies.delete) };
|
|
75
|
+
const ownRows = Object.values(parsedPolicies).includes('own-rows');
|
|
76
|
+
if (ownRows) {
|
|
77
|
+
if (typeof policies.ownerColumn !== 'string')
|
|
78
|
+
throw new Error('own-rows requires an owner column');
|
|
79
|
+
const ownerColumn = name(policies.ownerColumn);
|
|
80
|
+
const column = columns.find(column => column.name === ownerColumn);
|
|
81
|
+
if (!column || column.type !== 'text' || column.nullable)
|
|
82
|
+
throw new Error('own-rows requires a non-null text owner column');
|
|
83
|
+
parsedPolicies.ownerColumn = ownerColumn;
|
|
84
|
+
}
|
|
85
|
+
else if (policies.ownerColumn !== undefined)
|
|
86
|
+
throw new Error('ownerColumn requires own-rows');
|
|
87
|
+
return { name: tableName, columns, primaryKey, ...(indexes === undefined ? {} : { indexes }), policies: parsedPolicies };
|
|
88
|
+
});
|
|
89
|
+
if (new Set(tables.map(table => table.name)).size !== tables.length)
|
|
90
|
+
throw new Error('Duplicate data table');
|
|
91
|
+
const relations = new Set(tables.map(table => table.name));
|
|
92
|
+
for (const table of tables) {
|
|
93
|
+
for (const position of table.indexes?.keys() ?? []) {
|
|
94
|
+
const digest = createHash('sha256').update(`${table.name}:${position}`).digest('hex').slice(0, 8);
|
|
95
|
+
const indexName = `i_${table.name.slice(0, 40)}_${digest}`;
|
|
96
|
+
if (relations.has(indexName))
|
|
97
|
+
throw new Error(`Generated index name conflicts with table or index: ${indexName}`);
|
|
98
|
+
relations.add(indexName);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { version: root.version, ...(root.allowDestructive === undefined ? {} : { allowDestructive: root.allowDestructive }), tables };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../packages/shared/src/data.ts"],"names":[],"mappings":"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"}
|