@polardbx/pxbaas 0.0.0-stage → 0.1.0-beta.10
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 +223 -2
- package/bin/pxbaas.js +13 -0
- package/dist/app/local-index.d.ts +70 -0
- package/dist/app/local-index.d.ts.map +1 -0
- package/dist/app/local-index.js +140 -0
- package/dist/app/local-index.js.map +1 -0
- package/dist/app/preflight.d.ts +61 -0
- package/dist/app/preflight.d.ts.map +1 -0
- package/dist/app/preflight.js +115 -0
- package/dist/app/preflight.js.map +1 -0
- package/dist/app/spec-lint.d.ts +45 -0
- package/dist/app/spec-lint.d.ts.map +1 -0
- package/dist/app/spec-lint.js +423 -0
- package/dist/app/spec-lint.js.map +1 -0
- package/dist/app/templates.d.ts +167 -0
- package/dist/app/templates.d.ts.map +1 -0
- package/dist/app/templates.js +151 -0
- package/dist/app/templates.js.map +1 -0
- package/dist/cli/help-guides.d.ts +17 -0
- package/dist/cli/help-guides.d.ts.map +1 -0
- package/dist/cli/help-guides.js +132 -0
- package/dist/cli/help-guides.js.map +1 -0
- package/dist/cli/root.d.ts +3 -0
- package/dist/cli/root.d.ts.map +1 -0
- package/dist/cli/root.js +75 -0
- package/dist/cli/root.js.map +1 -0
- package/dist/commands/app/index.d.ts +8 -0
- package/dist/commands/app/index.d.ts.map +1 -0
- package/dist/commands/app/index.js +1907 -0
- package/dist/commands/app/index.js.map +1 -0
- package/dist/commands/auth/index.d.ts +3 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +198 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/completion/index.d.ts +3 -0
- package/dist/commands/completion/index.d.ts.map +1 -0
- package/dist/commands/completion/index.js +14 -0
- package/dist/commands/completion/index.js.map +1 -0
- package/dist/commands/data/index.d.ts +55 -0
- package/dist/commands/data/index.d.ts.map +1 -0
- package/dist/commands/data/index.js +407 -0
- package/dist/commands/data/index.js.map +1 -0
- package/dist/commands/db/index.d.ts +29 -0
- package/dist/commands/db/index.d.ts.map +1 -0
- package/dist/commands/db/index.js +500 -0
- package/dist/commands/db/index.js.map +1 -0
- package/dist/commands/doctor/index.d.ts +3 -0
- package/dist/commands/doctor/index.d.ts.map +1 -0
- package/dist/commands/doctor/index.js +305 -0
- package/dist/commands/doctor/index.js.map +1 -0
- package/dist/commands/functions/delete.d.ts +3 -0
- package/dist/commands/functions/delete.d.ts.map +1 -0
- package/dist/commands/functions/delete.js +55 -0
- package/dist/commands/functions/delete.js.map +1 -0
- package/dist/commands/functions/deploy.d.ts +3 -0
- package/dist/commands/functions/deploy.d.ts.map +1 -0
- package/dist/commands/functions/deploy.js +118 -0
- package/dist/commands/functions/deploy.js.map +1 -0
- package/dist/commands/functions/index.d.ts +3 -0
- package/dist/commands/functions/index.d.ts.map +1 -0
- package/dist/commands/functions/index.js +15 -0
- package/dist/commands/functions/index.js.map +1 -0
- package/dist/commands/functions/list.d.ts +6 -0
- package/dist/commands/functions/list.d.ts.map +1 -0
- package/dist/commands/functions/list.js +63 -0
- package/dist/commands/functions/list.js.map +1 -0
- package/dist/commands/functions/new.d.ts +7 -0
- package/dist/commands/functions/new.d.ts.map +1 -0
- package/dist/commands/functions/new.js +72 -0
- package/dist/commands/functions/new.js.map +1 -0
- package/dist/commands/gen/index.d.ts +3 -0
- package/dist/commands/gen/index.d.ts.map +1 -0
- package/dist/commands/gen/index.js +323 -0
- package/dist/commands/gen/index.js.map +1 -0
- package/dist/commands/guide/index.d.ts +8 -0
- package/dist/commands/guide/index.d.ts.map +1 -0
- package/dist/commands/guide/index.js +20 -0
- package/dist/commands/guide/index.js.map +1 -0
- package/dist/commands/instance/index.d.ts +8 -0
- package/dist/commands/instance/index.d.ts.map +1 -0
- package/dist/commands/instance/index.js +481 -0
- package/dist/commands/instance/index.js.map +1 -0
- package/dist/commands/login/index.d.ts +3 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +145 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/logout/index.d.ts +3 -0
- package/dist/commands/logout/index.d.ts.map +1 -0
- package/dist/commands/logout/index.js +41 -0
- package/dist/commands/logout/index.js.map +1 -0
- package/dist/commands/profile/import-env.d.ts +18 -0
- package/dist/commands/profile/import-env.d.ts.map +1 -0
- package/dist/commands/profile/import-env.js +206 -0
- package/dist/commands/profile/import-env.js.map +1 -0
- package/dist/commands/profile/index.d.ts +3 -0
- package/dist/commands/profile/index.d.ts.map +1 -0
- package/dist/commands/profile/index.js +124 -0
- package/dist/commands/profile/index.js.map +1 -0
- package/dist/commands/rest/index.d.ts +3 -0
- package/dist/commands/rest/index.d.ts.map +1 -0
- package/dist/commands/rest/index.js +102 -0
- package/dist/commands/rest/index.js.map +1 -0
- package/dist/commands/skill/index.d.ts +11 -0
- package/dist/commands/skill/index.d.ts.map +1 -0
- package/dist/commands/skill/index.js +228 -0
- package/dist/commands/skill/index.js.map +1 -0
- package/dist/commands/status/index.d.ts +3 -0
- package/dist/commands/status/index.d.ts.map +1 -0
- package/dist/commands/status/index.js +59 -0
- package/dist/commands/status/index.js.map +1 -0
- package/dist/commands/storage/index.d.ts +3 -0
- package/dist/commands/storage/index.d.ts.map +1 -0
- package/dist/commands/storage/index.js +400 -0
- package/dist/commands/storage/index.js.map +1 -0
- package/dist/commands/tenant/index.d.ts +19 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +667 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/commands/whoami/index.d.ts +3 -0
- package/dist/commands/whoami/index.d.ts.map +1 -0
- package/dist/commands/whoami/index.js +101 -0
- package/dist/commands/whoami/index.js.map +1 -0
- package/dist/credentials/commit.d.ts +38 -0
- package/dist/credentials/commit.d.ts.map +1 -0
- package/dist/credentials/commit.js +57 -0
- package/dist/credentials/commit.js.map +1 -0
- package/dist/credentials/credential-store.d.ts +86 -0
- package/dist/credentials/credential-store.d.ts.map +1 -0
- package/dist/credentials/credential-store.js +282 -0
- package/dist/credentials/credential-store.js.map +1 -0
- package/dist/credentials/env-file.d.ts +85 -0
- package/dist/credentials/env-file.d.ts.map +1 -0
- package/dist/credentials/env-file.js +193 -0
- package/dist/credentials/env-file.js.map +1 -0
- package/dist/credentials/formatter.d.ts +39 -0
- package/dist/credentials/formatter.d.ts.map +1 -0
- package/dist/credentials/formatter.js +79 -0
- package/dist/credentials/formatter.js.map +1 -0
- package/dist/credentials/index.d.ts +13 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +13 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/credentials/jwt-introspect.d.ts +39 -0
- package/dist/credentials/jwt-introspect.d.ts.map +1 -0
- package/dist/credentials/jwt-introspect.js +64 -0
- package/dist/credentials/jwt-introspect.js.map +1 -0
- package/dist/credentials/masker.d.ts +23 -0
- package/dist/credentials/masker.d.ts.map +1 -0
- package/dist/credentials/masker.js +40 -0
- package/dist/credentials/masker.js.map +1 -0
- package/dist/credentials/profile.d.ts +95 -0
- package/dist/credentials/profile.d.ts.map +1 -0
- package/dist/credentials/profile.js +207 -0
- package/dist/credentials/profile.js.map +1 -0
- package/dist/credentials/tenant-guard.d.ts +16 -0
- package/dist/credentials/tenant-guard.d.ts.map +1 -0
- package/dist/credentials/tenant-guard.js +53 -0
- package/dist/credentials/tenant-guard.js.map +1 -0
- package/dist/credentials/tty-guard.d.ts +29 -0
- package/dist/credentials/tty-guard.d.ts.map +1 -0
- package/dist/credentials/tty-guard.js +79 -0
- package/dist/credentials/tty-guard.js.map +1 -0
- package/dist/db/apply-schema.d.ts +144 -0
- package/dist/db/apply-schema.d.ts.map +1 -0
- package/dist/db/apply-schema.js +359 -0
- package/dist/db/apply-schema.js.map +1 -0
- package/dist/db/introspect.d.ts +54 -0
- package/dist/db/introspect.d.ts.map +1 -0
- package/dist/db/introspect.js +140 -0
- package/dist/db/introspect.js.map +1 -0
- package/dist/db/sql-file.d.ts +104 -0
- package/dist/db/sql-file.d.ts.map +1 -0
- package/dist/db/sql-file.js +584 -0
- package/dist/db/sql-file.js.map +1 -0
- package/dist/instance/provision.d.ts +89 -0
- package/dist/instance/provision.d.ts.map +1 -0
- package/dist/instance/provision.js +139 -0
- package/dist/instance/provision.js.map +1 -0
- package/dist/instance/zero-store.d.ts +47 -0
- package/dist/instance/zero-store.d.ts.map +1 -0
- package/dist/instance/zero-store.js +91 -0
- package/dist/instance/zero-store.js.map +1 -0
- package/dist/instance/zero-whitelist.d.ts +39 -0
- package/dist/instance/zero-whitelist.d.ts.map +1 -0
- package/dist/instance/zero-whitelist.js +67 -0
- package/dist/instance/zero-whitelist.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +69 -0
- package/dist/main.js.map +1 -0
- package/dist/skill/agents-md.d.ts +25 -0
- package/dist/skill/agents-md.d.ts.map +1 -0
- package/dist/skill/agents-md.js +62 -0
- package/dist/skill/agents-md.js.map +1 -0
- package/dist/skill/assets.d.ts +38 -0
- package/dist/skill/assets.d.ts.map +1 -0
- package/dist/skill/assets.js +111 -0
- package/dist/skill/assets.js.map +1 -0
- package/dist/skill/hint.d.ts +39 -0
- package/dist/skill/hint.d.ts.map +1 -0
- package/dist/skill/hint.js +109 -0
- package/dist/skill/hint.js.map +1 -0
- package/dist/skill/hosts.d.ts +45 -0
- package/dist/skill/hosts.d.ts.map +1 -0
- package/dist/skill/hosts.js +96 -0
- package/dist/skill/hosts.js.map +1 -0
- package/dist/skill/installer.d.ts +100 -0
- package/dist/skill/installer.d.ts.map +1 -0
- package/dist/skill/installer.js +241 -0
- package/dist/skill/installer.js.map +1 -0
- package/dist/skill/ownership.d.ts +35 -0
- package/dist/skill/ownership.d.ts.map +1 -0
- package/dist/skill/ownership.js +52 -0
- package/dist/skill/ownership.js.map +1 -0
- package/dist/tenant/bundle.d.ts +66 -0
- package/dist/tenant/bundle.d.ts.map +1 -0
- package/dist/tenant/bundle.js +132 -0
- package/dist/tenant/bundle.js.map +1 -0
- package/dist/tenant/guide.d.ts +50 -0
- package/dist/tenant/guide.d.ts.map +1 -0
- package/dist/tenant/guide.js +152 -0
- package/dist/tenant/guide.js.map +1 -0
- package/dist/tenant/probe.d.ts +65 -0
- package/dist/tenant/probe.d.ts.map +1 -0
- package/dist/tenant/probe.js +159 -0
- package/dist/tenant/probe.js.map +1 -0
- package/dist/tenant/verify.d.ts +37 -0
- package/dist/tenant/verify.d.ts.map +1 -0
- package/dist/tenant/verify.js +132 -0
- package/dist/tenant/verify.js.map +1 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +65 -0
- package/dist/version.js.map +1 -0
- package/package.json +63 -3
- package/skills/pxbaas-app-spec/SKILL.md +165 -0
- package/skills/pxbaas-app-spec/references/deploy-options.md +158 -0
- package/skills/pxbaas-app-spec/references/guardrails-pitfalls.md +89 -0
- package/skills/pxbaas-app-spec/references/runtime-contract.md +151 -0
- package/skills/pxbaas-app-spec/references/ssr-session.md +121 -0
- package/skills/pxbaas-app-spec/references/templates-examples.md +311 -0
- package/skills/pxbaas-cli/SKILL.md +186 -0
- package/skills/pxbaas-cli/references/api-reference.md +68 -0
- package/skills/pxbaas-cli/references/app-deploy.md +186 -0
- package/skills/pxbaas-cli/references/auth-and-credentials.md +116 -0
- package/skills/pxbaas-cli/references/data-postgrest.md +101 -0
- package/skills/pxbaas-cli/references/db-and-meta.md +102 -0
- package/skills/pxbaas-cli/references/edge-functions.md +71 -0
- package/skills/pxbaas-cli/references/multi-tenant-apps.md +138 -0
- package/skills/pxbaas-cli/references/provision.md +101 -0
- package/skills/pxbaas-cli/references/safety-and-two-phase.md +78 -0
- package/skills/pxbaas-cli/references/storage.md +61 -0
- package/skills/pxbaas-cli/references/tenant-admin.md +122 -0
- package/skills/pxbaas-cli/references/troubleshooting.md +76 -0
- package/templates/webapp/api/index.ts +55 -0
- package/templates/webapp/csr-bff/README.md +81 -0
- package/templates/webapp/csr-bff/backend/index.ts +168 -0
- package/templates/webapp/csr-bff/db/rls.json +13 -0
- package/templates/webapp/csr-bff/db/schema.sql +49 -0
- package/templates/webapp/csr-bff/frontend/dist/admin.html +101 -0
- package/templates/webapp/csr-bff/frontend/dist/article.html +44 -0
- package/templates/webapp/csr-bff/frontend/dist/blog.js +206 -0
- package/templates/webapp/csr-bff/frontend/dist/blogger.html +53 -0
- package/templates/webapp/csr-bff/frontend/dist/index.html +70 -0
- package/templates/webapp/csr-bff/frontend/dist/login.html +56 -0
- package/templates/webapp/csr-bff/frontend/dist/profile.html +59 -0
- package/templates/webapp/csr-bff/frontend/dist/signup.html +78 -0
- package/templates/webapp/csr-bff/frontend/dist/style.css +27 -0
- package/templates/webapp/manifest.json +419 -0
- package/templates/webapp/mpa/about.html +29 -0
- package/templates/webapp/mpa/app.js +42 -0
- package/templates/webapp/mpa/index.html +42 -0
- package/templates/webapp/mpa/index.ts +60 -0
- package/templates/webapp/mpa/style.css +42 -0
- package/templates/webapp/react-vite/frontend/index.html +12 -0
- package/templates/webapp/react-vite/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite/frontend/package.json +23 -0
- package/templates/webapp/react-vite/frontend/src/App.tsx +34 -0
- package/templates/webapp/react-vite/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite/frontend/src/style.css +46 -0
- package/templates/webapp/react-vite/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite/frontend/vite.config.ts +10 -0
- package/templates/webapp/react-vite-hono/backend/index.ts +38 -0
- package/templates/webapp/react-vite-hono/frontend/index.html +12 -0
- package/templates/webapp/react-vite-hono/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite-hono/frontend/package.json +23 -0
- package/templates/webapp/react-vite-hono/frontend/src/App.tsx +47 -0
- package/templates/webapp/react-vite-hono/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite-hono/frontend/src/style.css +66 -0
- package/templates/webapp/react-vite-hono/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite-hono/frontend/vite.config.ts +10 -0
- package/templates/webapp/spa/index.ts +119 -0
- package/templates/webapp/ssr-auth/backend/index.ts +133 -0
- package/templates/webapp/ssr-auth/frontend/dist/index.html +15 -0
- package/templates/webapp/ssr-blog/README.md +111 -0
- package/templates/webapp/ssr-blog/backend/index.ts +764 -0
- package/templates/webapp/ssr-blog/db/rls.json +13 -0
- package/templates/webapp/ssr-blog/db/schema.sql +51 -0
- package/templates/webapp/ssr-blog/frontend/dist/index.html +39 -0
- package/templates/webapp/ssr-frameworks/README.md +64 -0
- package/templates/webapp/ssr-frameworks/backend/index.ts +241 -0
- package/templates/webapp/ssr-frameworks/frontend/dist/index.html +31 -0
- package/templates/webapp/ssr-hono/backend/index.ts +111 -0
- package/templates/webapp/ssr-hono/frontend/dist/index.html +12 -0
- package/templates/webapp/ssr-shop/README.md +80 -0
- package/templates/webapp/ssr-shop/backend/index.ts +491 -0
- package/templates/webapp/ssr-shop/db/rls.json +16 -0
- package/templates/webapp/ssr-shop/db/schema.sql +90 -0
- package/templates/webapp/ssr-shop/frontend/dist/index.html +12 -0
- package/templates/webapp/vanilla-static/frontend/dist/app.js +6 -0
- package/templates/webapp/vanilla-static/frontend/dist/index.html +19 -0
- package/templates/webapp/vanilla-static/frontend/dist/style.css +43 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { ZeroDriver, ZeroError } from '@polardbx/pxbaas-client';
|
|
2
|
+
import { ProfileManager } from '../../credentials/profile.js';
|
|
3
|
+
import { CredentialStore } from '../../credentials/credential-store.js';
|
|
4
|
+
import { computeFingerprint, formatError, formatSuccess, formatWarning } from '../../credentials/index.js';
|
|
5
|
+
import { ZeroStore } from '../../instance/zero-store.js';
|
|
6
|
+
import { provisionInstance, releaseInstance, } from '../../instance/provision.js';
|
|
7
|
+
import { resolveWhitelistTarget } from '../../instance/zero-whitelist.js';
|
|
8
|
+
/**
|
|
9
|
+
* `pxbaas provision` / `pxbaas instance` — claim and manage disposable BaaS instances
|
|
10
|
+
* from PolarDB-X Zero. Fully automatic and offline-credential-free: keys come from
|
|
11
|
+
* Zero over TLS, are stored in the keyring, and only fingerprints are shown.
|
|
12
|
+
*/
|
|
13
|
+
export function registerInstanceCommands(program) {
|
|
14
|
+
// Top-level: pxbaas provision
|
|
15
|
+
program
|
|
16
|
+
.command('provision')
|
|
17
|
+
.description('Claim a disposable BaaS instance from PolarDB-X Zero and bind it to a profile')
|
|
18
|
+
.option('--name <profile>', 'Profile name to create (default: zero-<id suffix>)')
|
|
19
|
+
.option('--whitelist-ip <ip,cidr>', 'Extra IP whitelist for the instance (default: your egress IP)')
|
|
20
|
+
.option('--no-switch', 'Create the profile but do not switch the current profile to it')
|
|
21
|
+
.option('--reuse', 'Reuse an existing active Zero instance instead of claiming a new one')
|
|
22
|
+
.option('--force', 'Overwrite an existing profile of the same name')
|
|
23
|
+
.option('--json', 'Output in JSON format')
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
try {
|
|
26
|
+
await handleProvision(options, program);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
reportError(error, options.json);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const instanceCmd = program
|
|
33
|
+
.command('instance')
|
|
34
|
+
.description('Manage Zero-provisioned BaaS instances (list/release/credentials/current)');
|
|
35
|
+
// pxbaas instance claim — alias of provision
|
|
36
|
+
instanceCmd
|
|
37
|
+
.command('claim')
|
|
38
|
+
.description('Alias of `pxbaas provision`')
|
|
39
|
+
.option('--name <profile>', 'Profile name to create')
|
|
40
|
+
.option('--whitelist-ip <ip,cidr>', 'Extra IP whitelist')
|
|
41
|
+
.option('--no-switch', 'Do not switch current profile')
|
|
42
|
+
.option('--reuse', 'Reuse an existing active instance')
|
|
43
|
+
.option('--force', 'Overwrite an existing profile of the same name')
|
|
44
|
+
.option('--json', 'Output in JSON format')
|
|
45
|
+
.action(async (options) => {
|
|
46
|
+
try {
|
|
47
|
+
await handleProvision(options, program);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
reportError(error, options.json);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
instanceCmd
|
|
54
|
+
.command('list')
|
|
55
|
+
.description('List Zero instances bound on this machine (and reconcile with Zero when a token exists)')
|
|
56
|
+
.option('--json', 'Output in JSON format')
|
|
57
|
+
.action(async (options) => {
|
|
58
|
+
try {
|
|
59
|
+
await handleList(options, program);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
reportError(error, options.json);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
instanceCmd
|
|
66
|
+
.command('release <id>')
|
|
67
|
+
.description('Release a Zero instance (destructive; two-phase, needs --confirm)')
|
|
68
|
+
.option('--keep-profile', 'Release remotely but keep the local profile/credentials')
|
|
69
|
+
.option('--confirm', 'Actually perform the release (required)')
|
|
70
|
+
.option('--json', 'Output in JSON format')
|
|
71
|
+
.action(async (id, options) => {
|
|
72
|
+
try {
|
|
73
|
+
await handleRelease(id, options, program);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
reportError(error, options.json);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
instanceCmd
|
|
80
|
+
.command('credentials <id>')
|
|
81
|
+
.description('Show a Zero instance endpoint/dashboard/fingerprints (--reveal for dashboard password)')
|
|
82
|
+
.option('--reveal', 'Also print the Dashboard password (handle with care)')
|
|
83
|
+
.option('--json', 'Output in JSON format')
|
|
84
|
+
.action(async (id, options) => {
|
|
85
|
+
try {
|
|
86
|
+
await handleCredentials(id, options, program);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
reportError(error, options.json);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
instanceCmd
|
|
93
|
+
.command('current')
|
|
94
|
+
.description('Show the Zero instance bound to the current profile (if any)')
|
|
95
|
+
.option('--json', 'Output in JSON format')
|
|
96
|
+
.action(async (options) => {
|
|
97
|
+
try {
|
|
98
|
+
await handleCurrent(options, program);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
reportError(error, options.json);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// pxbaas instance whitelist get|add — Zero instances only (Studio-credential hash auth)
|
|
105
|
+
const whitelistCmd = instanceCmd
|
|
106
|
+
.command('whitelist')
|
|
107
|
+
.description('Manage the IP whitelist of a Zero-provisioned instance (Zero instances only)');
|
|
108
|
+
whitelistCmd
|
|
109
|
+
.command('get')
|
|
110
|
+
.description('Show the effective IP whitelist (Zero instances only)')
|
|
111
|
+
.option('--id <zeroId>', 'Target Zero instance id (sbx_*); defaults to the current Zero profile')
|
|
112
|
+
.option('--json', 'Output in JSON format')
|
|
113
|
+
.action(async (options) => {
|
|
114
|
+
try {
|
|
115
|
+
await handleWhitelistGet(options, program);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
reportError(error, options.json);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
whitelistCmd
|
|
122
|
+
.command('add <ips>')
|
|
123
|
+
.description('Append IPv4/CIDR to the whitelist (append-only and idempotent; Zero instances only)')
|
|
124
|
+
.option('--id <zeroId>', 'Target Zero instance id (sbx_*); defaults to the current Zero profile')
|
|
125
|
+
.option('--dry-run', 'Show what would be appended without calling Zero')
|
|
126
|
+
.option('--json', 'Output in JSON format')
|
|
127
|
+
.action(async (ips, options) => {
|
|
128
|
+
try {
|
|
129
|
+
await handleWhitelistAdd(ips, options, program);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
reportError(error, options.json);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function makeDeps() {
|
|
137
|
+
return {
|
|
138
|
+
zero: new ZeroDriver(),
|
|
139
|
+
profiles: new ProfileManager(),
|
|
140
|
+
creds: new CredentialStore(),
|
|
141
|
+
store: new ZeroStore(),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function isJson(options, program) {
|
|
145
|
+
return Boolean(options.json || program.opts().json);
|
|
146
|
+
}
|
|
147
|
+
function reportError(error, json) {
|
|
148
|
+
if (error instanceof ZeroError) {
|
|
149
|
+
const hint = zeroErrorHint(error.code);
|
|
150
|
+
if (json) {
|
|
151
|
+
console.log(JSON.stringify({ status: 'error', code: error.code, error: error.message, hint }, null, 2));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.error(formatError(`[${error.code}] ${error.message}`));
|
|
155
|
+
if (hint)
|
|
156
|
+
console.error(formatWarning(hint));
|
|
157
|
+
}
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
161
|
+
if (json)
|
|
162
|
+
console.log(JSON.stringify({ status: 'error', error: message }, null, 2));
|
|
163
|
+
else
|
|
164
|
+
console.error(formatError(message));
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
/** Stop-and-inform guidance for Zero capacity/rate errors (never loop-retry). */
|
|
168
|
+
function zeroErrorHint(code) {
|
|
169
|
+
switch (code) {
|
|
170
|
+
case 'SUPABASE_LIMIT_REACHED':
|
|
171
|
+
return 'You already hold the max concurrent instances. Run `pxbaas instance list`, then `pxbaas instance release <id> --confirm` to free a slot.';
|
|
172
|
+
case 'RATE_LIMIT_EXCEEDED':
|
|
173
|
+
return 'Rate limited by IP. Wait a bit before retrying; do not loop.';
|
|
174
|
+
case 'SUPABASE_POOL_EXHAUSTED':
|
|
175
|
+
return 'No instance in the pool right now. It refills automatically — retry once after 1-2 minutes.';
|
|
176
|
+
case 'SUPABASE_DISABLED':
|
|
177
|
+
return 'The Zero Supabase service is currently disabled. Report to the user; do not retry.';
|
|
178
|
+
case 'INVALID_WHITELIST_IP':
|
|
179
|
+
return 'whitelistIp must be a comma-separated list of IPv4/CIDR.';
|
|
180
|
+
case 'INSTANCE_NOT_FOUND':
|
|
181
|
+
return 'Instance not found, not owned by this token, or already released.';
|
|
182
|
+
case 'IP_MISMATCH':
|
|
183
|
+
return 'The whitelist API only accepts requests from the claiming IP or an already-whitelisted IP. Run on the claiming machine, or have an allowed IP append yours first.';
|
|
184
|
+
case 'STUDIO_CREDENTIALS_INVALID':
|
|
185
|
+
return 'Studio credential hash did not match the instance (wrong/corrupt local dashboard password). Re-provision from this machine.';
|
|
186
|
+
case 'ASSIGNMENT_EXPIRED':
|
|
187
|
+
return 'The instance passed its 15-day validity and was released. Run `pxbaas provision` to claim a new one.';
|
|
188
|
+
case 'INSTANCE_NOT_ACCESSIBLE':
|
|
189
|
+
return 'Instance not found, not claimed, or already released.';
|
|
190
|
+
case 'INSTANCE_BUSY':
|
|
191
|
+
return 'A cloud change task is in progress for this instance. Retry shortly.';
|
|
192
|
+
case 'CONCURRENT_UPDATE':
|
|
193
|
+
return 'Concurrent update; the cloud change already applied. Re-run `instance whitelist get` to reconcile, then retry.';
|
|
194
|
+
case 'CREDENTIALS_UNAVAILABLE':
|
|
195
|
+
return 'Instance credential record is abnormal. Re-provision, or contact the platform admin.';
|
|
196
|
+
case 'WHITELIST_MODIFY_FAILED':
|
|
197
|
+
return 'Cloud whitelist modification failed. Report with the cloudRequestId from the response.';
|
|
198
|
+
case 'INVALID_PARAMETER':
|
|
199
|
+
return 'Check the instanceId (pxsp-*), the X-Studio headers, and that ips is a comma-separated IPv4/CIDR list.';
|
|
200
|
+
default:
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function handleProvision(options, program) {
|
|
205
|
+
const json = isJson(options, program);
|
|
206
|
+
const deps = makeDeps();
|
|
207
|
+
const result = await provisionInstance(deps, {
|
|
208
|
+
name: options.name,
|
|
209
|
+
whitelistIp: options.whitelistIp,
|
|
210
|
+
switchProfile: options.switch, // commander sets switch=false with --no-switch
|
|
211
|
+
reuse: options.reuse,
|
|
212
|
+
force: options.force,
|
|
213
|
+
});
|
|
214
|
+
if (json) {
|
|
215
|
+
console.log(JSON.stringify(toProvisionJson(result), null, 2));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
console.log(formatSuccess(`${result.reused ? 'Reused' : 'Provisioned'} Zero instance ${result.instance.id}`));
|
|
219
|
+
console.log(` Profile: ${result.profileName}`);
|
|
220
|
+
if (result.switchedFrom && result.switchedFrom !== result.profileName) {
|
|
221
|
+
console.log(` Switched: ${result.switchedFrom} -> ${result.profileName} (switch back: pxbaas profile use ${result.switchedFrom})`);
|
|
222
|
+
}
|
|
223
|
+
console.log(` Endpoint: ${result.instance.endpoint}`);
|
|
224
|
+
if (result.instance.dashboardUrl)
|
|
225
|
+
console.log(` Dashboard: ${result.instance.dashboardUrl} (user: supabase)`);
|
|
226
|
+
console.log(` Keys: anon ${result.keys.anon.fingerprint} · service_role ${result.keys.serviceRole.fingerprint}`);
|
|
227
|
+
if (result.instance.expiresAt)
|
|
228
|
+
console.log(` Expires: ${result.instance.expiresAt} (15-day, no renewal)`);
|
|
229
|
+
if (result.instance.whitelistIp)
|
|
230
|
+
console.log(` Whitelist: ${result.instance.whitelistIp} (other IPs are rejected)`);
|
|
231
|
+
console.log('');
|
|
232
|
+
console.log(' Next: pxbaas status --json · pxbaas db tables --json · pxbaas skill install --host <host>');
|
|
233
|
+
console.log(' Dashboard password: pxbaas instance credentials ' + result.instance.id + ' --reveal');
|
|
234
|
+
}
|
|
235
|
+
function toProvisionJson(result) {
|
|
236
|
+
return {
|
|
237
|
+
status: result.reused ? 'reused' : 'provisioned',
|
|
238
|
+
profile: result.profileName,
|
|
239
|
+
switchedFrom: result.switchedFrom,
|
|
240
|
+
instance: result.instance,
|
|
241
|
+
keys: result.keys,
|
|
242
|
+
dashboard: result.dashboard,
|
|
243
|
+
nextSteps: [
|
|
244
|
+
'pxbaas status --json',
|
|
245
|
+
'pxbaas db tables --json',
|
|
246
|
+
'pxbaas skill install --host <qoder|claude|...>',
|
|
247
|
+
`pxbaas instance credentials ${result.instance.id} --reveal`,
|
|
248
|
+
],
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
async function handleList(options, program) {
|
|
252
|
+
const json = isJson(options, program);
|
|
253
|
+
const store = new ZeroStore();
|
|
254
|
+
const local = await store.listInstances();
|
|
255
|
+
const token = await store.getToken();
|
|
256
|
+
// Reconcile with Zero when we have a token (best-effort; never fail the command).
|
|
257
|
+
let remoteIds = null;
|
|
258
|
+
let remoteError;
|
|
259
|
+
if (token) {
|
|
260
|
+
try {
|
|
261
|
+
const remote = await new ZeroDriver().list(token);
|
|
262
|
+
remoteIds = remote.map((i) => i.id);
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
remoteError = e instanceof Error ? e.message : String(e);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const rows = local.map((rec) => ({
|
|
269
|
+
id: rec.id,
|
|
270
|
+
profile: rec.profileName,
|
|
271
|
+
endpoint: rec.endpoint,
|
|
272
|
+
expiresAt: rec.expiresAt ?? null,
|
|
273
|
+
expired: rec.expiresAt ? new Date(rec.expiresAt).getTime() <= Date.now() : false,
|
|
274
|
+
remotePresent: remoteIds ? remoteIds.includes(rec.id) : null,
|
|
275
|
+
}));
|
|
276
|
+
if (json) {
|
|
277
|
+
console.log(JSON.stringify({ instances: rows, reconciled: Boolean(remoteIds), remoteError }, null, 2));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (rows.length === 0) {
|
|
281
|
+
console.log(formatWarning('No Zero instances bound on this machine. Run `pxbaas provision` to claim one.'));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
for (const r of rows) {
|
|
285
|
+
const flags = [r.expired ? 'EXPIRED' : '', r.remotePresent === false ? 'released-remotely' : '']
|
|
286
|
+
.filter(Boolean)
|
|
287
|
+
.join(',');
|
|
288
|
+
console.log(`${r.id} profile=${r.profile} expires=${r.expiresAt ?? '?'}${flags ? ` [${flags}]` : ''}`);
|
|
289
|
+
}
|
|
290
|
+
if (remoteError)
|
|
291
|
+
console.log(formatWarning(`(could not reconcile with Zero: ${remoteError})`));
|
|
292
|
+
}
|
|
293
|
+
async function handleRelease(id, options, program) {
|
|
294
|
+
const json = isJson(options, program);
|
|
295
|
+
const deps = makeDeps();
|
|
296
|
+
const rec = await deps.store.getInstance(id);
|
|
297
|
+
if (!options.confirm) {
|
|
298
|
+
const preview = {
|
|
299
|
+
status: 'dry-run',
|
|
300
|
+
id,
|
|
301
|
+
profile: rec?.profileName ?? null,
|
|
302
|
+
willRemoveProfile: !options.keepProfile && Boolean(rec),
|
|
303
|
+
note: 'pass --confirm to release (destroys cloud resources; irreversible)',
|
|
304
|
+
};
|
|
305
|
+
if (json)
|
|
306
|
+
console.log(JSON.stringify(preview, null, 2));
|
|
307
|
+
else {
|
|
308
|
+
console.log(formatWarning(`Preview: release instance ${id}${rec ? ` and remove profile '${rec.profileName}'` : ''}.`));
|
|
309
|
+
console.log(' Re-run with --confirm to proceed (irreversible).');
|
|
310
|
+
}
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const result = await releaseInstance(deps, id, { removeProfile: !options.keepProfile });
|
|
314
|
+
if (json) {
|
|
315
|
+
console.log(JSON.stringify({ status: 'released', ...result }, null, 2));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
console.log(formatSuccess(`Released Zero instance ${id}`));
|
|
319
|
+
if (result.profileRemoved)
|
|
320
|
+
console.log(` Removed profile: ${result.profileRemoved}`);
|
|
321
|
+
if (result.wasCurrent)
|
|
322
|
+
console.log(formatWarning(' This was the current profile; no profile is active now. Use `pxbaas profile use <name>` or `pxbaas provision`.'));
|
|
323
|
+
}
|
|
324
|
+
async function handleCredentials(id, options, program) {
|
|
325
|
+
const json = isJson(options, program);
|
|
326
|
+
const store = new ZeroStore();
|
|
327
|
+
const rec = await store.getInstance(id);
|
|
328
|
+
if (!rec)
|
|
329
|
+
throw new Error(`No Zero instance '${id}' bound on this machine.`);
|
|
330
|
+
const creds = await new CredentialStore().getCredentials(rec.profileName);
|
|
331
|
+
const out = {
|
|
332
|
+
id: rec.id,
|
|
333
|
+
profile: rec.profileName,
|
|
334
|
+
endpoint: rec.endpoint,
|
|
335
|
+
dashboardUrl: rec.dashboardUrl ?? null,
|
|
336
|
+
dashboardUser: 'supabase',
|
|
337
|
+
expiresAt: rec.expiresAt ?? null,
|
|
338
|
+
whitelistIp: rec.whitelistIp ?? null,
|
|
339
|
+
keys: creds
|
|
340
|
+
? {
|
|
341
|
+
anon: { fingerprint: computeFingerprint(creds.anonKey), role: 'anon' },
|
|
342
|
+
serviceRole: { fingerprint: computeFingerprint(creds.serviceRoleKey), role: 'service_role' },
|
|
343
|
+
}
|
|
344
|
+
: null,
|
|
345
|
+
};
|
|
346
|
+
if (options.reveal) {
|
|
347
|
+
out.dashboardPassword = rec.dashboardPassword ?? null;
|
|
348
|
+
}
|
|
349
|
+
if (json) {
|
|
350
|
+
console.log(JSON.stringify(out, null, 2));
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
console.log(`Instance: ${rec.id}`);
|
|
354
|
+
console.log(`Profile: ${rec.profileName}`);
|
|
355
|
+
console.log(`Endpoint: ${rec.endpoint}`);
|
|
356
|
+
console.log(`Dashboard: ${rec.dashboardUrl ?? '-'} (user: supabase)`);
|
|
357
|
+
if (creds)
|
|
358
|
+
console.log(`Keys: anon ${computeFingerprint(creds.anonKey)} · service_role ${computeFingerprint(creds.serviceRoleKey)}`);
|
|
359
|
+
console.log(`Expires: ${rec.expiresAt ?? '-'}`);
|
|
360
|
+
if (options.reveal) {
|
|
361
|
+
console.log(formatWarning(`Dashboard password: ${rec.dashboardPassword ?? '-'} (do not paste into shared logs)`));
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
console.log(' (dashboard password hidden; re-run with --reveal)');
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
async function handleCurrent(options, program) {
|
|
368
|
+
const json = isJson(options, program);
|
|
369
|
+
const profiles = new ProfileManager();
|
|
370
|
+
const current = await profiles.getCurrentProfile();
|
|
371
|
+
if (!current) {
|
|
372
|
+
if (json)
|
|
373
|
+
console.log(JSON.stringify({ status: 'no-profile' }, null, 2));
|
|
374
|
+
else
|
|
375
|
+
console.log(formatWarning('No active profile. Run `pxbaas provision` (Zero) or `pxbaas login` (your own instance).'));
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (current.source !== 'zero') {
|
|
379
|
+
if (json)
|
|
380
|
+
console.log(JSON.stringify({ profile: current.name, source: current.source ?? 'login', zeroInstance: null }, null, 2));
|
|
381
|
+
else
|
|
382
|
+
console.log(`Current profile '${current.name}' is your own instance (not a Zero instance).`);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const rec = await new ZeroStore().getInstance(current.zeroInstanceId ?? '');
|
|
386
|
+
if (json) {
|
|
387
|
+
// Never emit secrets (token / dashboardPassword / dbPassword) — redacted view only.
|
|
388
|
+
console.log(JSON.stringify({ profile: current.name, source: 'zero', zeroInstance: publicInstanceView(rec) }, null, 2));
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
console.log(`Current profile '${current.name}' -> Zero instance ${current.zeroInstanceId}`);
|
|
392
|
+
if (rec)
|
|
393
|
+
console.log(` Endpoint: ${rec.endpoint} Expires: ${rec.expiresAt ?? '-'}`);
|
|
394
|
+
}
|
|
395
|
+
/** Redact a stored Zero instance record for safe output (drops token & passwords). */
|
|
396
|
+
function publicInstanceView(rec) {
|
|
397
|
+
if (!rec)
|
|
398
|
+
return null;
|
|
399
|
+
return {
|
|
400
|
+
id: rec.id,
|
|
401
|
+
endpoint: rec.endpoint,
|
|
402
|
+
dashboardUrl: rec.dashboardUrl ?? null,
|
|
403
|
+
profileName: rec.profileName,
|
|
404
|
+
expiresAt: rec.expiresAt ?? null,
|
|
405
|
+
whitelistIp: rec.whitelistIp ?? null,
|
|
406
|
+
claimedAt: rec.claimedAt,
|
|
407
|
+
dashboardUser: 'supabase',
|
|
408
|
+
secretsRedacted: true,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
function splitList(value) {
|
|
412
|
+
return (value ?? '')
|
|
413
|
+
.split(',')
|
|
414
|
+
.map((s) => s.trim())
|
|
415
|
+
.filter(Boolean);
|
|
416
|
+
}
|
|
417
|
+
async function handleWhitelistGet(options, program) {
|
|
418
|
+
const json = isJson(options, program);
|
|
419
|
+
const target = await resolveWhitelistTarget({ id: options.id });
|
|
420
|
+
const wl = await new ZeroDriver().getWhitelist(target.cloudInstanceId, target.studioHash);
|
|
421
|
+
const entries = splitList(wl.whitelist);
|
|
422
|
+
if (json) {
|
|
423
|
+
console.log(JSON.stringify({
|
|
424
|
+
status: 'ok',
|
|
425
|
+
instanceId: wl.instanceId,
|
|
426
|
+
groupName: wl.groupName,
|
|
427
|
+
whitelist: entries,
|
|
428
|
+
whitelistRaw: wl.whitelist,
|
|
429
|
+
source: wl.source,
|
|
430
|
+
expiresAt: wl.expiresAt ?? null,
|
|
431
|
+
updatedAt: wl.updatedAt ?? null,
|
|
432
|
+
}, null, 2));
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
console.log(formatSuccess(`Whitelist for ${wl.instanceId} (group ${wl.groupName}, source ${wl.source}):`));
|
|
436
|
+
if (entries.length === 0)
|
|
437
|
+
console.log(' (empty — only the system 127.0.0.1 baseline applies)');
|
|
438
|
+
for (const ip of entries)
|
|
439
|
+
console.log(` - ${ip}`);
|
|
440
|
+
if (wl.expiresAt)
|
|
441
|
+
console.log(` Expires: ${wl.expiresAt}`);
|
|
442
|
+
}
|
|
443
|
+
async function handleWhitelistAdd(ips, options, program) {
|
|
444
|
+
const json = isJson(options, program);
|
|
445
|
+
const target = await resolveWhitelistTarget({ id: options.id });
|
|
446
|
+
const requested = splitList(ips);
|
|
447
|
+
if (requested.length === 0) {
|
|
448
|
+
throw new Error('No IPs to add: pass a comma-separated list of IPv4/CIDR, e.g. 9.9.9.9,10.0.0.0/24.');
|
|
449
|
+
}
|
|
450
|
+
if (options.dryRun) {
|
|
451
|
+
const out = {
|
|
452
|
+
status: 'dry-run',
|
|
453
|
+
instanceId: target.cloudInstanceId,
|
|
454
|
+
ips: requested,
|
|
455
|
+
note: 'append-only; re-run without --dry-run to apply (existing entries are kept)',
|
|
456
|
+
};
|
|
457
|
+
if (json)
|
|
458
|
+
console.log(JSON.stringify(out, null, 2));
|
|
459
|
+
else
|
|
460
|
+
console.log(formatWarning(`Dry-run: would append [${requested.join(', ')}] to ${target.cloudInstanceId} (append-only).`));
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const res = await new ZeroDriver().appendWhitelist(target.cloudInstanceId, ips, target.studioHash);
|
|
464
|
+
if (json) {
|
|
465
|
+
console.log(JSON.stringify({
|
|
466
|
+
status: 'ok',
|
|
467
|
+
instanceId: res.instanceId,
|
|
468
|
+
groupName: res.groupName,
|
|
469
|
+
appliedIps: splitList(res.appliedIps),
|
|
470
|
+
effectiveWhitelist: splitList(res.effectiveWhitelist),
|
|
471
|
+
effectiveWhitelistRaw: res.effectiveWhitelist,
|
|
472
|
+
cloudRequestId: res.cloudRequestId ?? null,
|
|
473
|
+
}, null, 2));
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
console.log(formatSuccess(`Appended [${splitList(res.appliedIps).join(', ')}] to ${res.instanceId}.`));
|
|
477
|
+
console.log(` Effective whitelist: ${res.effectiveWhitelist}`);
|
|
478
|
+
if (res.cloudRequestId)
|
|
479
|
+
console.log(` cloudRequestId: ${res.cloudRequestId}`);
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/instance/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB3D"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import { assertTty, assertNoKeyArgs, commitProfileCredentials, formatSuccess, formatError, readStdinLines, ProfileManager, } from '../../credentials/index.js';
|
|
3
|
+
export function registerLoginCommand(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('login')
|
|
6
|
+
.description('Authenticate with PolarDB-X BaaS (interactive prompts by default; pipe keys with --anon-key-stdin/--service-key-stdin for non-interactive use)')
|
|
7
|
+
.option('--endpoint <url>', 'BaaS endpoint URL')
|
|
8
|
+
.option('--tenant-id <id>', 'Tenant ID (for multi-tenant mode)')
|
|
9
|
+
.option('--anon-key-stdin', 'Read anon key from stdin')
|
|
10
|
+
.option('--service-key-stdin', 'Read service role key from stdin')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
try {
|
|
13
|
+
await handleLogin(options, program);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
17
|
+
console.error(formatError(message));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async function handleLogin(options, program) {
|
|
23
|
+
// 检查 argv 中是否有密钥参数(安全守卫)
|
|
24
|
+
assertNoKeyArgs(process.argv);
|
|
25
|
+
const isStdinMode = options.anonKeyStdin || options.serviceKeyStdin;
|
|
26
|
+
// 如果不是 stdin 模式,必须是 TTY
|
|
27
|
+
if (!isStdinMode) {
|
|
28
|
+
assertTty();
|
|
29
|
+
}
|
|
30
|
+
let endpoint;
|
|
31
|
+
let tenantId;
|
|
32
|
+
let anonKey;
|
|
33
|
+
let serviceRoleKey;
|
|
34
|
+
if (isStdinMode) {
|
|
35
|
+
// stdin 模式:从命令行参数或 stdin 获取
|
|
36
|
+
endpoint = options.endpoint || '';
|
|
37
|
+
tenantId = options.tenantId;
|
|
38
|
+
if (!endpoint) {
|
|
39
|
+
throw new Error('--endpoint is required when using --anon-key-stdin or --service-key-stdin');
|
|
40
|
+
}
|
|
41
|
+
if (options.anonKeyStdin && options.serviceKeyStdin) {
|
|
42
|
+
// 两个都从 stdin 读取(每行一个)
|
|
43
|
+
const [anonLine, serviceLine] = await readStdinLines(2, 'anon key on first line, service role key on second line');
|
|
44
|
+
anonKey = anonLine;
|
|
45
|
+
serviceRoleKey = serviceLine;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// 只指定了一个 --*-key-stdin:用法错误。直接报错,绝不先阻塞读 stdin
|
|
49
|
+
// (否则在 TTY 下会卡住等输入,而不是立刻提示用法)。
|
|
50
|
+
throw new Error('Both --anon-key-stdin and --service-key-stdin must be specified together');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// TTY 交互模式:使用 inquirer 提示
|
|
55
|
+
const answers = await inquirer.prompt([
|
|
56
|
+
{
|
|
57
|
+
type: 'input',
|
|
58
|
+
name: 'endpoint',
|
|
59
|
+
message: 'BaaS endpoint URL:',
|
|
60
|
+
default: options.endpoint || 'http://localhost:8000',
|
|
61
|
+
validate: (input) => {
|
|
62
|
+
if (!input.trim())
|
|
63
|
+
return 'Endpoint is required';
|
|
64
|
+
if (!input.startsWith('http://') && !input.startsWith('https://')) {
|
|
65
|
+
return 'Endpoint must start with http:// or https://';
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'input',
|
|
72
|
+
name: 'tenantId',
|
|
73
|
+
message: 'Tenant ID (leave empty for single-tenant mode):',
|
|
74
|
+
default: options.tenantId || '',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'password',
|
|
78
|
+
name: 'anonKey',
|
|
79
|
+
message: 'Anon Key:',
|
|
80
|
+
mask: '*',
|
|
81
|
+
validate: (input) => {
|
|
82
|
+
if (!input.trim())
|
|
83
|
+
return 'Anon key is required';
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
type: 'password',
|
|
89
|
+
name: 'serviceRoleKey',
|
|
90
|
+
message: 'Service Role Key:',
|
|
91
|
+
mask: '*',
|
|
92
|
+
validate: (input) => {
|
|
93
|
+
if (!input.trim())
|
|
94
|
+
return 'Service role key is required';
|
|
95
|
+
return true;
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
]);
|
|
99
|
+
endpoint = answers.endpoint;
|
|
100
|
+
tenantId = answers.tenantId || undefined;
|
|
101
|
+
anonKey = answers.anonKey;
|
|
102
|
+
serviceRoleKey = answers.serviceRoleKey;
|
|
103
|
+
}
|
|
104
|
+
// 解析、校验并落库 profile + 凭据(与 profile import 共用同一套逻辑)
|
|
105
|
+
// profile 名优先级与 main.ts 的 preAction 钩子一致:尾置 --profile > 前置 --profile > 'default'
|
|
106
|
+
// (只读 program.opts() 会让 `login --profile x` 静默写进 default,即跨实例误写)
|
|
107
|
+
const profileName = options.profile || program.opts().profile || 'default';
|
|
108
|
+
const overwrote = (await new ProfileManager().getProfile(profileName)) !== null;
|
|
109
|
+
const result = await commitProfileCredentials({
|
|
110
|
+
profileName,
|
|
111
|
+
endpoint,
|
|
112
|
+
tenantId,
|
|
113
|
+
anonKey,
|
|
114
|
+
serviceRoleKey,
|
|
115
|
+
});
|
|
116
|
+
const mode = result.mode;
|
|
117
|
+
const profileOutcome = overwrote
|
|
118
|
+
? `overwrote existing profile '${profileName}'`
|
|
119
|
+
: `created new profile '${profileName}'`;
|
|
120
|
+
// 输出成功消息(只出指纹,绝不回显明文 key)
|
|
121
|
+
if (options.json || program.opts().json) {
|
|
122
|
+
const output = {
|
|
123
|
+
status: 'success',
|
|
124
|
+
message: `Login successful for profile: ${profileName}`,
|
|
125
|
+
profile: profileName,
|
|
126
|
+
profileStatus: overwrote ? 'overwritten' : 'created',
|
|
127
|
+
endpoint,
|
|
128
|
+
tenantId: tenantId || '(single-tenant)',
|
|
129
|
+
mode,
|
|
130
|
+
anonKeyFingerprint: result.anonKeyFingerprint,
|
|
131
|
+
serviceKeyFingerprint: result.serviceKeyFingerprint,
|
|
132
|
+
};
|
|
133
|
+
console.log(JSON.stringify(output, null, 2));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
console.log(formatSuccess(`Login successful for profile: ${profileName}`));
|
|
137
|
+
console.log(` Profile: ${profileOutcome}`);
|
|
138
|
+
console.log(` Endpoint: ${endpoint}`);
|
|
139
|
+
console.log(` Tenant ID: ${tenantId || '(single-tenant)'}`);
|
|
140
|
+
console.log(` Mode: ${mode}`);
|
|
141
|
+
console.log(` Anon Key: ${result.anonKeyFingerprint}`);
|
|
142
|
+
console.log(` Service Key: ${result.serviceKeyFingerprint}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=index.js.map
|