@tiangong-lca/cli 0.1.6 → 0.1.8
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 +21 -22
- package/dist/src/cli.js +46 -48
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/auth-identity-receipt.d.ts +1 -2
- package/dist/src/lib/auth-identity-receipt.js +3 -20
- package/dist/src/lib/auth-identity-receipt.js.map +1 -1
- package/dist/src/lib/credential-safety.d.ts +7 -0
- package/dist/src/lib/credential-safety.js +28 -0
- package/dist/src/lib/credential-safety.js.map +1 -0
- package/dist/src/lib/dataset-command.d.ts +2 -0
- package/dist/src/lib/dataset-command.js +20 -0
- package/dist/src/lib/dataset-command.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +3 -1
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
- package/dist/src/lib/env.d.ts +9 -2
- package/dist/src/lib/env.js +83 -24
- package/dist/src/lib/env.js.map +1 -1
- package/dist/src/lib/flow-publish-reviewed-data.js +1 -1
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-resulting-process.js +5 -7
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +1 -1
- package/dist/src/lib/process-refresh-references.js.map +1 -1
- package/dist/src/lib/process-save-draft.d.ts +1 -0
- package/dist/src/lib/process-save-draft.js +8 -0
- package/dist/src/lib/process-save-draft.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +1 -1
- package/dist/src/lib/process-scope-statistics.js.map +1 -1
- package/dist/src/lib/publish.d.ts +7 -0
- package/dist/src/lib/publish.js +111 -7
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/supabase-client.d.ts +4 -4
- package/dist/src/lib/supabase-client.js +16 -16
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/dist/src/lib/supabase-data-api-contract.d.ts +18 -10
- package/dist/src/lib/supabase-data-api-contract.js +17 -9
- package/dist/src/lib/supabase-data-api-contract.js.map +1 -1
- package/dist/src/lib/supabase-json-ordered-write.js +3 -1
- package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
- package/dist/src/lib/supabase-session.d.ts +5 -14
- package/dist/src/lib/supabase-session.js +34 -113
- package/dist/src/lib/supabase-session.js.map +1 -1
- package/package.json +1 -2
- package/dist/src/lib/user-api-key.d.ts +0 -16
- package/dist/src/lib/user-api-key.js +0 -75
- package/dist/src/lib/user-api-key.js.map +0 -1
|
@@ -79,7 +79,7 @@ export declare const DATA_API_RPC_TARGETS: {
|
|
|
79
79
|
};
|
|
80
80
|
readonly cmd_dataset_save_draft: {
|
|
81
81
|
readonly targetSchema: 'api';
|
|
82
|
-
readonly signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb)';
|
|
82
|
+
readonly signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb, p_model_version text)';
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
85
|
export type DataApiRpc = keyof typeof DATA_API_RPC_TARGETS;
|
|
@@ -87,9 +87,9 @@ export declare const DATA_API_CONTRACT: {
|
|
|
87
87
|
readonly schemaVersion: 'tiangong-lca-cli.data-api-contract.v1';
|
|
88
88
|
readonly databaseContract: {
|
|
89
89
|
readonly repository: 'tiangong-lca/database-engine';
|
|
90
|
-
readonly databaseCommit: '
|
|
91
|
-
readonly migrationHead: '
|
|
92
|
-
readonly migrationSetGitTreeSha: '
|
|
90
|
+
readonly databaseCommit: '1320dcc506fe37af6b625ae30fbe0bec38cf87c6';
|
|
91
|
+
readonly migrationHead: '20260902104500';
|
|
92
|
+
readonly migrationSetGitTreeSha: '88e212220c0037cee673d0522340d3cca5e791dd';
|
|
93
93
|
readonly contractMigrations: {
|
|
94
94
|
readonly fullSchemaCutover: {
|
|
95
95
|
readonly path: 'supabase/migrations/20260805130000_full_schema_cutover.sql';
|
|
@@ -99,21 +99,29 @@ export declare const DATA_API_CONTRACT: {
|
|
|
99
99
|
readonly path: 'supabase/migrations/20260806160000_api_contract_closure.sql';
|
|
100
100
|
readonly sha256: 'e0e7aec8e03d70c60ee0d5c2b332ce73fa7b4b229725c9a9fcb0e1a1d7e8c511';
|
|
101
101
|
};
|
|
102
|
+
readonly processModelVersionContract: {
|
|
103
|
+
readonly path: 'supabase/migrations/20260902100000_process_model_version_contract.sql';
|
|
104
|
+
readonly sha256: '99cbaf474098281ea8c57fcef093174d0ef78a18300f133dd8cc6f9e59a4a29b';
|
|
105
|
+
};
|
|
106
|
+
readonly processSaveDraftModelVersion: {
|
|
107
|
+
readonly path: 'supabase/migrations/20260902103509_add_process_model_version_to_dataset_save_draft.sql';
|
|
108
|
+
readonly sha256: 'ca93f3279673e292803bd8c477aec76b772c7246e16114808d31e64994037723';
|
|
109
|
+
};
|
|
102
110
|
readonly migrationHead: {
|
|
103
|
-
readonly path: 'supabase/migrations/
|
|
104
|
-
readonly sha256: '
|
|
111
|
+
readonly path: 'supabase/migrations/20260902104500_use_exact_model_version_in_review_ownership.sql';
|
|
112
|
+
readonly sha256: '538ec3001f7683b57817e4a89973ded127522ce94521720ed583de99711bbe60';
|
|
105
113
|
};
|
|
106
114
|
};
|
|
107
115
|
readonly contractReady: true;
|
|
108
|
-
readonly snapshotRole: 'frozen-
|
|
109
|
-
readonly provenanceIssue: 'tiangong-lca/database-engine#
|
|
116
|
+
readonly snapshotRole: 'frozen-process-model-version-contract';
|
|
117
|
+
readonly provenanceIssue: 'tiangong-lca/database-engine#589';
|
|
110
118
|
readonly publicCoreTableCount: 9;
|
|
111
119
|
readonly publicRoutineCount: 0;
|
|
112
120
|
};
|
|
113
121
|
readonly profiles: {
|
|
114
122
|
readonly 'api-contract-v1': {
|
|
115
123
|
readonly phase: 'contract';
|
|
116
|
-
readonly description: 'Frozen api RPC profile for database-engine migration head
|
|
124
|
+
readonly description: 'Frozen api RPC profile for database-engine migration head 20260902104500.';
|
|
117
125
|
};
|
|
118
126
|
};
|
|
119
127
|
readonly corePublicRelations: readonly ["contacts", "flowproperties", "flows", "ilcd", "lciamethods", "lifecyclemodels", "processes", "sources", "unitgroups"];
|
|
@@ -192,7 +200,7 @@ export declare const DATA_API_CONTRACT: {
|
|
|
192
200
|
};
|
|
193
201
|
readonly cmd_dataset_save_draft: {
|
|
194
202
|
readonly targetSchema: 'api';
|
|
195
|
-
readonly signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb)';
|
|
203
|
+
readonly signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb, p_model_version text)';
|
|
196
204
|
};
|
|
197
205
|
};
|
|
198
206
|
readonly rpcReplayClassification: {
|
|
@@ -147,16 +147,16 @@ export const DATA_API_RPC_TARGETS = {
|
|
|
147
147
|
},
|
|
148
148
|
cmd_dataset_save_draft: {
|
|
149
149
|
targetSchema: 'api',
|
|
150
|
-
signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb)',
|
|
150
|
+
signature: 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb, p_model_version text)',
|
|
151
151
|
},
|
|
152
152
|
};
|
|
153
153
|
export const DATA_API_CONTRACT = {
|
|
154
154
|
schemaVersion: 'tiangong-lca-cli.data-api-contract.v1',
|
|
155
155
|
databaseContract: {
|
|
156
156
|
repository: 'tiangong-lca/database-engine',
|
|
157
|
-
databaseCommit: '
|
|
158
|
-
migrationHead: '
|
|
159
|
-
migrationSetGitTreeSha: '
|
|
157
|
+
databaseCommit: '1320dcc506fe37af6b625ae30fbe0bec38cf87c6',
|
|
158
|
+
migrationHead: '20260902104500',
|
|
159
|
+
migrationSetGitTreeSha: '88e212220c0037cee673d0522340d3cca5e791dd',
|
|
160
160
|
contractMigrations: {
|
|
161
161
|
fullSchemaCutover: {
|
|
162
162
|
path: 'supabase/migrations/20260805130000_full_schema_cutover.sql',
|
|
@@ -166,21 +166,29 @@ export const DATA_API_CONTRACT = {
|
|
|
166
166
|
path: 'supabase/migrations/20260806160000_api_contract_closure.sql',
|
|
167
167
|
sha256: 'e0e7aec8e03d70c60ee0d5c2b332ce73fa7b4b229725c9a9fcb0e1a1d7e8c511',
|
|
168
168
|
},
|
|
169
|
+
processModelVersionContract: {
|
|
170
|
+
path: 'supabase/migrations/20260902100000_process_model_version_contract.sql',
|
|
171
|
+
sha256: '99cbaf474098281ea8c57fcef093174d0ef78a18300f133dd8cc6f9e59a4a29b',
|
|
172
|
+
},
|
|
173
|
+
processSaveDraftModelVersion: {
|
|
174
|
+
path: 'supabase/migrations/20260902103509_add_process_model_version_to_dataset_save_draft.sql',
|
|
175
|
+
sha256: 'ca93f3279673e292803bd8c477aec76b772c7246e16114808d31e64994037723',
|
|
176
|
+
},
|
|
169
177
|
migrationHead: {
|
|
170
|
-
path: 'supabase/migrations/
|
|
171
|
-
sha256: '
|
|
178
|
+
path: 'supabase/migrations/20260902104500_use_exact_model_version_in_review_ownership.sql',
|
|
179
|
+
sha256: '538ec3001f7683b57817e4a89973ded127522ce94521720ed583de99711bbe60',
|
|
172
180
|
},
|
|
173
181
|
},
|
|
174
182
|
contractReady: true,
|
|
175
|
-
snapshotRole: 'frozen-
|
|
176
|
-
provenanceIssue: 'tiangong-lca/database-engine#
|
|
183
|
+
snapshotRole: 'frozen-process-model-version-contract',
|
|
184
|
+
provenanceIssue: 'tiangong-lca/database-engine#589',
|
|
177
185
|
publicCoreTableCount: 9,
|
|
178
186
|
publicRoutineCount: 0,
|
|
179
187
|
},
|
|
180
188
|
profiles: {
|
|
181
189
|
'api-contract-v1': {
|
|
182
190
|
phase: 'contract',
|
|
183
|
-
description: 'Frozen api RPC profile for database-engine migration head
|
|
191
|
+
description: 'Frozen api RPC profile for database-engine migration head 20260902104500.',
|
|
184
192
|
},
|
|
185
193
|
},
|
|
186
194
|
corePublicRelations: CORE_PUBLIC_RELATIONS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase-data-api-contract.js","sourceRoot":"","sources":["../../../src/lib/supabase-data-api-contract.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport { DATA_API_RPC_REPLAY_CLASSIFICATION } from './supabase-data-api-replay.js';\nexport {\n DATA_API_RPC_REPLAY_CLASSIFICATION,\n isDataApiAuthRefreshReplaySafe,\n} from './supabase-data-api-replay.js';\n\nexport const DATA_API_PROFILE_ENV = 'TIANGONG_LCA_DATA_API_PROFILE';\nexport const DATA_API_PROFILES = ['api-contract-v1'] as const;\nexport type DataApiProfile = (typeof DATA_API_PROFILES)[number];\nexport type DataApiRole = 'anon' | 'authenticated' | 'service_role';\n\nexport const CORE_PUBLIC_RELATIONS = [\n 'contacts',\n 'flowproperties',\n 'flows',\n 'ilcd',\n 'lciamethods',\n 'lifecyclemodels',\n 'processes',\n 'sources',\n 'unitgroups',\n] as const;\nexport type CorePublicRelation = (typeof CORE_PUBLIC_RELATIONS)[number];\n\nexport const DATA_API_RELATION_CONSUMERS = {\n contacts: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n flowproperties: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n flows: [\n 'src/lib/flow-read.ts',\n 'src/lib/flow-list.ts',\n 'src/lib/flow-publish-version.ts',\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n ilcd: [],\n lciamethods: [\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n lifecyclemodels: [\n 'src/lib/lifecyclemodel-bundle-save.ts',\n 'src/lib/process-dedup-review.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n processes: [\n 'src/lib/process-get.ts',\n 'src/lib/process-list.ts',\n 'src/lib/process-save-draft.ts',\n 'src/lib/process-scope-statistics.ts',\n 'src/lib/process-dedup-review.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/supabase-rest.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n sources: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n unitgroups: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n} as const satisfies Record<CorePublicRelation, readonly string[]>;\n\ntype RpcTarget = {\n targetSchema: 'api';\n signature: string;\n};\n\nexport const DATA_API_RPC_TARGETS = {\n cmd_dataset_alias_execution_admit_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_admit_guarded(p_request jsonb)',\n },\n cmd_dataset_alias_execution_gate_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_alias_execution_gate_guarded(p_request_id uuid, p_preflight_token text, p_gate_name text)',\n },\n cmd_dataset_alias_execution_preflight_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_preflight_guarded(p_request jsonb)',\n },\n cmd_dataset_alias_execution_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_read(p_request_id uuid)',\n },\n cmd_dataset_delete: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_delete(p_table text, p_id uuid, p_version text, p_audit jsonb)',\n },\n cmd_dataset_derivative_rebuild_plan_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_derivative_rebuild_plan_guarded(p_plan jsonb)',\n },\n cmd_dataset_derivative_rebuild_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_derivative_rebuild_read(p_request_id uuid)',\n },\n cmd_dataset_derivative_rebuild_snapshot: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_derivative_rebuild_snapshot(p_table text, p_id uuid, p_version text)',\n },\n cmd_dataset_flow_identity_capture_attest_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_capture_attest_guarded(p_request jsonb)',\n },\n cmd_dataset_flow_identity_process_rewrite_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_process_rewrite_guarded(p_scope_id uuid, p_request jsonb, p_authorization jsonb)',\n },\n cmd_dataset_flow_identity_scope_finalize_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_scope_finalize_guarded(p_scope_id uuid, p_request jsonb, p_authorization jsonb)',\n },\n cmd_dataset_flow_identity_scope_lookup: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_lookup(p_request jsonb)',\n },\n cmd_dataset_flow_identity_scope_preflight_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_preflight_guarded(p_request jsonb)',\n },\n cmd_dataset_flow_identity_scope_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_read(p_scope_id uuid)',\n },\n cmd_dataset_flow_identity_scope_recover_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_scope_recover_guarded(p_scope_id uuid, p_request jsonb)',\n },\n cmd_dataset_save_draft: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb)',\n },\n} as const satisfies Record<string, RpcTarget>;\n\nexport type DataApiRpc = keyof typeof DATA_API_RPC_TARGETS;\n\nexport const DATA_API_CONTRACT = {\n schemaVersion: 'tiangong-lca-cli.data-api-contract.v1',\n databaseContract: {\n repository: 'tiangong-lca/database-engine',\n databaseCommit: '0a97cc761f8127ca379ab7d4df4395dab255707a',\n migrationHead: '20260807103000',\n migrationSetGitTreeSha: '116c1f08b5490eec630f997403b07c3fcb830a69',\n contractMigrations: {\n fullSchemaCutover: {\n path: 'supabase/migrations/20260805130000_full_schema_cutover.sql',\n sha256: 'd409022fb25d9313d17b0f76216ca6e4abbfce7d6c5b6e74c869314d1c7e5afb',\n },\n apiContractClosure: {\n path: 'supabase/migrations/20260806160000_api_contract_closure.sql',\n sha256: 'e0e7aec8e03d70c60ee0d5c2b332ce73fa7b4b229725c9a9fcb0e1a1d7e8c511',\n },\n migrationHead: {\n path: 'supabase/migrations/20260807103000_data_product_consumer_facades.sql',\n sha256: 'd7fe990d487a75a8aecced5af580d27f176e74ac00f18e7fa6e6d88733152646',\n },\n },\n contractReady: true,\n snapshotRole: 'frozen-post-cutover-api-contract',\n provenanceIssue: 'tiangong-lca/database-engine#422',\n publicCoreTableCount: 9,\n publicRoutineCount: 0,\n },\n profiles: {\n 'api-contract-v1': {\n phase: 'contract',\n description: 'Frozen api RPC profile for database-engine migration head 20260807103000.',\n },\n },\n corePublicRelations: CORE_PUBLIC_RELATIONS,\n relationConsumers: DATA_API_RELATION_CONSUMERS,\n views: [],\n rpcs: DATA_API_RPC_TARGETS,\n rpcReplayClassification: DATA_API_RPC_REPLAY_CLASSIFICATION,\n cliRolePolicy: {\n anon: 'deny',\n authenticated: 'allow',\n service_role: 'deny',\n },\n retryPolicy: {\n reads:\n 'GET/HEAD and manifest-classified read RPCs permit one auth-refresh replay only after 401/403',\n mutations:\n 'no automatic transport retry; recovery must use the capability idempotency/read path',\n },\n retiredCapabilities: [\n {\n capability: 'rpc:cmd_dataset_alias_plan_guarded',\n targetSchema: 'private',\n reason:\n 'The whole-plan executor is private. Authenticated CLI execution uses the frozen alias execution preflight/gate/admit/read api capabilities.',\n },\n ],\n blockers: [],\n} as const;\n\nexport type ResolvedDataApiCapability = {\n kind: 'relation' | 'rpc';\n name: string;\n schema: 'public' | 'api';\n profile: DataApiProfile;\n role: DataApiRole;\n signature: string | null;\n};\n\nfunction isCorePublicRelation(value: string): value is CorePublicRelation {\n return (CORE_PUBLIC_RELATIONS as readonly string[]).includes(value);\n}\n\nfunction isDataApiRpc(value: string): value is DataApiRpc {\n return Object.hasOwn(DATA_API_RPC_TARGETS, value);\n}\n\nexport function resolveDataApiProfile(env: NodeJS.ProcessEnv = process.env): DataApiProfile {\n const value = env[DATA_API_PROFILE_ENV]?.trim() || 'api-contract-v1';\n if ((DATA_API_PROFILES as readonly string[]).includes(value)) {\n return value as DataApiProfile;\n }\n throw new CliError(`Unsupported ${DATA_API_PROFILE_ENV}: ${value}`, {\n code: 'DATA_API_PROFILE_INVALID',\n exitCode: 2,\n details: { supported: DATA_API_PROFILES },\n });\n}\n\nfunction assertCliRole(role: DataApiRole): void {\n if (role !== 'authenticated') {\n throw new CliError(`The CLI Data API adapter does not accept the ${role} role.`, {\n code: 'DATA_API_ROLE_FORBIDDEN',\n exitCode: 2,\n details: { role, allowed_roles: ['authenticated'] },\n });\n }\n}\n\nexport function resolveDataApiCapability(options: {\n kind: 'relation' | 'rpc';\n name: string;\n env?: NodeJS.ProcessEnv;\n profile?: DataApiProfile;\n role?: DataApiRole;\n}): ResolvedDataApiCapability {\n const profile = options.profile ?? resolveDataApiProfile(options.env);\n const role = options.role ?? 'authenticated';\n assertCliRole(role);\n\n if (options.kind === 'relation') {\n if (!isCorePublicRelation(options.name)) {\n throw new CliError(`Unmanifested Data API relation: ${options.name}`, {\n code: 'DATA_API_CAPABILITY_UNMANIFESTED',\n exitCode: 2,\n details: { kind: options.kind, name: options.name },\n });\n }\n return {\n kind: 'relation',\n name: options.name,\n schema: 'public',\n profile,\n role,\n signature: null,\n };\n }\n\n if (!isDataApiRpc(options.name)) {\n throw new CliError(`Unmanifested Data API RPC: ${options.name}`, {\n code: 'DATA_API_CAPABILITY_UNMANIFESTED',\n exitCode: 2,\n details: { kind: options.kind, name: options.name },\n });\n }\n const target = DATA_API_RPC_TARGETS[options.name];\n return {\n kind: 'rpc',\n name: options.name,\n schema: 'api',\n profile,\n role,\n signature: target.signature,\n };\n}\n\nexport function applyDataApiProfileHeaders(\n headers: HeadersInit | undefined,\n capability: ResolvedDataApiCapability,\n method = 'GET',\n): Record<string, string> {\n const resolved = new Headers(headers);\n const normalizedMethod = method.toUpperCase();\n if (normalizedMethod === 'GET' || normalizedMethod === 'HEAD') {\n resolved.set('Accept-Profile', capability.schema);\n } else {\n resolved.set('Content-Profile', capability.schema);\n }\n return Object.fromEntries(resolved.entries());\n}\n\nexport function resolveDataApiCapabilityFromUrl(options: {\n url: string;\n method?: string;\n env?: NodeJS.ProcessEnv;\n profile?: DataApiProfile;\n}): ResolvedDataApiCapability {\n const parsed = new URL(options.url);\n const marker = '/rest/v1/';\n const markerIndex = parsed.pathname.indexOf(marker);\n if (markerIndex < 0) {\n throw new CliError(`URL is not a Supabase Data API route: ${options.url}`, {\n code: 'DATA_API_URL_INVALID',\n exitCode: 2,\n });\n }\n const segments = parsed.pathname\n .slice(markerIndex + marker.length)\n .split('/')\n .filter(Boolean);\n if (segments[0] === 'rpc' && segments[1]) {\n return resolveDataApiCapability({\n kind: 'rpc',\n name: segments[1],\n env: options.env,\n profile: options.profile,\n });\n }\n if (segments[0]) {\n return resolveDataApiCapability({\n kind: 'relation',\n name: segments[0],\n env: options.env,\n profile: options.profile,\n });\n }\n throw new CliError(`Data API URL has no relation or RPC name: ${options.url}`, {\n code: 'DATA_API_URL_INVALID',\n exitCode: 2,\n });\n}\n\nexport function isDataApiUrl(url: string): boolean {\n return new URL(url).pathname.includes('/rest/v1/');\n}\n\nexport function buildDataApiUrl(\n restBaseUrl: string,\n capability: Pick<ResolvedDataApiCapability, 'kind' | 'name'>,\n): string {\n const base = restBaseUrl.replace(/\\/+$/u, '');\n return capability.kind === 'rpc'\n ? `${base}/rpc/${capability.name}`\n : `${base}/${capability.name}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"supabase-data-api-contract.js","sourceRoot":"","sources":["../../../src/lib/supabase-data-api-contract.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport { DATA_API_RPC_REPLAY_CLASSIFICATION } from './supabase-data-api-replay.js';\nexport {\n DATA_API_RPC_REPLAY_CLASSIFICATION,\n isDataApiAuthRefreshReplaySafe,\n} from './supabase-data-api-replay.js';\n\nexport const DATA_API_PROFILE_ENV = 'TIANGONG_LCA_DATA_API_PROFILE';\nexport const DATA_API_PROFILES = ['api-contract-v1'] as const;\nexport type DataApiProfile = (typeof DATA_API_PROFILES)[number];\nexport type DataApiRole = 'anon' | 'authenticated' | 'service_role';\n\nexport const CORE_PUBLIC_RELATIONS = [\n 'contacts',\n 'flowproperties',\n 'flows',\n 'ilcd',\n 'lciamethods',\n 'lifecyclemodels',\n 'processes',\n 'sources',\n 'unitgroups',\n] as const;\nexport type CorePublicRelation = (typeof CORE_PUBLIC_RELATIONS)[number];\n\nexport const DATA_API_RELATION_CONSUMERS = {\n contacts: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n flowproperties: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n flows: [\n 'src/lib/flow-read.ts',\n 'src/lib/flow-list.ts',\n 'src/lib/flow-publish-version.ts',\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n ilcd: [],\n lciamethods: [\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n lifecyclemodels: [\n 'src/lib/lifecyclemodel-bundle-save.ts',\n 'src/lib/process-dedup-review.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n processes: [\n 'src/lib/process-get.ts',\n 'src/lib/process-list.ts',\n 'src/lib/process-save-draft.ts',\n 'src/lib/process-scope-statistics.ts',\n 'src/lib/process-dedup-review.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/supabase-rest.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n sources: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/supabase-json-ordered-write.ts',\n 'src/lib/process-refresh-references.ts',\n 'src/lib/dataset-maintenance-clear-account.ts',\n ],\n unitgroups: [\n 'src/lib/dataset-save-draft-run.ts',\n 'src/lib/dataset-remote-verify.ts',\n 'src/lib/dataset-maintenance-remote.ts',\n 'src/lib/dataset-maintenance-flow-identity-capture.ts',\n 'src/lib/process-refresh-references.ts',\n ],\n} as const satisfies Record<CorePublicRelation, readonly string[]>;\n\ntype RpcTarget = {\n targetSchema: 'api';\n signature: string;\n};\n\nexport const DATA_API_RPC_TARGETS = {\n cmd_dataset_alias_execution_admit_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_admit_guarded(p_request jsonb)',\n },\n cmd_dataset_alias_execution_gate_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_alias_execution_gate_guarded(p_request_id uuid, p_preflight_token text, p_gate_name text)',\n },\n cmd_dataset_alias_execution_preflight_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_preflight_guarded(p_request jsonb)',\n },\n cmd_dataset_alias_execution_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_alias_execution_read(p_request_id uuid)',\n },\n cmd_dataset_delete: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_delete(p_table text, p_id uuid, p_version text, p_audit jsonb)',\n },\n cmd_dataset_derivative_rebuild_plan_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_derivative_rebuild_plan_guarded(p_plan jsonb)',\n },\n cmd_dataset_derivative_rebuild_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_derivative_rebuild_read(p_request_id uuid)',\n },\n cmd_dataset_derivative_rebuild_snapshot: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_derivative_rebuild_snapshot(p_table text, p_id uuid, p_version text)',\n },\n cmd_dataset_flow_identity_capture_attest_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_capture_attest_guarded(p_request jsonb)',\n },\n cmd_dataset_flow_identity_process_rewrite_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_process_rewrite_guarded(p_scope_id uuid, p_request jsonb, p_authorization jsonb)',\n },\n cmd_dataset_flow_identity_scope_finalize_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_scope_finalize_guarded(p_scope_id uuid, p_request jsonb, p_authorization jsonb)',\n },\n cmd_dataset_flow_identity_scope_lookup: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_lookup(p_request jsonb)',\n },\n cmd_dataset_flow_identity_scope_preflight_guarded: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_preflight_guarded(p_request jsonb)',\n },\n cmd_dataset_flow_identity_scope_read: {\n targetSchema: 'api',\n signature: 'api.cmd_dataset_flow_identity_scope_read(p_scope_id uuid)',\n },\n cmd_dataset_flow_identity_scope_recover_guarded: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_flow_identity_scope_recover_guarded(p_scope_id uuid, p_request jsonb)',\n },\n cmd_dataset_save_draft: {\n targetSchema: 'api',\n signature:\n 'api.cmd_dataset_save_draft(p_table text, p_id uuid, p_version text, p_json_ordered jsonb, p_model_id uuid, p_rule_verification boolean, p_audit jsonb, p_model_version text)',\n },\n} as const satisfies Record<string, RpcTarget>;\n\nexport type DataApiRpc = keyof typeof DATA_API_RPC_TARGETS;\n\nexport const DATA_API_CONTRACT = {\n schemaVersion: 'tiangong-lca-cli.data-api-contract.v1',\n databaseContract: {\n repository: 'tiangong-lca/database-engine',\n databaseCommit: '1320dcc506fe37af6b625ae30fbe0bec38cf87c6',\n migrationHead: '20260902104500',\n migrationSetGitTreeSha: '88e212220c0037cee673d0522340d3cca5e791dd',\n contractMigrations: {\n fullSchemaCutover: {\n path: 'supabase/migrations/20260805130000_full_schema_cutover.sql',\n sha256: 'd409022fb25d9313d17b0f76216ca6e4abbfce7d6c5b6e74c869314d1c7e5afb',\n },\n apiContractClosure: {\n path: 'supabase/migrations/20260806160000_api_contract_closure.sql',\n sha256: 'e0e7aec8e03d70c60ee0d5c2b332ce73fa7b4b229725c9a9fcb0e1a1d7e8c511',\n },\n processModelVersionContract: {\n path: 'supabase/migrations/20260902100000_process_model_version_contract.sql',\n sha256: '99cbaf474098281ea8c57fcef093174d0ef78a18300f133dd8cc6f9e59a4a29b',\n },\n processSaveDraftModelVersion: {\n path: 'supabase/migrations/20260902103509_add_process_model_version_to_dataset_save_draft.sql',\n sha256: 'ca93f3279673e292803bd8c477aec76b772c7246e16114808d31e64994037723',\n },\n migrationHead: {\n path: 'supabase/migrations/20260902104500_use_exact_model_version_in_review_ownership.sql',\n sha256: '538ec3001f7683b57817e4a89973ded127522ce94521720ed583de99711bbe60',\n },\n },\n contractReady: true,\n snapshotRole: 'frozen-process-model-version-contract',\n provenanceIssue: 'tiangong-lca/database-engine#589',\n publicCoreTableCount: 9,\n publicRoutineCount: 0,\n },\n profiles: {\n 'api-contract-v1': {\n phase: 'contract',\n description: 'Frozen api RPC profile for database-engine migration head 20260902104500.',\n },\n },\n corePublicRelations: CORE_PUBLIC_RELATIONS,\n relationConsumers: DATA_API_RELATION_CONSUMERS,\n views: [],\n rpcs: DATA_API_RPC_TARGETS,\n rpcReplayClassification: DATA_API_RPC_REPLAY_CLASSIFICATION,\n cliRolePolicy: {\n anon: 'deny',\n authenticated: 'allow',\n service_role: 'deny',\n },\n retryPolicy: {\n reads:\n 'GET/HEAD and manifest-classified read RPCs permit one auth-refresh replay only after 401/403',\n mutations:\n 'no automatic transport retry; recovery must use the capability idempotency/read path',\n },\n retiredCapabilities: [\n {\n capability: 'rpc:cmd_dataset_alias_plan_guarded',\n targetSchema: 'private',\n reason:\n 'The whole-plan executor is private. Authenticated CLI execution uses the frozen alias execution preflight/gate/admit/read api capabilities.',\n },\n ],\n blockers: [],\n} as const;\n\nexport type ResolvedDataApiCapability = {\n kind: 'relation' | 'rpc';\n name: string;\n schema: 'public' | 'api';\n profile: DataApiProfile;\n role: DataApiRole;\n signature: string | null;\n};\n\nfunction isCorePublicRelation(value: string): value is CorePublicRelation {\n return (CORE_PUBLIC_RELATIONS as readonly string[]).includes(value);\n}\n\nfunction isDataApiRpc(value: string): value is DataApiRpc {\n return Object.hasOwn(DATA_API_RPC_TARGETS, value);\n}\n\nexport function resolveDataApiProfile(env: NodeJS.ProcessEnv = process.env): DataApiProfile {\n const value = env[DATA_API_PROFILE_ENV]?.trim() || 'api-contract-v1';\n if ((DATA_API_PROFILES as readonly string[]).includes(value)) {\n return value as DataApiProfile;\n }\n throw new CliError(`Unsupported ${DATA_API_PROFILE_ENV}: ${value}`, {\n code: 'DATA_API_PROFILE_INVALID',\n exitCode: 2,\n details: { supported: DATA_API_PROFILES },\n });\n}\n\nfunction assertCliRole(role: DataApiRole): void {\n if (role !== 'authenticated') {\n throw new CliError(`The CLI Data API adapter does not accept the ${role} role.`, {\n code: 'DATA_API_ROLE_FORBIDDEN',\n exitCode: 2,\n details: { role, allowed_roles: ['authenticated'] },\n });\n }\n}\n\nexport function resolveDataApiCapability(options: {\n kind: 'relation' | 'rpc';\n name: string;\n env?: NodeJS.ProcessEnv;\n profile?: DataApiProfile;\n role?: DataApiRole;\n}): ResolvedDataApiCapability {\n const profile = options.profile ?? resolveDataApiProfile(options.env);\n const role = options.role ?? 'authenticated';\n assertCliRole(role);\n\n if (options.kind === 'relation') {\n if (!isCorePublicRelation(options.name)) {\n throw new CliError(`Unmanifested Data API relation: ${options.name}`, {\n code: 'DATA_API_CAPABILITY_UNMANIFESTED',\n exitCode: 2,\n details: { kind: options.kind, name: options.name },\n });\n }\n return {\n kind: 'relation',\n name: options.name,\n schema: 'public',\n profile,\n role,\n signature: null,\n };\n }\n\n if (!isDataApiRpc(options.name)) {\n throw new CliError(`Unmanifested Data API RPC: ${options.name}`, {\n code: 'DATA_API_CAPABILITY_UNMANIFESTED',\n exitCode: 2,\n details: { kind: options.kind, name: options.name },\n });\n }\n const target = DATA_API_RPC_TARGETS[options.name];\n return {\n kind: 'rpc',\n name: options.name,\n schema: 'api',\n profile,\n role,\n signature: target.signature,\n };\n}\n\nexport function applyDataApiProfileHeaders(\n headers: HeadersInit | undefined,\n capability: ResolvedDataApiCapability,\n method = 'GET',\n): Record<string, string> {\n const resolved = new Headers(headers);\n const normalizedMethod = method.toUpperCase();\n if (normalizedMethod === 'GET' || normalizedMethod === 'HEAD') {\n resolved.set('Accept-Profile', capability.schema);\n } else {\n resolved.set('Content-Profile', capability.schema);\n }\n return Object.fromEntries(resolved.entries());\n}\n\nexport function resolveDataApiCapabilityFromUrl(options: {\n url: string;\n method?: string;\n env?: NodeJS.ProcessEnv;\n profile?: DataApiProfile;\n}): ResolvedDataApiCapability {\n const parsed = new URL(options.url);\n const marker = '/rest/v1/';\n const markerIndex = parsed.pathname.indexOf(marker);\n if (markerIndex < 0) {\n throw new CliError(`URL is not a Supabase Data API route: ${options.url}`, {\n code: 'DATA_API_URL_INVALID',\n exitCode: 2,\n });\n }\n const segments = parsed.pathname\n .slice(markerIndex + marker.length)\n .split('/')\n .filter(Boolean);\n if (segments[0] === 'rpc' && segments[1]) {\n return resolveDataApiCapability({\n kind: 'rpc',\n name: segments[1],\n env: options.env,\n profile: options.profile,\n });\n }\n if (segments[0]) {\n return resolveDataApiCapability({\n kind: 'relation',\n name: segments[0],\n env: options.env,\n profile: options.profile,\n });\n }\n throw new CliError(`Data API URL has no relation or RPC name: ${options.url}`, {\n code: 'DATA_API_URL_INVALID',\n exitCode: 2,\n });\n}\n\nexport function isDataApiUrl(url: string): boolean {\n return new URL(url).pathname.includes('/rest/v1/');\n}\n\nexport function buildDataApiUrl(\n restBaseUrl: string,\n capability: Pick<ResolvedDataApiCapability, 'kind' | 'name'>,\n): string {\n const base = restBaseUrl.replace(/\\/+$/u, '');\n return capability.kind === 'rpc'\n ? `${base}/rpc/${capability.name}`\n : `${base}/${capability.name}`;\n}\n"]}
|
|
@@ -90,7 +90,9 @@ export function hasSupabaseRestRuntime(env) {
|
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
92
|
try {
|
|
93
|
-
|
|
93
|
+
// Config-free auth must not turn an otherwise local workflow into a remote
|
|
94
|
+
// publisher merely because the official Production profile is available.
|
|
95
|
+
requireSupabaseRestRuntime(env, { allowProductionDefaults: false });
|
|
94
96
|
return true;
|
|
95
97
|
}
|
|
96
98
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase-json-ordered-write.js","sourceRoot":"","sources":["../../../src/lib/supabase-json-ordered-write.ts"],"names":[],"mappings":"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","sourcesContent":["// data-api-relations: lifecyclemodels, processes, sources\n// data-api-dynamic-relation-expression: options.table\nimport { CliError } from './errors.js';\nimport {\n buildDatasetCommandTransport,\n createDatasetRecord,\n saveDraftDatasetRecord,\n type DatasetCommandTransport,\n} from './dataset-command.js';\nimport type { FetchLike } from './http.js';\nimport {\n createSupabaseDataClient,\n requireSupabaseRestRuntime,\n runSupabaseArrayQuery,\n} from './supabase-client.js';\nimport { createSupabaseDataRuntime } from './supabase-session.js';\n\ntype JsonObject = Record<string, unknown>;\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport type SupabaseJsonOrderedTable = 'lifecyclemodels' | 'processes' | 'sources';\nexport type SupabaseJsonOrderedWriteMode = 'upsert_current_version' | 'append_only_insert';\nexport type SupabaseJsonOrderedWriteOperation =\n 'insert' | 'update_existing' | 'update_after_insert_error' | 'skipped_existing';\n\nexport type SupabaseJsonOrderedWriteResult = {\n status: 'success';\n operation: SupabaseJsonOrderedWriteOperation;\n};\n\ntype VisibleRow = {\n id: string;\n version: string;\n state_code: number | null;\n};\n\ntype SupabaseDataClient = ReturnType<typeof createSupabaseDataClient>['client'];\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimToken(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction buildSelectUrl(\n restBaseUrl: string,\n table: SupabaseJsonOrderedTable,\n id: string,\n version: string,\n): string {\n const url = new URL(`${restBaseUrl.replace(/\\/+$/u, '')}/${table}`);\n url.searchParams.set('select', 'id,version,state_code');\n url.searchParams.set('id', `eq.${id}`);\n url.searchParams.set('version', `eq.${version}`);\n return url.toString();\n}\n\nfunction buildUpdateUrl(\n restBaseUrl: string,\n table: SupabaseJsonOrderedTable,\n id: string,\n version: string,\n): string {\n const url = new URL(`${restBaseUrl.replace(/\\/+$/u, '')}/${table}`);\n url.searchParams.set('id', `eq.${id}`);\n url.searchParams.set('version', `eq.${version}`);\n return url.toString();\n}\n\nfunction parseVisibleRows(payload: unknown, url: string): VisibleRow[] {\n if (!Array.isArray(payload)) {\n throw new CliError(`Supabase REST response was not a JSON array for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: payload,\n });\n }\n\n return payload.map((item, index) => {\n if (!isRecord(item)) {\n throw new CliError(`Supabase REST row ${index} was not a JSON object for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: item,\n });\n }\n\n return {\n id: trimToken(item.id),\n version: trimToken(item.version),\n state_code: typeof item.state_code === 'number' ? item.state_code : null,\n };\n });\n}\n\nasync function exactVisibleRows(options: {\n client: SupabaseDataClient;\n restBaseUrl: string;\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n}): Promise<VisibleRow[]> {\n const url = buildSelectUrl(options.restBaseUrl, options.table, options.id, options.version);\n const payload = await runSupabaseArrayQuery(\n options.client\n .from(options.table)\n .select('id,version,state_code')\n .eq('id', options.id)\n .eq('version', options.version),\n url,\n );\n return parseVisibleRows(payload, url);\n}\n\nasync function insertJsonOrderedRow(options: {\n transport: DatasetCommandTransport;\n table: SupabaseJsonOrderedTable;\n id: string;\n payload: JsonObject;\n extraData?: JsonObject;\n}): Promise<void> {\n await createDatasetRecord({\n transport: options.transport,\n table: options.table,\n id: options.id,\n payload: options.payload,\n extraData: options.extraData,\n });\n}\n\nasync function updateJsonOrderedRow(options: {\n transport: DatasetCommandTransport;\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n payload: JsonObject;\n extraData?: JsonObject;\n}): Promise<void> {\n await saveDraftDatasetRecord({\n transport: options.transport,\n table: options.table,\n id: options.id,\n version: options.version,\n payload: options.payload,\n extraData: options.extraData,\n });\n}\n\nfunction requireNonEmptyToken(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label}.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nexport function hasSupabaseRestRuntime(env: NodeJS.ProcessEnv | undefined): boolean {\n if (!env) {\n return false;\n }\n try {\n requireSupabaseRestRuntime(env);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function syncSupabaseJsonOrderedRecord(options: {\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n payload: JsonObject;\n writeMode: SupabaseJsonOrderedWriteMode;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n extraData?: JsonObject;\n}): Promise<SupabaseJsonOrderedWriteResult> {\n const id = requireNonEmptyToken(options.id, 'dataset id', 'SUPABASE_JSON_ORDERED_ID_REQUIRED');\n const version = requireNonEmptyToken(\n options.version,\n 'dataset version',\n 'SUPABASE_JSON_ORDERED_VERSION_REQUIRED',\n );\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const runtime = createSupabaseDataRuntime({\n runtime: requireSupabaseRestRuntime(options.env),\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n const commandTransport = await buildDatasetCommandTransport({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n const { client, restBaseUrl } = createSupabaseDataClient(runtime, options.fetchImpl, timeoutMs);\n\n const visibleBefore = await exactVisibleRows({\n client,\n restBaseUrl,\n table: options.table,\n id,\n version,\n });\n\n if (options.writeMode === 'append_only_insert' && visibleBefore.length > 0) {\n return {\n status: 'success',\n operation: 'skipped_existing',\n };\n }\n\n if (visibleBefore.length > 0) {\n await updateJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n version,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'update_existing',\n };\n }\n\n try {\n await insertJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'insert',\n };\n } catch (error) {\n const visibleAfter = await exactVisibleRows({\n client,\n restBaseUrl,\n table: options.table,\n id,\n version,\n });\n\n if (visibleAfter.length === 0) {\n throw error;\n }\n\n if (options.writeMode === 'append_only_insert') {\n return {\n status: 'success',\n operation: 'skipped_existing',\n };\n }\n\n await updateJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n version,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'update_after_insert_error',\n };\n }\n}\n\nexport const __testInternals = {\n buildSelectUrl,\n buildUpdateUrl,\n parseVisibleRows,\n exactVisibleRows,\n insertJsonOrderedRow,\n updateJsonOrderedRow,\n requireNonEmptyToken,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"supabase-json-ordered-write.js","sourceRoot":"","sources":["../../../src/lib/supabase-json-ordered-write.ts"],"names":[],"mappings":"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","sourcesContent":["// data-api-relations: lifecyclemodels, processes, sources\n// data-api-dynamic-relation-expression: options.table\nimport { CliError } from './errors.js';\nimport {\n buildDatasetCommandTransport,\n createDatasetRecord,\n saveDraftDatasetRecord,\n type DatasetCommandTransport,\n} from './dataset-command.js';\nimport type { FetchLike } from './http.js';\nimport {\n createSupabaseDataClient,\n requireSupabaseRestRuntime,\n runSupabaseArrayQuery,\n} from './supabase-client.js';\nimport { createSupabaseDataRuntime } from './supabase-session.js';\n\ntype JsonObject = Record<string, unknown>;\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport type SupabaseJsonOrderedTable = 'lifecyclemodels' | 'processes' | 'sources';\nexport type SupabaseJsonOrderedWriteMode = 'upsert_current_version' | 'append_only_insert';\nexport type SupabaseJsonOrderedWriteOperation =\n 'insert' | 'update_existing' | 'update_after_insert_error' | 'skipped_existing';\n\nexport type SupabaseJsonOrderedWriteResult = {\n status: 'success';\n operation: SupabaseJsonOrderedWriteOperation;\n};\n\ntype VisibleRow = {\n id: string;\n version: string;\n state_code: number | null;\n};\n\ntype SupabaseDataClient = ReturnType<typeof createSupabaseDataClient>['client'];\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimToken(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction buildSelectUrl(\n restBaseUrl: string,\n table: SupabaseJsonOrderedTable,\n id: string,\n version: string,\n): string {\n const url = new URL(`${restBaseUrl.replace(/\\/+$/u, '')}/${table}`);\n url.searchParams.set('select', 'id,version,state_code');\n url.searchParams.set('id', `eq.${id}`);\n url.searchParams.set('version', `eq.${version}`);\n return url.toString();\n}\n\nfunction buildUpdateUrl(\n restBaseUrl: string,\n table: SupabaseJsonOrderedTable,\n id: string,\n version: string,\n): string {\n const url = new URL(`${restBaseUrl.replace(/\\/+$/u, '')}/${table}`);\n url.searchParams.set('id', `eq.${id}`);\n url.searchParams.set('version', `eq.${version}`);\n return url.toString();\n}\n\nfunction parseVisibleRows(payload: unknown, url: string): VisibleRow[] {\n if (!Array.isArray(payload)) {\n throw new CliError(`Supabase REST response was not a JSON array for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: payload,\n });\n }\n\n return payload.map((item, index) => {\n if (!isRecord(item)) {\n throw new CliError(`Supabase REST row ${index} was not a JSON object for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: item,\n });\n }\n\n return {\n id: trimToken(item.id),\n version: trimToken(item.version),\n state_code: typeof item.state_code === 'number' ? item.state_code : null,\n };\n });\n}\n\nasync function exactVisibleRows(options: {\n client: SupabaseDataClient;\n restBaseUrl: string;\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n}): Promise<VisibleRow[]> {\n const url = buildSelectUrl(options.restBaseUrl, options.table, options.id, options.version);\n const payload = await runSupabaseArrayQuery(\n options.client\n .from(options.table)\n .select('id,version,state_code')\n .eq('id', options.id)\n .eq('version', options.version),\n url,\n );\n return parseVisibleRows(payload, url);\n}\n\nasync function insertJsonOrderedRow(options: {\n transport: DatasetCommandTransport;\n table: SupabaseJsonOrderedTable;\n id: string;\n payload: JsonObject;\n extraData?: JsonObject;\n}): Promise<void> {\n await createDatasetRecord({\n transport: options.transport,\n table: options.table,\n id: options.id,\n payload: options.payload,\n extraData: options.extraData,\n });\n}\n\nasync function updateJsonOrderedRow(options: {\n transport: DatasetCommandTransport;\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n payload: JsonObject;\n extraData?: JsonObject;\n}): Promise<void> {\n await saveDraftDatasetRecord({\n transport: options.transport,\n table: options.table,\n id: options.id,\n version: options.version,\n payload: options.payload,\n extraData: options.extraData,\n });\n}\n\nfunction requireNonEmptyToken(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label}.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nexport function hasSupabaseRestRuntime(env: NodeJS.ProcessEnv | undefined): boolean {\n if (!env) {\n return false;\n }\n try {\n // Config-free auth must not turn an otherwise local workflow into a remote\n // publisher merely because the official Production profile is available.\n requireSupabaseRestRuntime(env, { allowProductionDefaults: false });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function syncSupabaseJsonOrderedRecord(options: {\n table: SupabaseJsonOrderedTable;\n id: string;\n version: string;\n payload: JsonObject;\n writeMode: SupabaseJsonOrderedWriteMode;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n extraData?: JsonObject;\n}): Promise<SupabaseJsonOrderedWriteResult> {\n const id = requireNonEmptyToken(options.id, 'dataset id', 'SUPABASE_JSON_ORDERED_ID_REQUIRED');\n const version = requireNonEmptyToken(\n options.version,\n 'dataset version',\n 'SUPABASE_JSON_ORDERED_VERSION_REQUIRED',\n );\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const runtime = createSupabaseDataRuntime({\n runtime: requireSupabaseRestRuntime(options.env),\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n const commandTransport = await buildDatasetCommandTransport({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n const { client, restBaseUrl } = createSupabaseDataClient(runtime, options.fetchImpl, timeoutMs);\n\n const visibleBefore = await exactVisibleRows({\n client,\n restBaseUrl,\n table: options.table,\n id,\n version,\n });\n\n if (options.writeMode === 'append_only_insert' && visibleBefore.length > 0) {\n return {\n status: 'success',\n operation: 'skipped_existing',\n };\n }\n\n if (visibleBefore.length > 0) {\n await updateJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n version,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'update_existing',\n };\n }\n\n try {\n await insertJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'insert',\n };\n } catch (error) {\n const visibleAfter = await exactVisibleRows({\n client,\n restBaseUrl,\n table: options.table,\n id,\n version,\n });\n\n if (visibleAfter.length === 0) {\n throw error;\n }\n\n if (options.writeMode === 'append_only_insert') {\n return {\n status: 'success',\n operation: 'skipped_existing',\n };\n }\n\n await updateJsonOrderedRow({\n transport: commandTransport,\n table: options.table,\n id,\n version,\n payload: options.payload,\n extraData: options.extraData,\n });\n return {\n status: 'success',\n operation: 'update_after_insert_error',\n };\n }\n}\n\nexport const __testInternals = {\n buildSelectUrl,\n buildUpdateUrl,\n parseVisibleRows,\n exactVisibleRows,\n insertJsonOrderedRow,\n updateJsonOrderedRow,\n requireNonEmptyToken,\n};\n"]}
|
|
@@ -5,7 +5,7 @@ import { exchangeOAuthAuthorizationCode, fetchOAuthUserInfo, type OAuthPkceValue
|
|
|
5
5
|
import { type SupabaseDataRuntime, type SupabaseRestRuntime } from './supabase-client.js';
|
|
6
6
|
export type CachedSupabaseSessionRecord = {
|
|
7
7
|
schema_version: 2;
|
|
8
|
-
auth_method: 'oauth'
|
|
8
|
+
auth_method: 'oauth';
|
|
9
9
|
supabase_url: string;
|
|
10
10
|
publishable_key_fingerprint: string;
|
|
11
11
|
auth_binding_fingerprint: string;
|
|
@@ -23,13 +23,13 @@ export type ResolvedSupabaseUserSession = {
|
|
|
23
23
|
userEmail: string;
|
|
24
24
|
projectBaseUrl: string;
|
|
25
25
|
sessionFile: string | null;
|
|
26
|
-
authMethod: 'oauth' | 'access_token'
|
|
27
|
-
source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | '
|
|
26
|
+
authMethod: 'oauth' | 'access_token';
|
|
27
|
+
source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | 'access_token';
|
|
28
28
|
};
|
|
29
29
|
type RuntimeIdentity = {
|
|
30
30
|
projectBaseUrl: string;
|
|
31
31
|
publishableKeyFingerprint: string;
|
|
32
|
-
authMethod: 'oauth' | 'access_token'
|
|
32
|
+
authMethod: 'oauth' | 'access_token';
|
|
33
33
|
authBindingFingerprint: string;
|
|
34
34
|
sessionFilePath: string | null;
|
|
35
35
|
memoKey: string;
|
|
@@ -61,18 +61,10 @@ declare function memoizeRecord(runtime: RuntimeIdentity, record: CachedSupabaseS
|
|
|
61
61
|
declare function dropMemoizedRecord(runtime: RuntimeIdentity): void;
|
|
62
62
|
declare function withSessionOperationLock<T>(memoKey: string, task: () => Promise<T>): Promise<T>;
|
|
63
63
|
declare function createSupabaseAuthClient(runtime: RuntimeIdentity, publishableKey: string, fetchImpl: FetchLike, timeoutMs: number): import("@supabase/supabase-js").SupabaseClient<any, "public", "public", any, any>;
|
|
64
|
-
declare function signInWithUserApiKey(options: {
|
|
65
|
-
runtime: SupabaseRestRuntime;
|
|
66
|
-
runtimeIdentity: RuntimeIdentity;
|
|
67
|
-
fetchImpl: FetchLike;
|
|
68
|
-
timeoutMs: number;
|
|
69
|
-
now: Date;
|
|
70
|
-
}): Promise<CachedSupabaseSessionRecord>;
|
|
71
64
|
declare function refreshWithRefreshToken(options: {
|
|
72
65
|
runtime: SupabaseRestRuntime;
|
|
73
66
|
runtimeIdentity: RuntimeIdentity;
|
|
74
67
|
refreshToken: string;
|
|
75
|
-
userEmail: string;
|
|
76
68
|
fetchImpl: FetchLike;
|
|
77
69
|
timeoutMs: number;
|
|
78
70
|
now: Date;
|
|
@@ -109,7 +101,7 @@ export type AuthStatusReceipt = {
|
|
|
109
101
|
schemaVersion: 'tiangong.cli-auth-status.v1';
|
|
110
102
|
status: 'ready' | 'login-required';
|
|
111
103
|
authMethod: ResolvedSupabaseUserSession['authMethod'];
|
|
112
|
-
sessionState: 'fresh' | 'refresh-required' | 'memory-only' | '
|
|
104
|
+
sessionState: 'fresh' | 'refresh-required' | 'memory-only' | 'missing';
|
|
113
105
|
sessionCache: 'private-file' | 'disabled' | 'memory-only';
|
|
114
106
|
expiresAt: number | null;
|
|
115
107
|
grantedScopes: string[];
|
|
@@ -163,7 +155,6 @@ export declare const __testInternals: {
|
|
|
163
155
|
resolveDefaultSessionFilePath: typeof resolveDefaultSessionFilePath;
|
|
164
156
|
resolveAndPersistSession: typeof resolveAndPersistSession;
|
|
165
157
|
resolveSessionFilePath: typeof resolveSessionFilePath;
|
|
166
|
-
signInWithUserApiKey: typeof signInWithUserApiKey;
|
|
167
158
|
withSessionOperationLock: typeof withSessionOperationLock;
|
|
168
159
|
writeCachedSessionRecord: typeof writeCachedSessionRecord;
|
|
169
160
|
};
|
|
@@ -7,7 +7,7 @@ import { openSystemBrowser, receiveOAuthLoopbackCallback, SYSTEM_BROWSER_OPTIONS
|
|
|
7
7
|
import { buildOAuthAuthorizationUrl, createOAuthPkceValues, DEFAULT_OAUTH_SCOPES, exchangeOAuthAuthorizationCode, fetchOAuthUserInfo, refreshOAuthTokens, } from './oauth-pkce.js';
|
|
8
8
|
import { withStateFileLock } from './state-lock.js';
|
|
9
9
|
import { createSupabaseFetch, deriveSupabaseProjectBaseUrl, } from './supabase-client.js';
|
|
10
|
-
import { fingerprintSecret
|
|
10
|
+
import { fingerprintSecret } from './credential-safety.js';
|
|
11
11
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
12
12
|
const SESSION_REFRESH_WINDOW_SECONDS = 300;
|
|
13
13
|
const SESSION_MEMORY_CACHE = new Map();
|
|
@@ -35,19 +35,13 @@ function parseCachedSessionRecord(value) {
|
|
|
35
35
|
if (!isRecord(value)) {
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
|
-
if (value.schema_version !==
|
|
38
|
+
if (value.schema_version !== 2) {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
const supabaseUrl = trimToken(value.supabase_url);
|
|
42
42
|
const publishableKeyFingerprint = trimToken(value.publishable_key_fingerprint);
|
|
43
|
-
const authMethod = value.
|
|
44
|
-
|
|
45
|
-
: value.auth_method === 'oauth' || value.auth_method === 'legacy_user_api_key'
|
|
46
|
-
? value.auth_method
|
|
47
|
-
: null;
|
|
48
|
-
const authBindingFingerprint = value.schema_version === 1
|
|
49
|
-
? trimToken(value.user_api_key_fingerprint)
|
|
50
|
-
: trimToken(value.auth_binding_fingerprint);
|
|
43
|
+
const authMethod = value.auth_method === 'oauth' ? 'oauth' : null;
|
|
44
|
+
const authBindingFingerprint = trimToken(value.auth_binding_fingerprint);
|
|
51
45
|
const userEmail = trimToken(value.user_email);
|
|
52
46
|
const accessToken = trimToken(value.access_token);
|
|
53
47
|
const refreshToken = trimToken(value.refresh_token);
|
|
@@ -57,12 +51,10 @@ function parseCachedSessionRecord(value) {
|
|
|
57
51
|
: value.expires_at === null
|
|
58
52
|
? null
|
|
59
53
|
: NaN;
|
|
60
|
-
const grantedScopes = value.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) => left.localeCompare(right))
|
|
65
|
-
: null;
|
|
54
|
+
const grantedScopes = Array.isArray(value.granted_scopes) &&
|
|
55
|
+
value.granted_scopes.every((scope) => typeof scope === 'string' && scope.trim())
|
|
56
|
+
? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) => left.localeCompare(right))
|
|
57
|
+
: null;
|
|
66
58
|
if (!supabaseUrl ||
|
|
67
59
|
!publishableKeyFingerprint ||
|
|
68
60
|
!authMethod ||
|
|
@@ -123,9 +115,7 @@ function buildRuntimeIdentity(runtime) {
|
|
|
123
115
|
const publishableKeyFingerprint = fingerprintSecret(runtime.publishableKey);
|
|
124
116
|
const authBindingFingerprint = runtime.authMode === 'oauth'
|
|
125
117
|
? fingerprintSecret(`oauth-client:${runtime.oauthClientId}`)
|
|
126
|
-
: runtime.
|
|
127
|
-
? fingerprintSecret(runtime.accessToken)
|
|
128
|
-
: fingerprintUserApiKey(runtime.userApiKey);
|
|
118
|
+
: fingerprintSecret(runtime.accessToken);
|
|
129
119
|
const sessionFilePath = resolveSessionFilePath(runtime);
|
|
130
120
|
return {
|
|
131
121
|
projectBaseUrl,
|
|
@@ -164,7 +154,7 @@ function buildCachedSessionRecord(options) {
|
|
|
164
154
|
}
|
|
165
155
|
return {
|
|
166
156
|
schema_version: 2,
|
|
167
|
-
auth_method:
|
|
157
|
+
auth_method: 'oauth',
|
|
168
158
|
supabase_url: options.runtime.projectBaseUrl,
|
|
169
159
|
publishable_key_fingerprint: options.runtime.publishableKeyFingerprint,
|
|
170
160
|
auth_binding_fingerprint: options.runtime.authBindingFingerprint,
|
|
@@ -267,76 +257,35 @@ function createSupabaseAuthClient(runtime, publishableKey, fetchImpl, timeoutMs)
|
|
|
267
257
|
},
|
|
268
258
|
});
|
|
269
259
|
}
|
|
270
|
-
async function signInWithUserApiKey(options) {
|
|
271
|
-
const credentials = requireUserApiKeyCredentials(options.runtime.userApiKey);
|
|
272
|
-
const authClient = createSupabaseAuthClient(options.runtimeIdentity, options.runtime.publishableKey, options.fetchImpl, options.timeoutMs);
|
|
273
|
-
const { data, error } = await authClient.auth.signInWithPassword({
|
|
274
|
-
email: credentials.email,
|
|
275
|
-
password: credentials.password,
|
|
276
|
-
});
|
|
277
|
-
if (error || !data.session) {
|
|
278
|
-
throw new CliError('Failed to sign in with TIANGONG_LCA_API_KEY.', {
|
|
279
|
-
code: 'SUPABASE_AUTH_SIGN_IN_FAILED',
|
|
280
|
-
exitCode: 1,
|
|
281
|
-
details: error?.message ?? 'Supabase auth session missing from sign-in response.',
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
return buildCachedSessionRecord({
|
|
285
|
-
runtime: options.runtimeIdentity,
|
|
286
|
-
session: data.session,
|
|
287
|
-
userEmail: trimToken(data.user?.email) || credentials.email,
|
|
288
|
-
grantedScopes: [],
|
|
289
|
-
now: options.now,
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
260
|
async function refreshWithRefreshToken(options) {
|
|
293
261
|
const normalizedRefreshToken = trimToken(options.refreshToken);
|
|
294
262
|
if (!normalizedRefreshToken) {
|
|
295
263
|
return null;
|
|
296
264
|
}
|
|
297
265
|
try {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
timeoutMs: options.timeoutMs,
|
|
311
|
-
});
|
|
312
|
-
return buildCachedSessionRecord({
|
|
313
|
-
runtime: options.runtimeIdentity,
|
|
314
|
-
session: {
|
|
315
|
-
access_token: tokens.accessToken,
|
|
316
|
-
refresh_token: tokens.refreshToken,
|
|
317
|
-
expires_at: undefined,
|
|
318
|
-
expires_in: tokens.expiresIn,
|
|
319
|
-
},
|
|
320
|
-
userEmail: userInfo.email,
|
|
321
|
-
grantedScopes: tokens.scope,
|
|
322
|
-
now: options.now,
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
if (options.runtime.authMode !== 'legacy_user_api_key') {
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
const authClient = createSupabaseAuthClient(options.runtimeIdentity, options.runtime.publishableKey, options.fetchImpl, options.timeoutMs);
|
|
329
|
-
const { data, error } = await authClient.auth.refreshSession({
|
|
330
|
-
refresh_token: normalizedRefreshToken,
|
|
266
|
+
const tokens = await refreshOAuthTokens({
|
|
267
|
+
projectBaseUrl: options.runtimeIdentity.projectBaseUrl,
|
|
268
|
+
clientId: options.runtime.oauthClientId,
|
|
269
|
+
refreshToken: normalizedRefreshToken,
|
|
270
|
+
fetchImpl: options.fetchImpl,
|
|
271
|
+
timeoutMs: options.timeoutMs,
|
|
272
|
+
});
|
|
273
|
+
const userInfo = await fetchOAuthUserInfo({
|
|
274
|
+
projectBaseUrl: options.runtimeIdentity.projectBaseUrl,
|
|
275
|
+
accessToken: tokens.accessToken,
|
|
276
|
+
fetchImpl: options.fetchImpl,
|
|
277
|
+
timeoutMs: options.timeoutMs,
|
|
331
278
|
});
|
|
332
|
-
if (error || !data.session) {
|
|
333
|
-
return null;
|
|
334
|
-
}
|
|
335
279
|
return buildCachedSessionRecord({
|
|
336
280
|
runtime: options.runtimeIdentity,
|
|
337
|
-
session:
|
|
338
|
-
|
|
339
|
-
|
|
281
|
+
session: {
|
|
282
|
+
access_token: tokens.accessToken,
|
|
283
|
+
refresh_token: tokens.refreshToken,
|
|
284
|
+
expires_at: undefined,
|
|
285
|
+
expires_in: tokens.expiresIn,
|
|
286
|
+
},
|
|
287
|
+
userEmail: userInfo.email,
|
|
288
|
+
grantedScopes: tokens.scope,
|
|
340
289
|
now: options.now,
|
|
341
290
|
});
|
|
342
291
|
}
|
|
@@ -417,7 +366,6 @@ async function resolveAndPersistSession(options) {
|
|
|
417
366
|
runtime,
|
|
418
367
|
runtimeIdentity,
|
|
419
368
|
refreshToken: refreshCandidate.refresh_token,
|
|
420
|
-
userEmail: refreshCandidate.user_email,
|
|
421
369
|
fetchImpl: options.fetchImpl,
|
|
422
370
|
timeoutMs: options.timeoutMs,
|
|
423
371
|
now: options.now,
|
|
@@ -431,25 +379,11 @@ async function resolveAndPersistSession(options) {
|
|
|
431
379
|
}
|
|
432
380
|
}
|
|
433
381
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
exitCode: 1,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
const signedIn = await signInWithUserApiKey({
|
|
442
|
-
runtime,
|
|
443
|
-
runtimeIdentity,
|
|
444
|
-
fetchImpl: options.fetchImpl,
|
|
445
|
-
timeoutMs: options.timeoutMs,
|
|
446
|
-
now: options.now,
|
|
382
|
+
dropMemoizedRecord(runtimeIdentity);
|
|
383
|
+
throw new CliError('No usable OAuth session is available. Run `tiangong-lca auth login` in a trusted terminal.', {
|
|
384
|
+
code: 'SUPABASE_OAUTH_LOGIN_REQUIRED',
|
|
385
|
+
exitCode: 1,
|
|
447
386
|
});
|
|
448
|
-
if (runtimeIdentity.sessionFilePath) {
|
|
449
|
-
writeCachedSessionRecord(runtimeIdentity.sessionFilePath, signedIn);
|
|
450
|
-
}
|
|
451
|
-
memoizeRecord(runtimeIdentity, signedIn);
|
|
452
|
-
return toResolvedSession(signedIn, runtimeIdentity, 'legacy_signin');
|
|
453
387
|
}
|
|
454
388
|
export async function resolveSupabaseUserSession(options) {
|
|
455
389
|
const runtimeIdentity = buildRuntimeIdentity(options.runtime);
|
|
@@ -517,18 +451,6 @@ export function inspectSupabaseAuthStatus(options) {
|
|
|
517
451
|
onlineVerified: false,
|
|
518
452
|
};
|
|
519
453
|
}
|
|
520
|
-
if (options.runtime.authMode === 'legacy_user_api_key') {
|
|
521
|
-
return {
|
|
522
|
-
schemaVersion: 'tiangong.cli-auth-status.v1',
|
|
523
|
-
status: 'ready',
|
|
524
|
-
authMethod: 'legacy_user_api_key',
|
|
525
|
-
sessionState: 'transition-only',
|
|
526
|
-
sessionCache: runtimeIdentity.sessionFilePath ? 'private-file' : 'disabled',
|
|
527
|
-
expiresAt: null,
|
|
528
|
-
grantedScopes: [],
|
|
529
|
-
onlineVerified: false,
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
454
|
const memoized = getMemoizedRecord(runtimeIdentity);
|
|
533
455
|
const cached = memoized && recordMatchesRuntime(memoized, runtimeIdentity)
|
|
534
456
|
? memoized
|
|
@@ -711,7 +633,6 @@ export const __testInternals = {
|
|
|
711
633
|
resolveDefaultSessionFilePath,
|
|
712
634
|
resolveAndPersistSession,
|
|
713
635
|
resolveSessionFilePath,
|
|
714
|
-
signInWithUserApiKey,
|
|
715
636
|
withSessionOperationLock,
|
|
716
637
|
writeCachedSessionRecord,
|
|
717
638
|
};
|