@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,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provisioning core logic — claim a Zero PXBaas instance and bind it to a baas
|
|
3
|
+
* profile. Kept separate from the commander wiring and driven by narrow
|
|
4
|
+
* interfaces so it is unit-testable with fakes (no keytar / no network).
|
|
5
|
+
*
|
|
6
|
+
* Security model: Zero returns plaintext keys over TLS; this module ingests them
|
|
7
|
+
* into the credential sink (keyring) and NEVER returns plaintext — only
|
|
8
|
+
* fingerprints. Agents can run this without a human TTY login.
|
|
9
|
+
*/
|
|
10
|
+
import type { BaasProfile } from '../credentials/profile.js';
|
|
11
|
+
import type { StoredCredentials } from '../credentials/credential-store.js';
|
|
12
|
+
import { type ZeroClaimResponse, type ZeroInstance } from '@polardbx/pxbaas-client';
|
|
13
|
+
import type { ZeroStore } from './zero-store.js';
|
|
14
|
+
/** Narrow deps so tests can inject fakes. */
|
|
15
|
+
export interface ZeroApi {
|
|
16
|
+
claim(whitelistIp?: string): Promise<ZeroClaimResponse>;
|
|
17
|
+
list(token: string): Promise<ZeroInstance[]>;
|
|
18
|
+
release(id: string, token: string): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface ProfileSink {
|
|
21
|
+
setProfile(p: BaasProfile): Promise<void>;
|
|
22
|
+
useProfile(name: string): Promise<void>;
|
|
23
|
+
getCurrentProfile(): Promise<BaasProfile | null>;
|
|
24
|
+
getProfile(name: string): Promise<BaasProfile | null>;
|
|
25
|
+
removeProfile(name: string): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
export interface CredSink {
|
|
28
|
+
setCredentials(name: string, c: StoredCredentials): Promise<void>;
|
|
29
|
+
getCredentials(name: string): Promise<StoredCredentials | null>;
|
|
30
|
+
deleteCredentials(name: string): Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
export interface ProvisionDeps {
|
|
33
|
+
zero: ZeroApi;
|
|
34
|
+
profiles: ProfileSink;
|
|
35
|
+
creds: CredSink;
|
|
36
|
+
store: ZeroStore;
|
|
37
|
+
}
|
|
38
|
+
export interface ProvisionOptions {
|
|
39
|
+
name?: string;
|
|
40
|
+
whitelistIp?: string;
|
|
41
|
+
/** Switch current profile to the new instance (default true). */
|
|
42
|
+
switchProfile?: boolean;
|
|
43
|
+
/** Overwrite an existing profile of the same name. */
|
|
44
|
+
force?: boolean;
|
|
45
|
+
/** Reuse an existing active Zero instance instead of claiming a new one. */
|
|
46
|
+
reuse?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface ProvisionResult {
|
|
49
|
+
reused: boolean;
|
|
50
|
+
profileName: string;
|
|
51
|
+
switchedFrom: string | null;
|
|
52
|
+
instance: {
|
|
53
|
+
id: string;
|
|
54
|
+
endpoint: string;
|
|
55
|
+
appEndpoint?: string;
|
|
56
|
+
dashboardUrl?: string;
|
|
57
|
+
region?: string;
|
|
58
|
+
whitelistIp?: string;
|
|
59
|
+
expiresAt?: string;
|
|
60
|
+
mode: 'single-tenant';
|
|
61
|
+
};
|
|
62
|
+
keys: {
|
|
63
|
+
anon: {
|
|
64
|
+
fingerprint: string;
|
|
65
|
+
role: 'anon';
|
|
66
|
+
};
|
|
67
|
+
serviceRole: {
|
|
68
|
+
fingerprint: string;
|
|
69
|
+
role: 'service_role';
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
dashboard: {
|
|
73
|
+
username: 'supabase';
|
|
74
|
+
passwordRevealed: boolean;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Claim (or reuse) a Zero instance and bind it to a profile + credentials. */
|
|
78
|
+
export declare function provisionInstance(deps: ProvisionDeps, options?: ProvisionOptions): Promise<ProvisionResult>;
|
|
79
|
+
export interface ReleaseResult {
|
|
80
|
+
id: string;
|
|
81
|
+
released: boolean;
|
|
82
|
+
profileRemoved: string | null;
|
|
83
|
+
wasCurrent: boolean;
|
|
84
|
+
}
|
|
85
|
+
/** Release a Zero instance and unbind/remove its local profile. */
|
|
86
|
+
export declare function releaseInstance(deps: ProvisionDeps, id: string, opts?: {
|
|
87
|
+
removeProfile?: boolean;
|
|
88
|
+
}): Promise<ReleaseResult>;
|
|
89
|
+
//# sourceMappingURL=provision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../../src/instance/provision.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAc,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,KAAK,EAAE,SAAS,EAAsB,MAAM,iBAAiB,CAAC;AAErE,6CAA6C;AAC7C,MAAM,WAAW,OAAO;IACtB,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AACD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,iBAAiB,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACtD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/C;AACD,MAAM,WAAW,QAAQ;IACvB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAChE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,eAAe,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,WAAW,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,cAAc,CAAA;SAAE,CAAC;KAC5D,CAAC;IACF,SAAS,EAAE;QAAE,QAAQ,EAAE,UAAU,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;CAChE;AAQD,+EAA+E;AAC/E,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA2G1B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,mEAAmE;AACnE,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,OAAO,CAAC,aAAa,CAAC,CAqBxB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provisioning core logic — claim a Zero PXBaas instance and bind it to a baas
|
|
3
|
+
* profile. Kept separate from the commander wiring and driven by narrow
|
|
4
|
+
* interfaces so it is unit-testable with fakes (no keytar / no network).
|
|
5
|
+
*
|
|
6
|
+
* Security model: Zero returns plaintext keys over TLS; this module ingests them
|
|
7
|
+
* into the credential sink (keyring) and NEVER returns plaintext — only
|
|
8
|
+
* fingerprints. Agents can run this without a human TTY login.
|
|
9
|
+
*/
|
|
10
|
+
import { computeFingerprint } from '../credentials/masker.js';
|
|
11
|
+
import { ZeroDriver } from '@polardbx/pxbaas-client';
|
|
12
|
+
function profileNameFor(id, explicit) {
|
|
13
|
+
if (explicit)
|
|
14
|
+
return explicit;
|
|
15
|
+
const suffix = id.replace(/[^a-zA-Z0-9]/g, '').slice(-6) || id.slice(-6);
|
|
16
|
+
return `zero-${suffix}`;
|
|
17
|
+
}
|
|
18
|
+
/** Claim (or reuse) a Zero instance and bind it to a profile + credentials. */
|
|
19
|
+
export async function provisionInstance(deps, options = {}) {
|
|
20
|
+
const switchProfile = options.switchProfile !== false;
|
|
21
|
+
// Reuse path: bind the most recent active local instance instead of claiming.
|
|
22
|
+
if (options.reuse) {
|
|
23
|
+
const active = await deps.store.listActive();
|
|
24
|
+
const recent = active[active.length - 1];
|
|
25
|
+
if (recent) {
|
|
26
|
+
const existing = await deps.creds.getCredentials(recent.profileName);
|
|
27
|
+
if (existing) {
|
|
28
|
+
const switchedFrom = switchProfile ? (await deps.profiles.getCurrentProfile())?.name ?? null : null;
|
|
29
|
+
if (switchProfile)
|
|
30
|
+
await deps.profiles.useProfile(recent.profileName);
|
|
31
|
+
return {
|
|
32
|
+
reused: true,
|
|
33
|
+
profileName: recent.profileName,
|
|
34
|
+
switchedFrom,
|
|
35
|
+
instance: {
|
|
36
|
+
id: recent.id,
|
|
37
|
+
endpoint: recent.endpoint,
|
|
38
|
+
appEndpoint: recent.appEndpoint,
|
|
39
|
+
dashboardUrl: recent.dashboardUrl,
|
|
40
|
+
whitelistIp: recent.whitelistIp,
|
|
41
|
+
expiresAt: recent.expiresAt,
|
|
42
|
+
mode: 'single-tenant',
|
|
43
|
+
},
|
|
44
|
+
keys: {
|
|
45
|
+
anon: { fingerprint: computeFingerprint(existing.anonKey), role: 'anon' },
|
|
46
|
+
serviceRole: { fingerprint: computeFingerprint(existing.serviceRoleKey), role: 'service_role' },
|
|
47
|
+
},
|
|
48
|
+
dashboard: { username: 'supabase', passwordRevealed: false },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// no reusable instance → fall through to claim
|
|
53
|
+
}
|
|
54
|
+
const claimed = await deps.zero.claim(options.whitelistIp);
|
|
55
|
+
const inst = claimed.instance;
|
|
56
|
+
const endpoint = ZeroDriver.toEndpoint(inst);
|
|
57
|
+
const name = profileNameFor(inst.id, options.name);
|
|
58
|
+
// Fail-closed on name collision unless forced.
|
|
59
|
+
const existingProfile = await deps.profiles.getProfile(name);
|
|
60
|
+
if (existingProfile && !options.force) {
|
|
61
|
+
throw new Error(`Profile '${name}' already exists. Choose another with --name, or pass --force to overwrite.`);
|
|
62
|
+
}
|
|
63
|
+
const switchedFrom = switchProfile ? (await deps.profiles.getCurrentProfile())?.name ?? null : null;
|
|
64
|
+
const now = new Date().toISOString();
|
|
65
|
+
const profile = {
|
|
66
|
+
name,
|
|
67
|
+
endpoint,
|
|
68
|
+
appEndpoint: inst.appEndpoint,
|
|
69
|
+
mode: 'single-tenant',
|
|
70
|
+
source: 'zero',
|
|
71
|
+
zeroInstanceId: inst.id,
|
|
72
|
+
expiresAt: inst.expiresAt,
|
|
73
|
+
createdAt: existingProfile?.createdAt ?? now,
|
|
74
|
+
updatedAt: now,
|
|
75
|
+
};
|
|
76
|
+
await deps.profiles.setProfile(profile);
|
|
77
|
+
await deps.creds.setCredentials(name, {
|
|
78
|
+
anonKey: inst.apiKey,
|
|
79
|
+
serviceRoleKey: inst.serviceRoleKey,
|
|
80
|
+
storedAt: now,
|
|
81
|
+
});
|
|
82
|
+
const record = {
|
|
83
|
+
id: inst.id,
|
|
84
|
+
endpoint,
|
|
85
|
+
appEndpoint: inst.appEndpoint,
|
|
86
|
+
profileName: name,
|
|
87
|
+
token: claimed.token,
|
|
88
|
+
expiresAt: inst.expiresAt,
|
|
89
|
+
dashboardUrl: inst.dashboardUrl,
|
|
90
|
+
whitelistIp: inst.whitelistIp,
|
|
91
|
+
dashboardPassword: inst.dashboardPassword,
|
|
92
|
+
dbPassword: inst.dbPassword,
|
|
93
|
+
claimedAt: now,
|
|
94
|
+
};
|
|
95
|
+
await deps.store.addInstance(record);
|
|
96
|
+
if (switchProfile)
|
|
97
|
+
await deps.profiles.useProfile(name);
|
|
98
|
+
return {
|
|
99
|
+
reused: false,
|
|
100
|
+
profileName: name,
|
|
101
|
+
switchedFrom,
|
|
102
|
+
instance: {
|
|
103
|
+
id: inst.id,
|
|
104
|
+
endpoint,
|
|
105
|
+
dashboardUrl: inst.dashboardUrl,
|
|
106
|
+
region: inst.region,
|
|
107
|
+
whitelistIp: inst.whitelistIp,
|
|
108
|
+
expiresAt: inst.expiresAt,
|
|
109
|
+
mode: 'single-tenant',
|
|
110
|
+
},
|
|
111
|
+
keys: {
|
|
112
|
+
anon: { fingerprint: computeFingerprint(inst.apiKey), role: 'anon' },
|
|
113
|
+
serviceRole: { fingerprint: computeFingerprint(inst.serviceRoleKey), role: 'service_role' },
|
|
114
|
+
},
|
|
115
|
+
dashboard: { username: 'supabase', passwordRevealed: false },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** Release a Zero instance and unbind/remove its local profile. */
|
|
119
|
+
export async function releaseInstance(deps, id, opts = {}) {
|
|
120
|
+
const removeProfile = opts.removeProfile !== false;
|
|
121
|
+
const rec = await deps.store.getInstance(id);
|
|
122
|
+
const token = rec?.token ?? (await deps.store.getToken());
|
|
123
|
+
if (!token) {
|
|
124
|
+
throw new Error('No Zero ownership token found locally; cannot release. Did you provision from this machine?');
|
|
125
|
+
}
|
|
126
|
+
await deps.zero.release(id, token);
|
|
127
|
+
await deps.store.removeInstance(id);
|
|
128
|
+
let profileRemoved = null;
|
|
129
|
+
let wasCurrent = false;
|
|
130
|
+
if (rec && removeProfile) {
|
|
131
|
+
const current = await deps.profiles.getCurrentProfile();
|
|
132
|
+
wasCurrent = current?.name === rec.profileName;
|
|
133
|
+
await deps.creds.deleteCredentials(rec.profileName);
|
|
134
|
+
await deps.profiles.removeProfile(rec.profileName);
|
|
135
|
+
profileRemoved = rec.profileName;
|
|
136
|
+
}
|
|
137
|
+
return { id, released: true, profileRemoved, wasCurrent };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.js","sourceRoot":"","sources":["../../src/instance/provision.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,EAAE,UAAU,EAA6C,MAAM,yBAAyB,CAAC;AA6DhG,SAAS,cAAc,CAAC,EAAU,EAAE,QAAiB;IACnD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO,QAAQ,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAmB,EACnB,UAA4B,EAAE;IAE9B,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC;IAEtD,8EAA8E;IAC9E,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACrE,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACpG,IAAI,aAAa;oBAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACtE,OAAO;oBACL,MAAM,EAAE,IAAI;oBACZ,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,YAAY;oBACZ,QAAQ,EAAE;wBACR,EAAE,EAAE,MAAM,CAAC,EAAE;wBACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;wBACjC,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,IAAI,EAAE,eAAe;qBACtB;oBACD,IAAI,EAAE;wBACJ,IAAI,EAAE,EAAE,WAAW,EAAE,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;wBACzE,WAAW,EAAE,EAAE,WAAW,EAAE,kBAAkB,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE;qBAChG;oBACD,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,EAAE;iBAC7D,CAAC;YACJ,CAAC;QACH,CAAC;QACD,+CAA+C;IACjD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,+CAA+C;IAC/C,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7D,IAAI,eAAe,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,6EAA6E,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACpG,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,OAAO,GAAgB;QAC3B,IAAI;QACJ,QAAQ;QACR,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,MAAM;QACd,cAAc,EAAE,IAAI,CAAC,EAAE;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,eAAe,EAAE,SAAS,IAAI,GAAG;QAC5C,SAAS,EAAE,GAAG;KACf,CAAC;IACF,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAExC,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE;QACpC,OAAO,EAAE,IAAI,CAAC,MAAM;QACpB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,QAAQ,EAAE,GAAG;KACd,CAAC,CAAC;IAEH,MAAM,MAAM,GAAuB;QACjC,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,QAAQ;QACR,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI;QACjB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,GAAG;KACf,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,aAAa;QAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAExD,OAAO;QACL,MAAM,EAAE,KAAK;QACb,WAAW,EAAE,IAAI;QACjB,YAAY;QACZ,QAAQ,EAAE;YACR,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ;YACR,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,eAAe;SACtB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,EAAE,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;YACpE,WAAW,EAAE,EAAE,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE;SAC5F;QACD,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,EAAE;KAC7D,CAAC;AACJ,CAAC;AASD,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAmB,EACnB,EAAU,EACV,OAAoC,EAAE;IAEtC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,GAAG,EAAE,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IAED,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAEpC,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QACxD,UAAU,GAAG,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC,WAAW,CAAC;QAC/C,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACnD,cAAc,GAAG,GAAG,CAAC,WAAW,CAAC;IACnC,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero store — persists PolarDB-X Zero ownership token and claimed-instance
|
|
3
|
+
* bindings under `~/.baas/zero.json` (mode 0600).
|
|
4
|
+
*
|
|
5
|
+
* Because PXBaas has NO credentials re-read endpoint (unlike PXFuse), the keys
|
|
6
|
+
* returned at claim time must be durably stored here (and in the keyring via
|
|
7
|
+
* CredentialStore). `instance list` cannot fetch keys back from Zero.
|
|
8
|
+
*/
|
|
9
|
+
export interface ZeroInstanceRecord {
|
|
10
|
+
id: string;
|
|
11
|
+
endpoint: string;
|
|
12
|
+
appEndpoint?: string;
|
|
13
|
+
profileName: string;
|
|
14
|
+
token: string;
|
|
15
|
+
expiresAt?: string;
|
|
16
|
+
dashboardUrl?: string;
|
|
17
|
+
whitelistIp?: string;
|
|
18
|
+
/** Sensitive; stored 0600, never printed except via `instance credentials --reveal`. */
|
|
19
|
+
dashboardPassword?: string;
|
|
20
|
+
dbPassword?: string;
|
|
21
|
+
claimedAt: string;
|
|
22
|
+
}
|
|
23
|
+
interface ZeroStoreFile {
|
|
24
|
+
version: 1;
|
|
25
|
+
token: string;
|
|
26
|
+
instances: ZeroInstanceRecord[];
|
|
27
|
+
}
|
|
28
|
+
export declare class ZeroStore {
|
|
29
|
+
private homeDir;
|
|
30
|
+
private cache;
|
|
31
|
+
constructor(homeDir?: string);
|
|
32
|
+
private filePath;
|
|
33
|
+
load(): Promise<ZeroStoreFile>;
|
|
34
|
+
private save;
|
|
35
|
+
/** Latest ownership token (empty string when never provisioned). */
|
|
36
|
+
getToken(): Promise<string>;
|
|
37
|
+
/** Upsert an instance record by id and refresh the top-level token. */
|
|
38
|
+
addInstance(record: ZeroInstanceRecord): Promise<void>;
|
|
39
|
+
getInstance(id: string): Promise<ZeroInstanceRecord | null>;
|
|
40
|
+
findInstanceByProfile(profileName: string): Promise<ZeroInstanceRecord | null>;
|
|
41
|
+
listInstances(): Promise<ZeroInstanceRecord[]>;
|
|
42
|
+
/** Instances whose expiresAt is in the future (or unknown). */
|
|
43
|
+
listActive(now?: Date): Promise<ZeroInstanceRecord[]>;
|
|
44
|
+
removeInstance(id: string): Promise<boolean>;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=zero-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zero-store.d.ts","sourceRoot":"","sources":["../../src/instance/zero-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAA8B;gBAE/B,OAAO,CAAC,EAAE,MAAM;IAI5B,OAAO,CAAC,QAAQ;IAIV,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;YAiBtB,IAAI;IAQlB,oEAAoE;IAC9D,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAKjC,uEAAuE;IACjE,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAStD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAK3D,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAK9E,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAKpD,+DAA+D;IACzD,UAAU,CAAC,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAKjE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQnD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero store — persists PolarDB-X Zero ownership token and claimed-instance
|
|
3
|
+
* bindings under `~/.baas/zero.json` (mode 0600).
|
|
4
|
+
*
|
|
5
|
+
* Because PXBaas has NO credentials re-read endpoint (unlike PXFuse), the keys
|
|
6
|
+
* returned at claim time must be durably stored here (and in the keyring via
|
|
7
|
+
* CredentialStore). `instance list` cannot fetch keys back from Zero.
|
|
8
|
+
*/
|
|
9
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
export class ZeroStore {
|
|
14
|
+
homeDir;
|
|
15
|
+
cache = null;
|
|
16
|
+
constructor(homeDir) {
|
|
17
|
+
this.homeDir = homeDir ?? join(homedir(), '.baas');
|
|
18
|
+
}
|
|
19
|
+
filePath() {
|
|
20
|
+
return join(this.homeDir, 'zero.json');
|
|
21
|
+
}
|
|
22
|
+
async load() {
|
|
23
|
+
if (this.cache)
|
|
24
|
+
return this.cache;
|
|
25
|
+
const p = this.filePath();
|
|
26
|
+
if (!existsSync(p)) {
|
|
27
|
+
this.cache = { version: 1, token: '', instances: [] };
|
|
28
|
+
return this.cache;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const data = JSON.parse(await readFile(p, 'utf-8'));
|
|
32
|
+
if (data.version !== 1)
|
|
33
|
+
throw new Error(`Unsupported zero.json version: ${data.version}`);
|
|
34
|
+
this.cache = { version: 1, token: data.token ?? '', instances: data.instances ?? [] };
|
|
35
|
+
return this.cache;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
throw new Error(`Failed to read zero.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async save(state) {
|
|
42
|
+
if (!existsSync(this.homeDir)) {
|
|
43
|
+
await mkdir(this.homeDir, { mode: 0o700, recursive: true });
|
|
44
|
+
}
|
|
45
|
+
await writeFile(this.filePath(), JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
|
|
46
|
+
this.cache = state;
|
|
47
|
+
}
|
|
48
|
+
/** Latest ownership token (empty string when never provisioned). */
|
|
49
|
+
async getToken() {
|
|
50
|
+
const s = await this.load();
|
|
51
|
+
return s.token;
|
|
52
|
+
}
|
|
53
|
+
/** Upsert an instance record by id and refresh the top-level token. */
|
|
54
|
+
async addInstance(record) {
|
|
55
|
+
const s = await this.load();
|
|
56
|
+
const idx = s.instances.findIndex((i) => i.id === record.id);
|
|
57
|
+
if (idx >= 0)
|
|
58
|
+
s.instances[idx] = record;
|
|
59
|
+
else
|
|
60
|
+
s.instances.push(record);
|
|
61
|
+
s.token = record.token || s.token;
|
|
62
|
+
await this.save(s);
|
|
63
|
+
}
|
|
64
|
+
async getInstance(id) {
|
|
65
|
+
const s = await this.load();
|
|
66
|
+
return s.instances.find((i) => i.id === id) ?? null;
|
|
67
|
+
}
|
|
68
|
+
async findInstanceByProfile(profileName) {
|
|
69
|
+
const s = await this.load();
|
|
70
|
+
return s.instances.find((i) => i.profileName === profileName) ?? null;
|
|
71
|
+
}
|
|
72
|
+
async listInstances() {
|
|
73
|
+
const s = await this.load();
|
|
74
|
+
return [...s.instances];
|
|
75
|
+
}
|
|
76
|
+
/** Instances whose expiresAt is in the future (or unknown). */
|
|
77
|
+
async listActive(now = new Date()) {
|
|
78
|
+
const s = await this.load();
|
|
79
|
+
return s.instances.filter((i) => !i.expiresAt || new Date(i.expiresAt).getTime() > now.getTime());
|
|
80
|
+
}
|
|
81
|
+
async removeInstance(id) {
|
|
82
|
+
const s = await this.load();
|
|
83
|
+
const before = s.instances.length;
|
|
84
|
+
s.instances = s.instances.filter((i) => i.id !== id);
|
|
85
|
+
if (s.instances.length === before)
|
|
86
|
+
return false;
|
|
87
|
+
await this.save(s);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=zero-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zero-store.js","sourceRoot":"","sources":["../../src/instance/zero-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAuBjC,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAChB,KAAK,GAAyB,IAAI,CAAC;IAE3C,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAEO,QAAQ;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAkB,CAAC;YACrE,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1F,IAAI,CAAC,KAAK,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACtF,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,KAAoB;QACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,QAAQ;QACZ,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC,KAAK,CAAC;IACjB,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,WAAW,CAAC,MAA0B;QAC1C,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,GAAG,IAAI,CAAC;YAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;;YACnC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC1B,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,WAAmB;QAC7C,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,IAAI,IAAI,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,UAAU,CAAC,MAAY,IAAI,IAAI,EAAE;QACrC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU;QAC7B,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;QAClC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QAChD,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero whitelist self-service helpers (CLI side).
|
|
3
|
+
*
|
|
4
|
+
* The whitelist API authenticates with a Studio-credential HASH (not the pxz_token
|
|
5
|
+
* ownership cookie) and addresses the instance by its cloud id (`pxsp-*`), so this
|
|
6
|
+
* module turns a locally-bound Zero record into the (cloudInstanceId, studioHash)
|
|
7
|
+
* pair the driver needs — and enforces the "Zero instances only" guard.
|
|
8
|
+
*
|
|
9
|
+
* The dashboard password and its derived sha256("supabase:"+password) are NEVER
|
|
10
|
+
* returned in any printable field; only the opaque `studioHash` is handed to the
|
|
11
|
+
* driver. See references/provision.md and the pxbaas-cli SKILL safety rules.
|
|
12
|
+
*/
|
|
13
|
+
import { type ZeroInstanceRecord } from './zero-store.js';
|
|
14
|
+
/**
|
|
15
|
+
* sha256hex("<user>:<password>"), UTF-8, no trailing newline. Equivalent to the
|
|
16
|
+
* password — never log or persist it. `user` is fixed to `supabase` by the API.
|
|
17
|
+
*/
|
|
18
|
+
export declare function studioCredentialHash(password: string, user?: string): string;
|
|
19
|
+
export interface WhitelistTarget {
|
|
20
|
+
record: ZeroInstanceRecord;
|
|
21
|
+
/** Cloud instance id (`pxsp-*`) used in the whitelist API path. */
|
|
22
|
+
cloudInstanceId: string;
|
|
23
|
+
/** Opaque Studio-credential sha256; do not print. */
|
|
24
|
+
studioHash: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve which Zero instance a `whitelist get|add` targets.
|
|
28
|
+
*
|
|
29
|
+
* - `opts.id` (an `sbx_*` ownership id) selects explicitly.
|
|
30
|
+
* - Otherwise the current profile is used and MUST be `source === 'zero'`.
|
|
31
|
+
*
|
|
32
|
+
* Throws a plain Error (clear, user-facing) when the target is not a locally-bound
|
|
33
|
+
* Zero instance or has no stored dashboard password — the whitelist surface is
|
|
34
|
+
* Zero-only by design.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveWhitelistTarget(opts: {
|
|
37
|
+
id: string | undefined;
|
|
38
|
+
}): Promise<WhitelistTarget>;
|
|
39
|
+
//# sourceMappingURL=zero-whitelist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zero-whitelist.d.ts","sourceRoot":"","sources":["../../src/instance/zero-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAa,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,SAAa,GAAG,MAAM,CAEhF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAkCvG"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero whitelist self-service helpers (CLI side).
|
|
3
|
+
*
|
|
4
|
+
* The whitelist API authenticates with a Studio-credential HASH (not the pxz_token
|
|
5
|
+
* ownership cookie) and addresses the instance by its cloud id (`pxsp-*`), so this
|
|
6
|
+
* module turns a locally-bound Zero record into the (cloudInstanceId, studioHash)
|
|
7
|
+
* pair the driver needs — and enforces the "Zero instances only" guard.
|
|
8
|
+
*
|
|
9
|
+
* The dashboard password and its derived sha256("supabase:"+password) are NEVER
|
|
10
|
+
* returned in any printable field; only the opaque `studioHash` is handed to the
|
|
11
|
+
* driver. See references/provision.md and the pxbaas-cli SKILL safety rules.
|
|
12
|
+
*/
|
|
13
|
+
import { createHash } from 'node:crypto';
|
|
14
|
+
import { ZeroDriver } from '@polardbx/pxbaas-client';
|
|
15
|
+
import { ProfileManager } from '../credentials/profile.js';
|
|
16
|
+
import { ZeroStore } from './zero-store.js';
|
|
17
|
+
/**
|
|
18
|
+
* sha256hex("<user>:<password>"), UTF-8, no trailing newline. Equivalent to the
|
|
19
|
+
* password — never log or persist it. `user` is fixed to `supabase` by the API.
|
|
20
|
+
*/
|
|
21
|
+
export function studioCredentialHash(password, user = 'supabase') {
|
|
22
|
+
return createHash('sha256').update(`${user}:${password}`, 'utf8').digest('hex');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve which Zero instance a `whitelist get|add` targets.
|
|
26
|
+
*
|
|
27
|
+
* - `opts.id` (an `sbx_*` ownership id) selects explicitly.
|
|
28
|
+
* - Otherwise the current profile is used and MUST be `source === 'zero'`.
|
|
29
|
+
*
|
|
30
|
+
* Throws a plain Error (clear, user-facing) when the target is not a locally-bound
|
|
31
|
+
* Zero instance or has no stored dashboard password — the whitelist surface is
|
|
32
|
+
* Zero-only by design.
|
|
33
|
+
*/
|
|
34
|
+
export async function resolveWhitelistTarget(opts) {
|
|
35
|
+
const store = new ZeroStore();
|
|
36
|
+
let record;
|
|
37
|
+
if (opts.id) {
|
|
38
|
+
record = await store.getInstance(opts.id);
|
|
39
|
+
if (!record) {
|
|
40
|
+
throw new Error(`No Zero instance '${opts.id}' bound on this machine. Whitelist management is only available for Zero-provisioned instances.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const current = await new ProfileManager().getCurrentProfile();
|
|
45
|
+
if (!current) {
|
|
46
|
+
throw new Error('No active profile. Run `pxbaas provision` to claim a Zero instance first.');
|
|
47
|
+
}
|
|
48
|
+
if (current.source !== 'zero') {
|
|
49
|
+
throw new Error(`Whitelist management is only available for Zero-provisioned instances; current profile '${current.name}' is not a Zero instance (source='${current.source ?? 'login'}').`);
|
|
50
|
+
}
|
|
51
|
+
record =
|
|
52
|
+
(current.zeroInstanceId ? await store.getInstance(current.zeroInstanceId) : null) ??
|
|
53
|
+
(await store.findInstanceByProfile(current.name));
|
|
54
|
+
if (!record) {
|
|
55
|
+
throw new Error(`Zero instance for profile '${current.name}' is not bound locally; cannot authenticate the whitelist API.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!record.dashboardPassword) {
|
|
59
|
+
throw new Error('This Zero instance has no stored dashboard password, so the whitelist API cannot be authenticated. Re-provision from this machine (`pxbaas provision`).');
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
record,
|
|
63
|
+
cloudInstanceId: ZeroDriver.cloudInstanceId(record.endpoint),
|
|
64
|
+
studioHash: studioCredentialHash(record.dashboardPassword),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=zero-whitelist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zero-whitelist.js","sourceRoot":"","sources":["../../src/instance/zero-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAA2B,MAAM,iBAAiB,CAAC;AAErE;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,IAAI,GAAG,UAAU;IACtE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAgC;IAC3E,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;IAC9B,IAAI,MAAiC,CAAC;IAEtC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,EAAE,iGAAiG,CAAC,CAAC;QACjJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC,iBAAiB,EAAE,CAAC;QAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,2FAA2F,OAAO,CAAC,IAAI,qCAAqC,OAAO,CAAC,MAAM,IAAI,OAAO,KAAK,CAAC,CAAC;QAC9L,CAAC;QACD,MAAM;YACJ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjF,CAAC,MAAM,KAAK,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,CAAC,IAAI,gEAAgE,CAAC,CAAC;QAC9H,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,yJAAyJ,CAAC,CAAC;IAC7K,CAAC;IAED,OAAO;QACL,MAAM;QACN,eAAe,EAAE,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5D,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,iBAAiB,CAAC;KAC3D,CAAC;AACJ,CAAC"}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { registerCommands } from './cli/root.js';
|
|
4
|
+
import { TOP_LEVEL_AGENT_GUIDE } from './cli/help-guides.js';
|
|
5
|
+
import { ProfileManager, isProfileCreatingCommand, setCliProfileOverrideGlobal, } from './credentials/profile.js';
|
|
6
|
+
import { resolvePackageVersion } from './version.js';
|
|
7
|
+
// Global options
|
|
8
|
+
program
|
|
9
|
+
.name('pxbaas')
|
|
10
|
+
.description('PolarDB-X BaaS CLI')
|
|
11
|
+
// Read from package.json at runtime: a hardcoded string here reported
|
|
12
|
+
// `0.0.0-dev` for every build, so `--version` could never identify a release.
|
|
13
|
+
.version(resolvePackageVersion())
|
|
14
|
+
.option('--json', 'Output in JSON format')
|
|
15
|
+
.option('--profile <name>', 'Use specific profile')
|
|
16
|
+
.option('--debug', 'Enable debug output')
|
|
17
|
+
// Discoverability for coding agents: the full develop-and-deploy workflow
|
|
18
|
+
// lives under `pxbaas app --help`; keep this pointer to three lines.
|
|
19
|
+
.addHelpText('after', TOP_LEVEL_AGENT_GUIDE);
|
|
20
|
+
// Register all commands
|
|
21
|
+
registerCommands(program);
|
|
22
|
+
// `--profile` is a program-level option, so commander only parses it when given
|
|
23
|
+
// BEFORE the subcommand (`pxbaas --profile x app list`). Every command resolves
|
|
24
|
+
// credentials through ProfileManager.getCurrentProfile(), which used to make a
|
|
25
|
+
// trailing `--profile` a silent no-op — the command then ran against whatever
|
|
26
|
+
// profile happened to be current, i.e. a cross-instance write hazard.
|
|
27
|
+
// Declare it on every (sub)command as well so both positions work.
|
|
28
|
+
const declareProfileOption = (cmd) => {
|
|
29
|
+
if (!cmd.options.some((o) => o.long === '--profile')) {
|
|
30
|
+
cmd.option('--profile <name>', 'Use specific profile');
|
|
31
|
+
}
|
|
32
|
+
cmd.commands.forEach(declareProfileOption);
|
|
33
|
+
};
|
|
34
|
+
declareProfileOption(program);
|
|
35
|
+
/** Full command path of the action command (e.g. ['profile','import']), program name excluded. */
|
|
36
|
+
const commandPathOf = (actionCommand) => {
|
|
37
|
+
const parts = [];
|
|
38
|
+
for (let c = actionCommand; c && c !== program; c = c.parent) {
|
|
39
|
+
if (c.name())
|
|
40
|
+
parts.unshift(c.name());
|
|
41
|
+
}
|
|
42
|
+
return parts;
|
|
43
|
+
};
|
|
44
|
+
// Resolve --profile once, before any command runs: validate it exists (fail loudly
|
|
45
|
+
// instead of silently falling back to the current profile) and publish it as a
|
|
46
|
+
// process-wide override. Never persisted — `profile ls` current marker is untouched.
|
|
47
|
+
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
48
|
+
const requested = (actionCommand.opts().profile ?? program.opts().profile);
|
|
49
|
+
if (!requested)
|
|
50
|
+
return;
|
|
51
|
+
// `login` / `profile import` write the named profile, so an unknown name is their
|
|
52
|
+
// precondition, not an error. Still publish the override: the command must read and
|
|
53
|
+
// write that exact profile rather than whatever happens to be current.
|
|
54
|
+
if (isProfileCreatingCommand(commandPathOf(actionCommand))) {
|
|
55
|
+
setCliProfileOverrideGlobal(requested);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const manager = new ProfileManager();
|
|
59
|
+
const known = await manager.listProfiles();
|
|
60
|
+
if (!known.some((p) => p.name === requested)) {
|
|
61
|
+
const names = known.map((p) => p.name).join(', ') || '(none)';
|
|
62
|
+
console.error(`✗ Unknown profile: '${requested}'. Available profiles: ${names}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
setCliProfileOverrideGlobal(requested);
|
|
66
|
+
});
|
|
67
|
+
// Parse arguments
|
|
68
|
+
program.parse();
|
|
69
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed AGENTS.md block for agents without a SKILL.md convention.
|
|
3
|
+
*
|
|
4
|
+
* Cloud agents (Devin, Jules, Copilot coding agent) and guideline-only tools
|
|
5
|
+
* (Junie, Comate, CodeArts, Windsurf, Kiro steering) read repository-level
|
|
6
|
+
* AGENTS.md. `pxbaas skill install --scope project --agents-md` writes a small
|
|
7
|
+
* marker-delimited block pointing at the exported skill directories and
|
|
8
|
+
* `pxbaas guide`. Everything outside the markers is never touched, and the
|
|
9
|
+
* block is idempotently replaced on re-install.
|
|
10
|
+
*/
|
|
11
|
+
export declare const AGENTS_MD_FILE = "AGENTS.md";
|
|
12
|
+
export declare const BEGIN_MARKER = "<!-- BEGIN pxbaas-skills (managed by pxbaas skill install; do not edit) -->";
|
|
13
|
+
export declare const END_MARKER = "<!-- END pxbaas-skills -->";
|
|
14
|
+
export declare function renderBlock(lines: string[]): string;
|
|
15
|
+
export declare function upsertAgentsMdBlock(projectRoot: string, lines: string[]): Promise<{
|
|
16
|
+
path: string;
|
|
17
|
+
created: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function removeAgentsMdBlock(projectRoot: string): Promise<{
|
|
20
|
+
path: string;
|
|
21
|
+
removed: boolean;
|
|
22
|
+
deletedFile: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function agentsMdBlockPresent(projectRoot: string): Promise<boolean>;
|
|
25
|
+
//# sourceMappingURL=agents-md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.d.ts","sourceRoot":"","sources":["../../src/skill/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,YAAY,gFACsD,CAAC;AAChF,eAAO,MAAM,UAAU,+BAA+B,CAAC;AAUvD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnD;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAa7C;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CAYnE;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhF"}
|