@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.
Files changed (46) hide show
  1. package/README.md +21 -22
  2. package/dist/src/cli.js +46 -48
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/auth-identity-receipt.d.ts +1 -2
  5. package/dist/src/lib/auth-identity-receipt.js +3 -20
  6. package/dist/src/lib/auth-identity-receipt.js.map +1 -1
  7. package/dist/src/lib/credential-safety.d.ts +7 -0
  8. package/dist/src/lib/credential-safety.js +28 -0
  9. package/dist/src/lib/credential-safety.js.map +1 -0
  10. package/dist/src/lib/dataset-command.d.ts +2 -0
  11. package/dist/src/lib/dataset-command.js +20 -0
  12. package/dist/src/lib/dataset-command.js.map +1 -1
  13. package/dist/src/lib/dataset-save-draft-run.js +3 -1
  14. package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
  15. package/dist/src/lib/env.d.ts +9 -2
  16. package/dist/src/lib/env.js +83 -24
  17. package/dist/src/lib/env.js.map +1 -1
  18. package/dist/src/lib/flow-publish-reviewed-data.js +1 -1
  19. package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
  20. package/dist/src/lib/lifecyclemodel-resulting-process.js +5 -7
  21. package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
  22. package/dist/src/lib/process-refresh-references.js +1 -1
  23. package/dist/src/lib/process-refresh-references.js.map +1 -1
  24. package/dist/src/lib/process-save-draft.d.ts +1 -0
  25. package/dist/src/lib/process-save-draft.js +8 -0
  26. package/dist/src/lib/process-save-draft.js.map +1 -1
  27. package/dist/src/lib/process-scope-statistics.js +1 -1
  28. package/dist/src/lib/process-scope-statistics.js.map +1 -1
  29. package/dist/src/lib/publish.d.ts +7 -0
  30. package/dist/src/lib/publish.js +111 -7
  31. package/dist/src/lib/publish.js.map +1 -1
  32. package/dist/src/lib/supabase-client.d.ts +4 -4
  33. package/dist/src/lib/supabase-client.js +16 -16
  34. package/dist/src/lib/supabase-client.js.map +1 -1
  35. package/dist/src/lib/supabase-data-api-contract.d.ts +18 -10
  36. package/dist/src/lib/supabase-data-api-contract.js +17 -9
  37. package/dist/src/lib/supabase-data-api-contract.js.map +1 -1
  38. package/dist/src/lib/supabase-json-ordered-write.js +3 -1
  39. package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
  40. package/dist/src/lib/supabase-session.d.ts +5 -14
  41. package/dist/src/lib/supabase-session.js +34 -113
  42. package/dist/src/lib/supabase-session.js.map +1 -1
  43. package/package.json +1 -2
  44. package/dist/src/lib/user-api-key.d.ts +0 -16
  45. package/dist/src/lib/user-api-key.js +0 -75
  46. package/dist/src/lib/user-api-key.js.map +0 -1
@@ -4,7 +4,7 @@ import { type ResolvedSupabaseUserSession } from './supabase-session.js';
4
4
  export declare const AUTH_IDENTITY_RECEIPT_SCHEMA: 'tiangong-lca.auth-identity-receipt.v1';
5
5
  export declare const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2147483647;
6
6
  declare const CLI_PACKAGE_NAME: '@tiangong-lca/cli';
7
- declare const SESSION_SOURCES: readonly ['memory', 'cache', 'refresh', 'oauth_login', 'legacy_signin', 'access_token'];
7
+ declare const SESSION_SOURCES: readonly ['memory', 'cache', 'refresh', 'oauth_login', 'access_token'];
8
8
  declare const CACHE_MODES: readonly ['disabled', 'custom-file', 'platform-default'];
9
9
  type SessionSource = (typeof SESSION_SOURCES)[number];
10
10
  type CacheMode = (typeof CACHE_MODES)[number];
@@ -91,7 +91,6 @@ declare function assertSessionBinding(options: {
91
91
  runtime: SupabaseRestRuntime;
92
92
  session: ResolvedSupabaseUserSession;
93
93
  projectBaseUrl: string;
94
- credentialEmail: string | null;
95
94
  now: Date;
96
95
  }): void;
97
96
  declare function currentUserFailureStatus(error: unknown): number | null;
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { CliError } from './errors.js';
4
4
  import { buildSupabaseAuthHeaders, deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
5
5
  import { resolveSupabaseUserSession, } from './supabase-session.js';
6
- import { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';
6
+ import { redactEmail } from './credential-safety.js';
7
7
  export const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1';
8
8
  export const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;
9
9
  const CLI_PACKAGE_NAME = '@tiangong-lca/cli';
@@ -14,14 +14,7 @@ const SESSION_REFRESH_WINDOW_SECONDS = 300;
14
14
  const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
15
15
  const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
16
16
  const EMAIL_PATTERN = /^[^@\s]+@[^@\s]+\.[^@\s]+$/u;
17
- const SESSION_SOURCES = [
18
- 'memory',
19
- 'cache',
20
- 'refresh',
21
- 'oauth_login',
22
- 'legacy_signin',
23
- 'access_token',
24
- ];
17
+ const SESSION_SOURCES = ['memory', 'cache', 'refresh', 'oauth_login', 'access_token'];
25
18
  const CACHE_MODES = ['disabled', 'custom-file', 'platform-default'];
26
19
  class ResponseBodyTooLargeError extends Error {
27
20
  constructor() {
@@ -177,7 +170,6 @@ function sessionExpiresAtUtc(expiresAt) {
177
170
  function assertSessionBinding(options) {
178
171
  const { runtime, session } = options;
179
172
  const sessionEmail = normalizeEmail(session.userEmail);
180
- const credentialEmail = options.credentialEmail ? normalizeEmail(options.credentialEmail) : null;
181
173
  const accessToken = token(session.accessToken);
182
174
  const source = session.source;
183
175
  const expectedMode = cacheMode(runtime);
@@ -197,7 +189,6 @@ function assertSessionBinding(options) {
197
189
  session.authMethod !== runtime.authMode ||
198
190
  session.projectBaseUrl !== options.projectBaseUrl ||
199
191
  !sessionEmail ||
200
- (credentialEmail !== null && sessionEmail !== credentialEmail) ||
201
192
  !SESSION_SOURCES.includes(session.source) ||
202
193
  !cachePathMatches ||
203
194
  !cacheSourceFresh ||
@@ -493,9 +484,6 @@ export async function runAuthIdentityReceipt(options) {
493
484
  if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {
494
485
  return identityError('Authenticated project does not match --expected-project-ref.', 'AUTH_IDENTITY_PROJECT_MISMATCH', { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } });
495
486
  }
496
- const credentialEmail = runtime.authMode === 'legacy_user_api_key'
497
- ? requireUserApiKeyCredentials(runtime.userApiKey).email
498
- : null;
499
487
  let session = await resolveBoundSession({
500
488
  runtime,
501
489
  fetchImpl: options.fetchImpl,
@@ -507,7 +495,6 @@ export async function runAuthIdentityReceipt(options) {
507
495
  runtime,
508
496
  session,
509
497
  projectBaseUrl,
510
- credentialEmail,
511
498
  now,
512
499
  });
513
500
  let currentUser;
@@ -537,7 +524,6 @@ export async function runAuthIdentityReceipt(options) {
537
524
  runtime,
538
525
  session,
539
526
  projectBaseUrl,
540
- credentialEmail,
541
527
  now,
542
528
  });
543
529
  currentUser = await fetchCurrentUser({
@@ -549,10 +535,7 @@ export async function runAuthIdentityReceipt(options) {
549
535
  });
550
536
  }
551
537
  const sessionEmail = normalizeEmail(session.userEmail);
552
- const normalizedCredentialEmail = credentialEmail ? normalizeEmail(credentialEmail) : null;
553
- if (!sessionEmail ||
554
- currentUser.email !== sessionEmail ||
555
- (normalizedCredentialEmail !== null && currentUser.email !== normalizedCredentialEmail)) {
538
+ if (!sessionEmail || currentUser.email !== sessionEmail) {
556
539
  return identityError('Server-verified current user does not match the resolved session identity.', 'AUTH_IDENTITY_SESSION_MISMATCH');
557
540
  }
558
541
  if (expectedUserId !== null && expectedUserId !== currentUser.userId) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth-identity-receipt.js","sourceRoot":"","sources":["../../../src/lib/auth-identity-receipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,0BAA0B,GAE3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,GAE3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,CAAC,MAAM,4BAA4B,GAAG,uCAAgD,CAAC;AAC7F,MAAM,CAAC,MAAM,4BAA4B,GAAG,aAAa,CAAC;AAE1D,MAAM,gBAAgB,GAAG,mBAA4B,CAAC;AACtD,MAAM,iBAAiB,GAAG,eAAwB,CAAC;AACnD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AACrC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAC3C,MAAM,cAAc,GAAG,iBAAiB,CAAC;AACzC,MAAM,YAAY,GAAG,iEAAiE,CAAC;AACvF,MAAM,aAAa,GAAG,6BAA6B,CAAC;AACpD,MAAM,eAAe,GAAG;IACtB,QAAQ;IACR,OAAO;IACP,SAAS;IACT,aAAa;IACb,eAAe;IACf,cAAc;CACN,CAAC;AACX,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,kBAAkB,CAAU,CAAC;AAM7E,MAAM,yBAA0B,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAgED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACf,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACpD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;SAC9C,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,UAAU,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IACvD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,aAAa,CACpB,OAAe,EACf,IAAY,EACZ,OAAO,GAA6C,EAAE;IAEtD,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE;QAC1B,IAAI;QACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;KACvE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,OAAO,aAAa,CAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC,EAAE,KAAa;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,aAAa,CAClB,GAAG,KAAK,4CAA4C,EACpD,mCAAmC,EACnC;YACE,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;SAC3B,CACF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAgC;IAC/D,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IACrE,IAAI,UAAU,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO,aAAa,CAClB,wDAAwD,EACxD,mCAAmC,EACnC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,CAC3D,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,MAAM,UAAU,GAAG,KAAK,IAAI,kBAAkB,CAAC;IAC/C,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC;QAC7B,UAAU,IAAI,CAAC;QACf,UAAU,GAAG,4BAA4B,EACzC,CAAC;QACD,OAAO,aAAa,CAClB,0DAA0D,4BAA4B,GAAG,EACzF,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;AACjF,CAAC;AAED,SAAS,wBAAwB,CAC/B,cAAuB;IAEvB,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,cAAc,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;YACzB,GAAG,CAAC,MAAM,KAAK,UAAU;YACzB,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,IAAI;YACR,CAAC,UAAU;YACX,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;YACxB,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EACjC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,cAAsB;IACnD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,aAAa,CAClB,8DAA8D,EAC9D,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC;AAC7B,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAkB;IAIhD,IAAI,cAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,cAAc,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAClB,uEAAuE,EACvE,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACzD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,SAAS,CAAC,OAA4B;IAC7C,IAAI,OAAO,CAAC,QAAQ,KAAK,cAAc,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACvE,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAClE,CAAC;AAED,SAAS,mBAAmB,CAAC,SAAwB;IACnD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,aAAa,CAClB,oDAAoD,EACpD,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACtC,OAAO,aAAa,CAClB,oDAAoD,EACpD,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,oBAAoB,CAAC,OAM7B;IACC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAgB,CAAC;IACxC,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,MAAM,gBAAgB,GACpB,YAAY,KAAK,UAAU;QACzB,CAAC,CAAC,WAAW,KAAK,IAAI;QACtB,CAAC,CAAC,YAAY,KAAK,aAAa;YAC9B,CAAC,CAAC,WAAW,KAAK,iBAAiB;YACnC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC;IAC7B,MAAM,gBAAgB,GACpB,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,CAAC,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ;YACpC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;YAClC,OAAO,CAAC,SAAS;gBACf,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,8BAA8B,CAAC,CAAC;IAEjF,IACE,CAAC,WAAW;QACZ,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,QAAQ;QACvC,OAAO,CAAC,cAAc,KAAK,OAAO,CAAC,cAAc;QACjD,CAAC,YAAY;QACb,CAAC,eAAe,KAAK,IAAI,IAAI,YAAY,KAAK,eAAe,CAAC;QAC9D,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,CAAC,gBAAgB;QACjB,CAAC,gBAAgB;QACjB,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAC7D,CAAC;QACD,aAAa,CACX,4FAA4F,EAC5F,gCAAgC,CACjC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,OAOlC;IACC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,kBAAkB,CAAC;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,SAAS,GACb,KAAK,YAAY,QAAQ;YACvB,CAAC,CAAC,KAAK,CAAC,IAAI;YACZ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;gBACjD,CAAC,CAAC,KAAK,CAAC,IAAI;gBACZ,CAAC,CAAC,4BAA4B,CAAC;QACrC,OAAO,aAAa,CAClB,mDAAmD,EACnD,8BAA8B,EAC9B,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IACE,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAC5B,KAAK,CAAC,IAAI,KAAK,qCAAqC;QACpD,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QACxB,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ;QACxC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACvC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED,SAAS,qBAAqB,CAAC,QAE9B;IACC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,QAItC;IACC,MAAM,aAAa,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,GAAG,kBAAkB,EAAE,CAAC;QACjE,MAAM,IAAI,yBAAyB,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,kBAAkB,EAAE,CAAC;YACzD,MAAM,IAAI,yBAAyB,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM;YACR,CAAC;YACD,aAAa,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;YACxC,IAAI,aAAa,GAAG,kBAAkB,EAAE,CAAC;gBACvC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC5C,MAAM,IAAI,yBAAyB,EAAE,CAAC;YACxC,CAAC;YACD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAM/B;IACC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAC5D,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;YACtC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,wBAAwB,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC;YAC9E,QAAQ,EAAE,OAAO;YACjB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,aAAa,CAClB,0EAA0E,EAC1E,qCAAqC,EACrC;YACE,OAAO,EAAE;gBACP,QAAQ,EAAE,iBAAiB;gBAC3B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK;aAC1D;SACF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,aAAa,CAClB,mDAAmD,QAAQ,CAAC,MAAM,GAAG,EACrE,qCAAqC,EACrC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC9E,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,OAAO,aAAa,CAClB,mEAAmE,EACnE,mCAAmC,EACnC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,yBAAyB,EAAE,CAAC;YAC/C,OAAO,aAAa,CAClB,yEAAyE,EACzE,kCAAkC,EAClC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAClB,wDAAwD,EACxD,qCAAqC,EACrC;YACE,OAAO,EAAE;gBACP,QAAQ,EAAE,iBAAiB;gBAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK;aAC1D;SACF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAClB,yDAAyD,EACzD,mCAAmC,EACnC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC9C,OAAO,aAAa,CAClB,mEAAmE,EACnE,+BAA+B,EAC/B,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAClB,2EAA2E,EAC3E,gCAAgC,EAChC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,OAAO,UAAU,CAAC;QAChB,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,UAAU;QACvB,QAAQ,EAAE,OAAO;QACjB,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,CAAC;KACpD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,OAI5B;IACC,OAAO,UAAU,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC,UAAU;QAC/B,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,aAAa,EAAE,OAAO,CAAC,YAAY;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAiB,EAAE,QAA2B;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,CACL,MAAM,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAmB,KAAc,EAAE,MAAoB;IACrE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAU,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AAC7D,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,0CAA0C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,YAAY,CAAC,OAA4B;IAChD,MAAM,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAChB,CAAC,YAAY,CAAC,KAAK,EAAE;YACnB,YAAY;YACZ,UAAU;YACV,iBAAiB;YACjB,KAAK;YACL,UAAU;YACV,WAAW;YACX,SAAS;YACT,sBAAsB;YACtB,mBAAmB;YACnB,QAAQ;YACR,SAAS;YACT,QAAQ;SACT,CAAC,EACF,CAAC;QACD,OAAO,cAAc,CAAC,gDAAgD,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACpC,MAAM,aAAa,GACjB,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,gBAAgB,KAAK,QAAQ;QAC/D,CAAC,CAAC,wBAAwB,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC;IACX,IACE,KAAK,CAAC,MAAM,KAAK,4BAA4B;QAC7C,KAAK,CAAC,MAAM,KAAK,QAAQ;QACzB,KAAK,CAAC,SAAS,KAAK,mBAAmB;QACvC,KAAK,CAAC,iBAAiB,KAAK,WAAW;QACvC,CAAC,kBAAkB,CAAC,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,QAAQ,CAAC,GAAG,CAAC;QACd,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;QACvD,GAAG,CAAC,YAAY,KAAK,gBAAgB;QACrC,CAAC,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC;QACtC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClB,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAC3D,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC;QACtC,CAAC,aAAa;QACd,aAAa,CAAC,UAAU,KAAK,OAAO,CAAC,WAAW;QAChD,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClC,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC;QACtC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClB,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;QAClF,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;QACzC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC;QACzC,OAAO,OAAO,CAAC,YAAY,KAAK,SAAS;QACzC,CAAC,CAAC,OAAO,CAAC,cAAc,KAAK,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChF,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC,cAAc,KAAK,QAAQ;QAC3C,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC7C,OAAO,QAAQ,CAAC,eAAe,KAAK,QAAQ;QAC5C,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9C,QAAQ,CAAC,cAAc,KAAK,kBAAkB,CAAC,OAAO,CAAC,WAAqB,CAAC;QAC7E,QAAQ,CAAC,eAAe;YACtB,mBAAmB,CAAC;gBAClB,UAAU,EAAE,OAAO,CAAC,WAAqB;gBACzC,MAAM,EAAE,QAAQ,CAAC,OAAiB;gBAClC,YAAY,EAAE,QAAQ,CAAC,aAAuB;aAC/C,CAAC;QACJ,CAAC,QAAQ,CAAC,UAAU,CAAC;QACrB,CAAC,YAAY,CAAC,UAAU,EAAE;YACxB,sBAAsB;YACtB,kBAAkB;YAClB,MAAM;YACN,QAAQ;YACR,oBAAoB;YACpB,iBAAiB;YACjB,gBAAgB;SACjB,CAAC;QACF,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,cAAc,CAAU,CAAC;QAC3E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAyB,CAAC;QACzD,CAAC,CACC,UAAU,CAAC,oBAAoB,KAAK,IAAI,IAAI,gBAAgB,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAC9F;QACD,CAAC,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,IAAI,eAAe,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACvF,CAAC,CAAC,UAAU,CAAC,kBAAkB,KAAK,IAAI,IAAI,UAAU,CAAC,kBAAkB,KAAK,IAAI,CAAC;QACnF,CAAC,CAAC,UAAU,CAAC,cAAc,KAAK,IAAI,IAAI,UAAU,CAAC,cAAc,KAAK,IAAI,CAAC;QAC3E,UAAU,CAAC,MAAM,KAAK,IAAI;QAC1B,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,KAAK,IAAI,CAAC;QACvF,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,KAAK,IAAI,CAAC;QAC/E,UAAU,CAAC,eAAe;YACxB,MAAM,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI,CAAC;gBAC9C,MAAM,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,CAAC;QAChD,UAAU,CAAC,IAAI;YACb,CAAC,UAAU,CAAC,eAAe,KAAK,CAAC;gBAC/B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,UAAU,CAAC,eAAe,KAAK,CAAC;oBAChC,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,SAAS,CAAC;QAClB,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI;YACvC,UAAU,CAAC,oBAAoB,KAAK,OAAO,CAAC,WAAW,CAAC;QAC1D,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,IAAI,UAAU,CAAC,gBAAgB,KAAK,QAAQ,CAAC,OAAO,CAAC;QAC1F,OAAO,KAAK,CAAC,oBAAoB,KAAK,QAAQ;QAC9C,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAChD,CAAC;QACD,OAAO,cAAc,CAAC,iDAAiD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,OAAO,GAAG,KAA4B,CAAC;IAC7C,IAAI,OAAO,CAAC,oBAAoB,KAAK,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,cAAc,CAAC,4DAA4D,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAsC;IAEtC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,OAAO,CAAC,kBAAkB,EAC1B,wBAAwB,CACzB,CAAC;IACF,MAAM,cAAc,GAAG,uBAAuB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,aAAa,CAClB,0DAA0D,EAC1D,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACtC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAChC,OAAO,aAAa,CAClB,2CAA2C,EAC3C,oCAAoC,EACpC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClF,IAAI,kBAAkB,KAAK,IAAI,IAAI,kBAAkB,KAAK,UAAU,EAAE,CAAC;QACrE,OAAO,aAAa,CAClB,8DAA8D,EAC9D,gCAAgC,EAChC,EAAE,OAAO,EAAE,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAE,EAAE,CAC5F,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GACnB,OAAO,CAAC,QAAQ,KAAK,qBAAqB;QACxC,CAAC,CAAC,4BAA4B,CAAC,OAAO,CAAC,UAAoB,CAAC,CAAC,KAAK;QAClE,CAAC,CAAC,IAAI,CAAC;IAEX,IAAI,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACtC,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS;QACT,GAAG;QACH,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,0BAA0B;KAC7E,CAAC,CAAC;IACH,oBAAoB,CAAC;QACnB,OAAO;QACP,OAAO;QACP,cAAc;QACd,eAAe;QACf,GAAG;KACJ,CAAC,CAAC;IAEH,IAAI,WAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,WAAW,GAAG,MAAM,gBAAgB,CAAC;YACnC,cAAc;YACd,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,GAAG,MAAM,mBAAmB,CAAC;YAClC,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS;YACT,GAAG;YACH,YAAY,EAAE,IAAI;YAClB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,0BAA0B;SAC7E,CAAC,CAAC;QACH,oBAAoB,CAAC;YACnB,OAAO;YACP,OAAO;YACP,cAAc;YACd,eAAe;YACf,GAAG;SACJ,CAAC,CAAC;QACH,WAAW,GAAG,MAAM,gBAAgB,CAAC;YACnC,cAAc;YACd,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IACD,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,yBAAyB,GAAG,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,IACE,CAAC,YAAY;QACb,WAAW,CAAC,KAAK,KAAK,YAAY;QAClC,CAAC,yBAAyB,KAAK,IAAI,IAAI,WAAW,CAAC,KAAK,KAAK,yBAAyB,CAAC,EACvF,CAAC;QACD,OAAO,aAAa,CAClB,4EAA4E,EAC5E,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;QACrE,OAAO,aAAa,CAClB,uDAAuD,EACvD,6BAA6B,EAC7B,EAAE,OAAO,EAAE,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,uBAAuB,GAC3B,MAAM,CAAC,kBAAkB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC;IACxE,MAAM,KAAK,GAA6B;QACtC,MAAM,EAAE,4BAA4B;QACpC,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,mBAAmB;QAC9B,iBAAiB,EAAE,WAAW;QAC9B,eAAe,EAAE,GAAG,CAAC,WAAW,EAAE;QAClC,GAAG,EAAE;YACH,YAAY,EAAE,gBAAgB;YAC9B,eAAe,EAAE,UAAU;SAC5B;QACD,OAAO,EAAE;YACP,WAAW,EAAE,UAAU;YACvB,gBAAgB,EAAE,cAAc;SACjC;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,WAAW,CAAC,MAAM;YAC3B,aAAa,EAAE,YAAY;SAC5B;QACD,OAAO,EAAE;YACP,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC;YAC9B,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,cAAc,EAAE,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC;SACvD;QACD,QAAQ,EAAE;YACR,cAAc,EAAE,kBAAkB,CAAC,UAAU,CAAC;YAC9C,eAAe,EAAE,mBAAmB,CAAC;gBACnC,UAAU;gBACV,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,YAAY;aACb,CAAC;SACH;QACD,UAAU,EAAE;YACV,IAAI,EACF,uBAAuB,KAAK,CAAC;gBAC3B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,uBAAuB,KAAK,CAAC;oBAC7B,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,SAAS;YACjB,eAAe,EAAE,uBAAoC;YACrD,oBAAoB,EAAE,kBAAkB;YACxC,gBAAgB,EAAE,cAAc;YAChC,kBAAkB,EAAE,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YAC7D,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YACrD,MAAM,EAAE,IAAI;SACb;KACF,CAAC;IACF,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,oBAAoB,EAAE,UAAU,CAAC,KAAK,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,kBAAkB;IAClB,oBAAoB;IACpB,SAAS;IACT,kBAAkB;IAClB,wBAAwB;IACxB,wBAAwB;IACxB,qBAAqB;IACrB,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,OAAO;IACP,cAAc;IACd,oBAAoB;IACpB,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,uBAAuB;IACvB,kBAAkB;IAClB,mBAAmB;IACnB,sBAAsB;IACtB,mBAAmB;IACnB,UAAU;IACV,eAAe;IACf,KAAK;CACN,CAAC","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\nimport { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';\n\nexport const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1' as const;\nexport const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;\n\nconst CLI_PACKAGE_NAME = '@tiangong-lca/cli' as const;\nconst CURRENT_USER_PATH = '/auth/v1/user' as const;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RESPONSE_BYTES = 64 * 1024;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\nconst SHA256_PATTERN = /^[0-9a-f]{64}$/u;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;\nconst EMAIL_PATTERN = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/u;\nconst SESSION_SOURCES = [\n 'memory',\n 'cache',\n 'refresh',\n 'oauth_login',\n 'legacy_signin',\n 'access_token',\n] as const;\nconst CACHE_MODES = ['disabled', 'custom-file', 'platform-default'] as const;\n\ntype SessionSource = (typeof SESSION_SOURCES)[number];\ntype CacheMode = (typeof CACHE_MODES)[number];\ntype JsonObject = Record<string, unknown>;\n\nclass ResponseBodyTooLargeError extends Error {\n constructor() {\n super('Response body exceeded the identity receipt byte limit.');\n this.name = 'ResponseBodyTooLargeError';\n }\n}\n\nexport type AuthIdentityReceiptScope = {\n schema: typeof AUTH_IDENTITY_RECEIPT_SCHEMA;\n status: 'passed';\n operation: 'current-user-read';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n cli: {\n package_name: typeof CLI_PACKAGE_NAME;\n package_version: string;\n };\n project: {\n project_ref: string;\n project_base_url: string;\n };\n identity: {\n user_id: string;\n display_email: string;\n };\n session: {\n source: SessionSource;\n cache_mode: CacheMode;\n force_reauth: boolean;\n expires_at_utc: string | null;\n };\n bindings: {\n request_sha256: string;\n response_sha256: string;\n };\n assertions: {\n mode: 'observed' | 'partial' | 'intent-bound';\n requested_count: 0 | 1 | 2;\n expected_project_ref: string | null;\n expected_user_id: string | null;\n project_ref_passed: true | null;\n user_id_passed: true | null;\n passed: true;\n };\n};\n\nexport type AuthIdentityReceipt = AuthIdentityReceiptScope & {\n receipt_scope_sha256: string;\n};\n\nexport type ResolveAuthIdentitySession = (options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}) => Promise<ResolvedSupabaseUserSession>;\n\nexport type RunAuthIdentityReceiptOptions = {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n expectedProjectRef?: string | null;\n expectedUserId?: string | null;\n timeoutMs?: number;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stableJsonValue);\n }\n if (isRecord(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, stableJsonValue(value[key])]),\n );\n }\n return value;\n}\n\nfunction sha256Json(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(stableJsonValue(value)))\n .digest('hex');\n}\n\nfunction token(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction normalizeEmail(value: unknown): string | null {\n const normalized = token(value)?.toLowerCase() ?? null;\n if (!normalized || normalized.length > 254 || !EMAIL_PATTERN.test(normalized)) {\n return null;\n }\n return normalized;\n}\n\nfunction isCanonicalUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_PATTERN.test(value);\n}\n\nfunction identityError(\n message: string,\n code: string,\n options: { exitCode?: number; details?: unknown } = {},\n): never {\n throw new CliError(message, {\n code,\n exitCode: options.exitCode ?? 1,\n ...(options.details === undefined ? {} : { details: options.details }),\n });\n}\n\nfunction receiptInvalid(message: string): never {\n return identityError(message, 'AUTH_IDENTITY_RECEIPT_INVALID');\n}\n\nfunction normalizeExpectation(value: string | null | undefined, label: string): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const normalized = token(value);\n if (!normalized) {\n return identityError(\n `${label} must be a non-empty string when provided.`,\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n {\n exitCode: 2,\n details: { option: label },\n },\n );\n }\n return normalized;\n}\n\nfunction normalizeExpectedUserId(value: string | null | undefined): string | null {\n const normalized = normalizeExpectation(value, '--expected-user-id');\n if (normalized !== null && !isCanonicalUuid(normalized)) {\n return identityError(\n '--expected-user-id must be a canonical lowercase UUID.',\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n { exitCode: 2, details: { option: '--expected-user-id' } },\n );\n }\n return normalized;\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (\n !Number.isInteger(normalized) ||\n normalized <= 0 ||\n normalized > AUTH_IDENTITY_MAX_TIMEOUT_MS\n ) {\n return identityError(\n `Auth identity timeout must be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`,\n 'AUTH_IDENTITY_TIMEOUT_INVALID',\n { exitCode: 2 },\n );\n }\n return normalized;\n}\n\nfunction canonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') {\n return false;\n }\n const timestamp = new Date(value);\n return !Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value;\n}\n\nfunction canonicalProjectIdentity(\n projectBaseUrl: unknown,\n): { projectBaseUrl: string; projectRef: string } | null {\n const normalized = token(projectBaseUrl);\n if (!normalized || normalized !== projectBaseUrl) {\n return null;\n }\n try {\n const url = new URL(normalized);\n const suffix = '.supabase.co';\n const hostname = url.hostname.toLowerCase();\n const projectRef = hostname.endsWith(suffix) ? hostname.slice(0, -suffix.length) : '';\n if (\n url.protocol !== 'https:' ||\n url.origin !== normalized ||\n url.username ||\n url.password ||\n url.port ||\n !projectRef ||\n projectRef.includes('.') ||\n !/^[a-z0-9-]+$/u.test(projectRef)\n ) {\n return null;\n }\n return { projectBaseUrl: url.origin, projectRef };\n } catch {\n return null;\n }\n}\n\nfunction projectRefFromBaseUrl(projectBaseUrl: string): string {\n const identity = canonicalProjectIdentity(projectBaseUrl);\n if (!identity) {\n return identityError(\n 'The Supabase project URL did not contain a project identity.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n return identity.projectRef;\n}\n\nfunction resolveProjectIdentity(apiBaseUrl: string): {\n projectBaseUrl: string;\n projectRef: string;\n} {\n let projectBaseUrl: string;\n try {\n projectBaseUrl = deriveSupabaseProjectBaseUrl(apiBaseUrl);\n } catch {\n return identityError(\n 'TIANGONG_LCA_API_BASE_URL must identify a canonical Supabase project.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n const projectRef = projectRefFromBaseUrl(projectBaseUrl);\n return { projectBaseUrl, projectRef };\n}\n\nfunction cacheMode(runtime: SupabaseRestRuntime): CacheMode {\n if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {\n return 'disabled';\n }\n return runtime.sessionFile ? 'custom-file' : 'platform-default';\n}\n\nfunction sessionExpiresAtUtc(expiresAt: number | null): string | null {\n if (expiresAt === null) {\n return null;\n }\n if (!Number.isFinite(expiresAt)) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n const timestamp = new Date(Math.floor(expiresAt) * 1000);\n if (Number.isNaN(timestamp.getTime())) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n return timestamp.toISOString();\n}\n\nfunction assertSessionBinding(options: {\n runtime: SupabaseRestRuntime;\n session: ResolvedSupabaseUserSession;\n projectBaseUrl: string;\n credentialEmail: string | null;\n now: Date;\n}): void {\n const { runtime, session } = options;\n const sessionEmail = normalizeEmail(session.userEmail);\n const credentialEmail = options.credentialEmail ? normalizeEmail(options.credentialEmail) : null;\n const accessToken = token(session.accessToken);\n const source = session.source as string;\n const expectedMode = cacheMode(runtime);\n const customSessionPath = runtime.sessionFile ? path.resolve(runtime.sessionFile) : null;\n const sessionPath = session.sessionFile ? path.resolve(session.sessionFile) : null;\n const cachePathMatches =\n expectedMode === 'disabled'\n ? sessionPath === null\n : expectedMode === 'custom-file'\n ? sessionPath === customSessionPath\n : sessionPath !== null;\n const cacheSourceFresh =\n !['memory', 'cache'].includes(source) ||\n (typeof session.expiresAt === 'number' &&\n Number.isFinite(session.expiresAt) &&\n session.expiresAt >\n Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);\n\n if (\n !accessToken ||\n session.authMethod !== runtime.authMode ||\n session.projectBaseUrl !== options.projectBaseUrl ||\n !sessionEmail ||\n (credentialEmail !== null && sessionEmail !== credentialEmail) ||\n !SESSION_SOURCES.includes(session.source) ||\n !cachePathMatches ||\n !cacheSourceFresh ||\n (runtime.forceReauth && ['memory', 'cache'].includes(source))\n ) {\n identityError(\n 'Resolved auth session does not match the requested credential, project, or cache boundary.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n}\n\nasync function resolveBoundSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh?: boolean;\n resolveSessionImpl: ResolveAuthIdentitySession;\n}): Promise<ResolvedSupabaseUserSession> {\n try {\n return await options.resolveSessionImpl({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: options.forceRefresh,\n });\n } catch (error) {\n const causeCode =\n error instanceof CliError\n ? error.code\n : isRecord(error) && typeof error.code === 'string'\n ? error.code\n : 'UNEXPECTED_SESSION_FAILURE';\n return identityError(\n 'Failed to resolve the authenticated user session.',\n 'AUTH_IDENTITY_SESSION_FAILED',\n { details: { cause_code: causeCode } },\n );\n }\n}\n\nfunction currentUserFailureStatus(error: unknown): number | null {\n if (\n !(error instanceof CliError) ||\n error.code !== 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED' ||\n !isRecord(error.details) ||\n typeof error.details.status !== 'number' ||\n !Number.isInteger(error.details.status)\n ) {\n return null;\n }\n return error.details.status;\n}\n\nfunction declaredResponseBytes(response: {\n headers: { get(name: string): string | null };\n}): number | null {\n const value = response.headers.get('content-length')?.trim() ?? '';\n if (!/^\\d+$/u.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nasync function readBoundedResponseText(response: {\n body?: ReadableStream<Uint8Array> | null;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}): Promise<string> {\n const declaredBytes = declaredResponseBytes(response);\n if (declaredBytes !== null && declaredBytes > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n return text;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let observedBytes = 0;\n let text = '';\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n observedBytes += chunk.value.byteLength;\n if (observedBytes > MAX_RESPONSE_BYTES) {\n await Promise.allSettled([reader.cancel()]);\n throw new ResponseBodyTooLargeError();\n }\n text += decoder.decode(chunk.value, { stream: true });\n }\n text += decoder.decode();\n return text;\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function fetchCurrentUser(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ userId: string; email: string }> {\n const url = `${options.projectBaseUrl}${CURRENT_USER_PATH}`;\n let response;\n try {\n response = await options.fetchImpl(url, {\n method: 'GET',\n headers: buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),\n redirect: 'error',\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n } catch (error) {\n return identityError(\n 'Authenticated current-user lookup failed before a response was received.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n if (!response.ok) {\n return identityError(\n `Authenticated current-user lookup returned HTTP ${response.status}.`,\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const contentType = response.headers.get('content-type')?.toLowerCase() ?? '';\n if (!contentType.includes('application/json')) {\n return identityError(\n 'Authenticated current-user response did not declare JSON content.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n\n let text: string;\n try {\n text = await readBoundedResponseText(response);\n } catch (error) {\n if (error instanceof ResponseBodyTooLargeError) {\n return identityError(\n 'Authenticated current-user response exceeded the bounded receipt limit.',\n 'AUTH_IDENTITY_RESPONSE_TOO_LARGE',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return identityError(\n 'Authenticated current-user response could not be read.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n status: response.status,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return identityError(\n 'Authenticated current-user response was not valid JSON.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n if (isRecord(payload) && payload.ok === false) {\n return identityError(\n 'Authenticated current-user response explicitly reported ok:false.',\n 'AUTH_IDENTITY_REMOTE_REJECTED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const userId = isRecord(payload) && isCanonicalUuid(payload.id) ? payload.id : null;\n const email = isRecord(payload) ? normalizeEmail(payload.email) : null;\n if (!userId || !email) {\n return identityError(\n 'Authenticated current-user response did not contain a valid id and email.',\n 'AUTH_IDENTITY_RESPONSE_INVALID',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return { userId, email };\n}\n\nfunction requestFingerprint(projectRef: string): string {\n return sha256Json({\n method: 'GET',\n path: CURRENT_USER_PATH,\n project_ref: projectRef,\n redirect: 'error',\n header_names: ['accept', 'apikey', 'authorization'],\n });\n}\n\nfunction responseFingerprint(options: {\n projectRef: string;\n userId: string;\n displayEmail: string;\n}): string {\n return sha256Json({\n project_ref: options.projectRef,\n user_id: options.userId,\n display_email: options.displayEmail,\n });\n}\n\nfunction hasExactKeys(value: JsonObject, expected: readonly string[]): boolean {\n const actual = Object.keys(value).sort();\n const sortedExpected = [...expected].sort();\n return (\n actual.length === sortedExpected.length &&\n actual.every((key, index) => key === sortedExpected[index])\n );\n}\n\nfunction isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === 'string' && values.includes(value as T);\n}\n\nfunction isCanonicalToken(value: unknown): value is string {\n return typeof value === 'string' && token(value) === value;\n}\n\nfunction isMaskedEmail(value: unknown): value is string {\n return isCanonicalToken(value) && /^(?:[^*@\\s]{2})?\\*{4}@[^@\\s]+\\.[^@\\s]+$/u.test(value);\n}\n\nfunction receiptScope(receipt: AuthIdentityReceipt): AuthIdentityReceiptScope {\n const { receipt_scope_sha256: _receiptScopeSha256, ...scope } = receipt;\n return scope;\n}\n\nexport function parseAuthIdentityReceipt(value: unknown): AuthIdentityReceipt {\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n 'assertions',\n 'bindings',\n 'captured_at_utc',\n 'cli',\n 'identity',\n 'operation',\n 'project',\n 'receipt_scope_sha256',\n 'remote_write_mode',\n 'schema',\n 'session',\n 'status',\n ])\n ) {\n return receiptInvalid('Auth identity receipt must be an exact object.');\n }\n\n const cli = value.cli;\n const project = value.project;\n const identity = value.identity;\n const session = value.session;\n const bindings = value.bindings;\n const assertions = value.assertions;\n const parsedProject =\n isRecord(project) && typeof project.project_base_url === 'string'\n ? canonicalProjectIdentity(project.project_base_url)\n : null;\n if (\n value.schema !== AUTH_IDENTITY_RECEIPT_SCHEMA ||\n value.status !== 'passed' ||\n value.operation !== 'current-user-read' ||\n value.remote_write_mode !== 'read-only' ||\n !canonicalTimestamp(value.captured_at_utc) ||\n !isRecord(cli) ||\n !hasExactKeys(cli, ['package_name', 'package_version']) ||\n cli.package_name !== CLI_PACKAGE_NAME ||\n !isCanonicalToken(cli.package_version) ||\n !isRecord(project) ||\n !hasExactKeys(project, ['project_base_url', 'project_ref']) ||\n !isCanonicalToken(project.project_ref) ||\n !parsedProject ||\n parsedProject.projectRef !== project.project_ref ||\n !isRecord(identity) ||\n !hasExactKeys(identity, ['display_email', 'user_id']) ||\n !isCanonicalUuid(identity.user_id) ||\n !isMaskedEmail(identity.display_email) ||\n !isRecord(session) ||\n !hasExactKeys(session, ['cache_mode', 'expires_at_utc', 'force_reauth', 'source']) ||\n !isOneOf(session.source, SESSION_SOURCES) ||\n !isOneOf(session.cache_mode, CACHE_MODES) ||\n typeof session.force_reauth !== 'boolean' ||\n !(session.expires_at_utc === null || canonicalTimestamp(session.expires_at_utc)) ||\n !isRecord(bindings) ||\n !hasExactKeys(bindings, ['request_sha256', 'response_sha256']) ||\n typeof bindings.request_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.request_sha256) ||\n typeof bindings.response_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.response_sha256) ||\n bindings.request_sha256 !== requestFingerprint(project.project_ref as string) ||\n bindings.response_sha256 !==\n responseFingerprint({\n projectRef: project.project_ref as string,\n userId: identity.user_id as string,\n displayEmail: identity.display_email as string,\n }) ||\n !isRecord(assertions) ||\n !hasExactKeys(assertions, [\n 'expected_project_ref',\n 'expected_user_id',\n 'mode',\n 'passed',\n 'project_ref_passed',\n 'requested_count',\n 'user_id_passed',\n ]) ||\n !isOneOf(assertions.mode, ['observed', 'partial', 'intent-bound'] as const) ||\n ![0, 1, 2].includes(assertions.requested_count as number) ||\n !(\n assertions.expected_project_ref === null || isCanonicalToken(assertions.expected_project_ref)\n ) ||\n !(assertions.expected_user_id === null || isCanonicalUuid(assertions.expected_user_id)) ||\n !(assertions.project_ref_passed === true || assertions.project_ref_passed === null) ||\n !(assertions.user_id_passed === true || assertions.user_id_passed === null) ||\n assertions.passed !== true ||\n (assertions.expected_project_ref === null) !== (assertions.project_ref_passed === null) ||\n (assertions.expected_user_id === null) !== (assertions.user_id_passed === null) ||\n assertions.requested_count !==\n Number(assertions.expected_project_ref !== null) +\n Number(assertions.expected_user_id !== null) ||\n assertions.mode !==\n (assertions.requested_count === 0\n ? 'observed'\n : assertions.requested_count === 2\n ? 'intent-bound'\n : 'partial') ||\n (assertions.expected_project_ref !== null &&\n assertions.expected_project_ref !== project.project_ref) ||\n (assertions.expected_user_id !== null && assertions.expected_user_id !== identity.user_id) ||\n typeof value.receipt_scope_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.receipt_scope_sha256)\n ) {\n return receiptInvalid('Auth identity receipt failed schema validation.');\n }\n\n const receipt = value as AuthIdentityReceipt;\n if (receipt.receipt_scope_sha256 !== sha256Json(receiptScope(receipt))) {\n return receiptInvalid('Auth identity receipt canonical scope hash does not match.');\n }\n return receipt;\n}\n\nexport async function runAuthIdentityReceipt(\n options: RunAuthIdentityReceiptOptions,\n): Promise<AuthIdentityReceipt> {\n const timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n const expectedProjectRef = normalizeExpectation(\n options.expectedProjectRef,\n '--expected-project-ref',\n );\n const expectedUserId = normalizeExpectedUserId(options.expectedUserId);\n const cliVersion = token(options.cliVersion);\n if (!cliVersion) {\n return identityError(\n 'CLI package version is required for an identity receipt.',\n 'AUTH_IDENTITY_VERSION_INVALID',\n { exitCode: 2 },\n );\n }\n const now = options.now ?? new Date();\n if (Number.isNaN(now.getTime())) {\n return identityError(\n 'Identity receipt capture time is invalid.',\n 'AUTH_IDENTITY_CAPTURE_TIME_INVALID',\n { exitCode: 2 },\n );\n }\n\n const runtime = requireSupabaseRestRuntime(options.env);\n const { projectBaseUrl, projectRef } = resolveProjectIdentity(runtime.apiBaseUrl);\n if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {\n return identityError(\n 'Authenticated project does not match --expected-project-ref.',\n 'AUTH_IDENTITY_PROJECT_MISMATCH',\n { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } },\n );\n }\n const credentialEmail =\n runtime.authMode === 'legacy_user_api_key'\n ? requireUserApiKeyCredentials(runtime.userApiKey as string).email\n : null;\n\n let session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n credentialEmail,\n now,\n });\n\n let currentUser: Awaited<ReturnType<typeof fetchCurrentUser>>;\n try {\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n } catch (error) {\n const status = currentUserFailureStatus(error);\n if (status === null || ![401, 403].includes(status)) {\n throw error;\n }\n session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh: true,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n credentialEmail,\n now,\n });\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n }\n const sessionEmail = normalizeEmail(session.userEmail);\n const normalizedCredentialEmail = credentialEmail ? normalizeEmail(credentialEmail) : null;\n if (\n !sessionEmail ||\n currentUser.email !== sessionEmail ||\n (normalizedCredentialEmail !== null && currentUser.email !== normalizedCredentialEmail)\n ) {\n return identityError(\n 'Server-verified current user does not match the resolved session identity.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n if (expectedUserId !== null && expectedUserId !== currentUser.userId) {\n return identityError(\n 'Authenticated user does not match --expected-user-id.',\n 'AUTH_IDENTITY_USER_MISMATCH',\n { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } },\n );\n }\n\n const displayEmail = redactEmail(currentUser.email);\n const requestedAssertionCount =\n Number(expectedProjectRef !== null) + Number(expectedUserId !== null);\n const scope: AuthIdentityReceiptScope = {\n schema: AUTH_IDENTITY_RECEIPT_SCHEMA,\n status: 'passed',\n operation: 'current-user-read',\n remote_write_mode: 'read-only',\n captured_at_utc: now.toISOString(),\n cli: {\n package_name: CLI_PACKAGE_NAME,\n package_version: cliVersion,\n },\n project: {\n project_ref: projectRef,\n project_base_url: projectBaseUrl,\n },\n identity: {\n user_id: currentUser.userId,\n display_email: displayEmail,\n },\n session: {\n source: session.source,\n cache_mode: cacheMode(runtime),\n force_reauth: runtime.forceReauth,\n expires_at_utc: sessionExpiresAtUtc(session.expiresAt),\n },\n bindings: {\n request_sha256: requestFingerprint(projectRef),\n response_sha256: responseFingerprint({\n projectRef,\n userId: currentUser.userId,\n displayEmail,\n }),\n },\n assertions: {\n mode:\n requestedAssertionCount === 0\n ? 'observed'\n : requestedAssertionCount === 2\n ? 'intent-bound'\n : 'partial',\n requested_count: requestedAssertionCount as 0 | 1 | 2,\n expected_project_ref: expectedProjectRef,\n expected_user_id: expectedUserId,\n project_ref_passed: expectedProjectRef === null ? null : true,\n user_id_passed: expectedUserId === null ? null : true,\n passed: true,\n },\n };\n return parseAuthIdentityReceipt({\n ...scope,\n receipt_scope_sha256: sha256Json(scope),\n });\n}\n\nexport const __testInternals = {\n MAX_RESPONSE_BYTES,\n assertSessionBinding,\n cacheMode,\n canonicalTimestamp,\n canonicalProjectIdentity,\n currentUserFailureStatus,\n declaredResponseBytes,\n fetchCurrentUser,\n hasExactKeys,\n isCanonicalToken,\n isCanonicalUuid,\n isMaskedEmail,\n isOneOf,\n normalizeEmail,\n normalizeExpectation,\n normalizeExpectedUserId,\n normalizeTimeoutMs,\n projectRefFromBaseUrl,\n readBoundedResponseText,\n requestFingerprint,\n responseFingerprint,\n resolveProjectIdentity,\n sessionExpiresAtUtc,\n sha256Json,\n stableJsonValue,\n token,\n};\n"]}
1
+ {"version":3,"file":"auth-identity-receipt.js","sourceRoot":"","sources":["../../../src/lib/auth-identity-receipt.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\nimport { redactEmail } from './credential-safety.js';\n\nexport const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1' as const;\nexport const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;\n\nconst CLI_PACKAGE_NAME = '@tiangong-lca/cli' as const;\nconst CURRENT_USER_PATH = '/auth/v1/user' as const;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RESPONSE_BYTES = 64 * 1024;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\nconst SHA256_PATTERN = /^[0-9a-f]{64}$/u;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;\nconst EMAIL_PATTERN = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/u;\nconst SESSION_SOURCES = ['memory', 'cache', 'refresh', 'oauth_login', 'access_token'] as const;\nconst CACHE_MODES = ['disabled', 'custom-file', 'platform-default'] as const;\n\ntype SessionSource = (typeof SESSION_SOURCES)[number];\ntype CacheMode = (typeof CACHE_MODES)[number];\ntype JsonObject = Record<string, unknown>;\n\nclass ResponseBodyTooLargeError extends Error {\n constructor() {\n super('Response body exceeded the identity receipt byte limit.');\n this.name = 'ResponseBodyTooLargeError';\n }\n}\n\nexport type AuthIdentityReceiptScope = {\n schema: typeof AUTH_IDENTITY_RECEIPT_SCHEMA;\n status: 'passed';\n operation: 'current-user-read';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n cli: {\n package_name: typeof CLI_PACKAGE_NAME;\n package_version: string;\n };\n project: {\n project_ref: string;\n project_base_url: string;\n };\n identity: {\n user_id: string;\n display_email: string;\n };\n session: {\n source: SessionSource;\n cache_mode: CacheMode;\n force_reauth: boolean;\n expires_at_utc: string | null;\n };\n bindings: {\n request_sha256: string;\n response_sha256: string;\n };\n assertions: {\n mode: 'observed' | 'partial' | 'intent-bound';\n requested_count: 0 | 1 | 2;\n expected_project_ref: string | null;\n expected_user_id: string | null;\n project_ref_passed: true | null;\n user_id_passed: true | null;\n passed: true;\n };\n};\n\nexport type AuthIdentityReceipt = AuthIdentityReceiptScope & {\n receipt_scope_sha256: string;\n};\n\nexport type ResolveAuthIdentitySession = (options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}) => Promise<ResolvedSupabaseUserSession>;\n\nexport type RunAuthIdentityReceiptOptions = {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n expectedProjectRef?: string | null;\n expectedUserId?: string | null;\n timeoutMs?: number;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stableJsonValue);\n }\n if (isRecord(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, stableJsonValue(value[key])]),\n );\n }\n return value;\n}\n\nfunction sha256Json(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(stableJsonValue(value)))\n .digest('hex');\n}\n\nfunction token(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction normalizeEmail(value: unknown): string | null {\n const normalized = token(value)?.toLowerCase() ?? null;\n if (!normalized || normalized.length > 254 || !EMAIL_PATTERN.test(normalized)) {\n return null;\n }\n return normalized;\n}\n\nfunction isCanonicalUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_PATTERN.test(value);\n}\n\nfunction identityError(\n message: string,\n code: string,\n options: { exitCode?: number; details?: unknown } = {},\n): never {\n throw new CliError(message, {\n code,\n exitCode: options.exitCode ?? 1,\n ...(options.details === undefined ? {} : { details: options.details }),\n });\n}\n\nfunction receiptInvalid(message: string): never {\n return identityError(message, 'AUTH_IDENTITY_RECEIPT_INVALID');\n}\n\nfunction normalizeExpectation(value: string | null | undefined, label: string): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const normalized = token(value);\n if (!normalized) {\n return identityError(\n `${label} must be a non-empty string when provided.`,\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n {\n exitCode: 2,\n details: { option: label },\n },\n );\n }\n return normalized;\n}\n\nfunction normalizeExpectedUserId(value: string | null | undefined): string | null {\n const normalized = normalizeExpectation(value, '--expected-user-id');\n if (normalized !== null && !isCanonicalUuid(normalized)) {\n return identityError(\n '--expected-user-id must be a canonical lowercase UUID.',\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n { exitCode: 2, details: { option: '--expected-user-id' } },\n );\n }\n return normalized;\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (\n !Number.isInteger(normalized) ||\n normalized <= 0 ||\n normalized > AUTH_IDENTITY_MAX_TIMEOUT_MS\n ) {\n return identityError(\n `Auth identity timeout must be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`,\n 'AUTH_IDENTITY_TIMEOUT_INVALID',\n { exitCode: 2 },\n );\n }\n return normalized;\n}\n\nfunction canonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') {\n return false;\n }\n const timestamp = new Date(value);\n return !Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value;\n}\n\nfunction canonicalProjectIdentity(\n projectBaseUrl: unknown,\n): { projectBaseUrl: string; projectRef: string } | null {\n const normalized = token(projectBaseUrl);\n if (!normalized || normalized !== projectBaseUrl) {\n return null;\n }\n try {\n const url = new URL(normalized);\n const suffix = '.supabase.co';\n const hostname = url.hostname.toLowerCase();\n const projectRef = hostname.endsWith(suffix) ? hostname.slice(0, -suffix.length) : '';\n if (\n url.protocol !== 'https:' ||\n url.origin !== normalized ||\n url.username ||\n url.password ||\n url.port ||\n !projectRef ||\n projectRef.includes('.') ||\n !/^[a-z0-9-]+$/u.test(projectRef)\n ) {\n return null;\n }\n return { projectBaseUrl: url.origin, projectRef };\n } catch {\n return null;\n }\n}\n\nfunction projectRefFromBaseUrl(projectBaseUrl: string): string {\n const identity = canonicalProjectIdentity(projectBaseUrl);\n if (!identity) {\n return identityError(\n 'The Supabase project URL did not contain a project identity.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n return identity.projectRef;\n}\n\nfunction resolveProjectIdentity(apiBaseUrl: string): {\n projectBaseUrl: string;\n projectRef: string;\n} {\n let projectBaseUrl: string;\n try {\n projectBaseUrl = deriveSupabaseProjectBaseUrl(apiBaseUrl);\n } catch {\n return identityError(\n 'TIANGONG_LCA_API_BASE_URL must identify a canonical Supabase project.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n const projectRef = projectRefFromBaseUrl(projectBaseUrl);\n return { projectBaseUrl, projectRef };\n}\n\nfunction cacheMode(runtime: SupabaseRestRuntime): CacheMode {\n if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {\n return 'disabled';\n }\n return runtime.sessionFile ? 'custom-file' : 'platform-default';\n}\n\nfunction sessionExpiresAtUtc(expiresAt: number | null): string | null {\n if (expiresAt === null) {\n return null;\n }\n if (!Number.isFinite(expiresAt)) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n const timestamp = new Date(Math.floor(expiresAt) * 1000);\n if (Number.isNaN(timestamp.getTime())) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n return timestamp.toISOString();\n}\n\nfunction assertSessionBinding(options: {\n runtime: SupabaseRestRuntime;\n session: ResolvedSupabaseUserSession;\n projectBaseUrl: string;\n now: Date;\n}): void {\n const { runtime, session } = options;\n const sessionEmail = normalizeEmail(session.userEmail);\n const accessToken = token(session.accessToken);\n const source = session.source as string;\n const expectedMode = cacheMode(runtime);\n const customSessionPath = runtime.sessionFile ? path.resolve(runtime.sessionFile) : null;\n const sessionPath = session.sessionFile ? path.resolve(session.sessionFile) : null;\n const cachePathMatches =\n expectedMode === 'disabled'\n ? sessionPath === null\n : expectedMode === 'custom-file'\n ? sessionPath === customSessionPath\n : sessionPath !== null;\n const cacheSourceFresh =\n !['memory', 'cache'].includes(source) ||\n (typeof session.expiresAt === 'number' &&\n Number.isFinite(session.expiresAt) &&\n session.expiresAt >\n Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);\n\n if (\n !accessToken ||\n session.authMethod !== runtime.authMode ||\n session.projectBaseUrl !== options.projectBaseUrl ||\n !sessionEmail ||\n !SESSION_SOURCES.includes(session.source) ||\n !cachePathMatches ||\n !cacheSourceFresh ||\n (runtime.forceReauth && ['memory', 'cache'].includes(source))\n ) {\n identityError(\n 'Resolved auth session does not match the requested credential, project, or cache boundary.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n}\n\nasync function resolveBoundSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh?: boolean;\n resolveSessionImpl: ResolveAuthIdentitySession;\n}): Promise<ResolvedSupabaseUserSession> {\n try {\n return await options.resolveSessionImpl({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: options.forceRefresh,\n });\n } catch (error) {\n const causeCode =\n error instanceof CliError\n ? error.code\n : isRecord(error) && typeof error.code === 'string'\n ? error.code\n : 'UNEXPECTED_SESSION_FAILURE';\n return identityError(\n 'Failed to resolve the authenticated user session.',\n 'AUTH_IDENTITY_SESSION_FAILED',\n { details: { cause_code: causeCode } },\n );\n }\n}\n\nfunction currentUserFailureStatus(error: unknown): number | null {\n if (\n !(error instanceof CliError) ||\n error.code !== 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED' ||\n !isRecord(error.details) ||\n typeof error.details.status !== 'number' ||\n !Number.isInteger(error.details.status)\n ) {\n return null;\n }\n return error.details.status;\n}\n\nfunction declaredResponseBytes(response: {\n headers: { get(name: string): string | null };\n}): number | null {\n const value = response.headers.get('content-length')?.trim() ?? '';\n if (!/^\\d+$/u.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nasync function readBoundedResponseText(response: {\n body?: ReadableStream<Uint8Array> | null;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}): Promise<string> {\n const declaredBytes = declaredResponseBytes(response);\n if (declaredBytes !== null && declaredBytes > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n return text;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let observedBytes = 0;\n let text = '';\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n observedBytes += chunk.value.byteLength;\n if (observedBytes > MAX_RESPONSE_BYTES) {\n await Promise.allSettled([reader.cancel()]);\n throw new ResponseBodyTooLargeError();\n }\n text += decoder.decode(chunk.value, { stream: true });\n }\n text += decoder.decode();\n return text;\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function fetchCurrentUser(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ userId: string; email: string }> {\n const url = `${options.projectBaseUrl}${CURRENT_USER_PATH}`;\n let response;\n try {\n response = await options.fetchImpl(url, {\n method: 'GET',\n headers: buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),\n redirect: 'error',\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n } catch (error) {\n return identityError(\n 'Authenticated current-user lookup failed before a response was received.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n if (!response.ok) {\n return identityError(\n `Authenticated current-user lookup returned HTTP ${response.status}.`,\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const contentType = response.headers.get('content-type')?.toLowerCase() ?? '';\n if (!contentType.includes('application/json')) {\n return identityError(\n 'Authenticated current-user response did not declare JSON content.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n\n let text: string;\n try {\n text = await readBoundedResponseText(response);\n } catch (error) {\n if (error instanceof ResponseBodyTooLargeError) {\n return identityError(\n 'Authenticated current-user response exceeded the bounded receipt limit.',\n 'AUTH_IDENTITY_RESPONSE_TOO_LARGE',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return identityError(\n 'Authenticated current-user response could not be read.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n status: response.status,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return identityError(\n 'Authenticated current-user response was not valid JSON.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n if (isRecord(payload) && payload.ok === false) {\n return identityError(\n 'Authenticated current-user response explicitly reported ok:false.',\n 'AUTH_IDENTITY_REMOTE_REJECTED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const userId = isRecord(payload) && isCanonicalUuid(payload.id) ? payload.id : null;\n const email = isRecord(payload) ? normalizeEmail(payload.email) : null;\n if (!userId || !email) {\n return identityError(\n 'Authenticated current-user response did not contain a valid id and email.',\n 'AUTH_IDENTITY_RESPONSE_INVALID',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return { userId, email };\n}\n\nfunction requestFingerprint(projectRef: string): string {\n return sha256Json({\n method: 'GET',\n path: CURRENT_USER_PATH,\n project_ref: projectRef,\n redirect: 'error',\n header_names: ['accept', 'apikey', 'authorization'],\n });\n}\n\nfunction responseFingerprint(options: {\n projectRef: string;\n userId: string;\n displayEmail: string;\n}): string {\n return sha256Json({\n project_ref: options.projectRef,\n user_id: options.userId,\n display_email: options.displayEmail,\n });\n}\n\nfunction hasExactKeys(value: JsonObject, expected: readonly string[]): boolean {\n const actual = Object.keys(value).sort();\n const sortedExpected = [...expected].sort();\n return (\n actual.length === sortedExpected.length &&\n actual.every((key, index) => key === sortedExpected[index])\n );\n}\n\nfunction isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === 'string' && values.includes(value as T);\n}\n\nfunction isCanonicalToken(value: unknown): value is string {\n return typeof value === 'string' && token(value) === value;\n}\n\nfunction isMaskedEmail(value: unknown): value is string {\n return isCanonicalToken(value) && /^(?:[^*@\\s]{2})?\\*{4}@[^@\\s]+\\.[^@\\s]+$/u.test(value);\n}\n\nfunction receiptScope(receipt: AuthIdentityReceipt): AuthIdentityReceiptScope {\n const { receipt_scope_sha256: _receiptScopeSha256, ...scope } = receipt;\n return scope;\n}\n\nexport function parseAuthIdentityReceipt(value: unknown): AuthIdentityReceipt {\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n 'assertions',\n 'bindings',\n 'captured_at_utc',\n 'cli',\n 'identity',\n 'operation',\n 'project',\n 'receipt_scope_sha256',\n 'remote_write_mode',\n 'schema',\n 'session',\n 'status',\n ])\n ) {\n return receiptInvalid('Auth identity receipt must be an exact object.');\n }\n\n const cli = value.cli;\n const project = value.project;\n const identity = value.identity;\n const session = value.session;\n const bindings = value.bindings;\n const assertions = value.assertions;\n const parsedProject =\n isRecord(project) && typeof project.project_base_url === 'string'\n ? canonicalProjectIdentity(project.project_base_url)\n : null;\n if (\n value.schema !== AUTH_IDENTITY_RECEIPT_SCHEMA ||\n value.status !== 'passed' ||\n value.operation !== 'current-user-read' ||\n value.remote_write_mode !== 'read-only' ||\n !canonicalTimestamp(value.captured_at_utc) ||\n !isRecord(cli) ||\n !hasExactKeys(cli, ['package_name', 'package_version']) ||\n cli.package_name !== CLI_PACKAGE_NAME ||\n !isCanonicalToken(cli.package_version) ||\n !isRecord(project) ||\n !hasExactKeys(project, ['project_base_url', 'project_ref']) ||\n !isCanonicalToken(project.project_ref) ||\n !parsedProject ||\n parsedProject.projectRef !== project.project_ref ||\n !isRecord(identity) ||\n !hasExactKeys(identity, ['display_email', 'user_id']) ||\n !isCanonicalUuid(identity.user_id) ||\n !isMaskedEmail(identity.display_email) ||\n !isRecord(session) ||\n !hasExactKeys(session, ['cache_mode', 'expires_at_utc', 'force_reauth', 'source']) ||\n !isOneOf(session.source, SESSION_SOURCES) ||\n !isOneOf(session.cache_mode, CACHE_MODES) ||\n typeof session.force_reauth !== 'boolean' ||\n !(session.expires_at_utc === null || canonicalTimestamp(session.expires_at_utc)) ||\n !isRecord(bindings) ||\n !hasExactKeys(bindings, ['request_sha256', 'response_sha256']) ||\n typeof bindings.request_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.request_sha256) ||\n typeof bindings.response_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.response_sha256) ||\n bindings.request_sha256 !== requestFingerprint(project.project_ref as string) ||\n bindings.response_sha256 !==\n responseFingerprint({\n projectRef: project.project_ref as string,\n userId: identity.user_id as string,\n displayEmail: identity.display_email as string,\n }) ||\n !isRecord(assertions) ||\n !hasExactKeys(assertions, [\n 'expected_project_ref',\n 'expected_user_id',\n 'mode',\n 'passed',\n 'project_ref_passed',\n 'requested_count',\n 'user_id_passed',\n ]) ||\n !isOneOf(assertions.mode, ['observed', 'partial', 'intent-bound'] as const) ||\n ![0, 1, 2].includes(assertions.requested_count as number) ||\n !(\n assertions.expected_project_ref === null || isCanonicalToken(assertions.expected_project_ref)\n ) ||\n !(assertions.expected_user_id === null || isCanonicalUuid(assertions.expected_user_id)) ||\n !(assertions.project_ref_passed === true || assertions.project_ref_passed === null) ||\n !(assertions.user_id_passed === true || assertions.user_id_passed === null) ||\n assertions.passed !== true ||\n (assertions.expected_project_ref === null) !== (assertions.project_ref_passed === null) ||\n (assertions.expected_user_id === null) !== (assertions.user_id_passed === null) ||\n assertions.requested_count !==\n Number(assertions.expected_project_ref !== null) +\n Number(assertions.expected_user_id !== null) ||\n assertions.mode !==\n (assertions.requested_count === 0\n ? 'observed'\n : assertions.requested_count === 2\n ? 'intent-bound'\n : 'partial') ||\n (assertions.expected_project_ref !== null &&\n assertions.expected_project_ref !== project.project_ref) ||\n (assertions.expected_user_id !== null && assertions.expected_user_id !== identity.user_id) ||\n typeof value.receipt_scope_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.receipt_scope_sha256)\n ) {\n return receiptInvalid('Auth identity receipt failed schema validation.');\n }\n\n const receipt = value as AuthIdentityReceipt;\n if (receipt.receipt_scope_sha256 !== sha256Json(receiptScope(receipt))) {\n return receiptInvalid('Auth identity receipt canonical scope hash does not match.');\n }\n return receipt;\n}\n\nexport async function runAuthIdentityReceipt(\n options: RunAuthIdentityReceiptOptions,\n): Promise<AuthIdentityReceipt> {\n const timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n const expectedProjectRef = normalizeExpectation(\n options.expectedProjectRef,\n '--expected-project-ref',\n );\n const expectedUserId = normalizeExpectedUserId(options.expectedUserId);\n const cliVersion = token(options.cliVersion);\n if (!cliVersion) {\n return identityError(\n 'CLI package version is required for an identity receipt.',\n 'AUTH_IDENTITY_VERSION_INVALID',\n { exitCode: 2 },\n );\n }\n const now = options.now ?? new Date();\n if (Number.isNaN(now.getTime())) {\n return identityError(\n 'Identity receipt capture time is invalid.',\n 'AUTH_IDENTITY_CAPTURE_TIME_INVALID',\n { exitCode: 2 },\n );\n }\n\n const runtime = requireSupabaseRestRuntime(options.env);\n const { projectBaseUrl, projectRef } = resolveProjectIdentity(runtime.apiBaseUrl);\n if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {\n return identityError(\n 'Authenticated project does not match --expected-project-ref.',\n 'AUTH_IDENTITY_PROJECT_MISMATCH',\n { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } },\n );\n }\n let session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n now,\n });\n\n let currentUser: Awaited<ReturnType<typeof fetchCurrentUser>>;\n try {\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n } catch (error) {\n const status = currentUserFailureStatus(error);\n if (status === null || ![401, 403].includes(status)) {\n throw error;\n }\n session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh: true,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n now,\n });\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n }\n const sessionEmail = normalizeEmail(session.userEmail);\n if (!sessionEmail || currentUser.email !== sessionEmail) {\n return identityError(\n 'Server-verified current user does not match the resolved session identity.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n if (expectedUserId !== null && expectedUserId !== currentUser.userId) {\n return identityError(\n 'Authenticated user does not match --expected-user-id.',\n 'AUTH_IDENTITY_USER_MISMATCH',\n { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } },\n );\n }\n\n const displayEmail = redactEmail(currentUser.email);\n const requestedAssertionCount =\n Number(expectedProjectRef !== null) + Number(expectedUserId !== null);\n const scope: AuthIdentityReceiptScope = {\n schema: AUTH_IDENTITY_RECEIPT_SCHEMA,\n status: 'passed',\n operation: 'current-user-read',\n remote_write_mode: 'read-only',\n captured_at_utc: now.toISOString(),\n cli: {\n package_name: CLI_PACKAGE_NAME,\n package_version: cliVersion,\n },\n project: {\n project_ref: projectRef,\n project_base_url: projectBaseUrl,\n },\n identity: {\n user_id: currentUser.userId,\n display_email: displayEmail,\n },\n session: {\n source: session.source,\n cache_mode: cacheMode(runtime),\n force_reauth: runtime.forceReauth,\n expires_at_utc: sessionExpiresAtUtc(session.expiresAt),\n },\n bindings: {\n request_sha256: requestFingerprint(projectRef),\n response_sha256: responseFingerprint({\n projectRef,\n userId: currentUser.userId,\n displayEmail,\n }),\n },\n assertions: {\n mode:\n requestedAssertionCount === 0\n ? 'observed'\n : requestedAssertionCount === 2\n ? 'intent-bound'\n : 'partial',\n requested_count: requestedAssertionCount as 0 | 1 | 2,\n expected_project_ref: expectedProjectRef,\n expected_user_id: expectedUserId,\n project_ref_passed: expectedProjectRef === null ? null : true,\n user_id_passed: expectedUserId === null ? null : true,\n passed: true,\n },\n };\n return parseAuthIdentityReceipt({\n ...scope,\n receipt_scope_sha256: sha256Json(scope),\n });\n}\n\nexport const __testInternals = {\n MAX_RESPONSE_BYTES,\n assertSessionBinding,\n cacheMode,\n canonicalTimestamp,\n canonicalProjectIdentity,\n currentUserFailureStatus,\n declaredResponseBytes,\n fetchCurrentUser,\n hasExactKeys,\n isCanonicalToken,\n isCanonicalUuid,\n isMaskedEmail,\n isOneOf,\n normalizeEmail,\n normalizeExpectation,\n normalizeExpectedUserId,\n normalizeTimeoutMs,\n projectRefFromBaseUrl,\n readBoundedResponseText,\n requestFingerprint,\n responseFingerprint,\n resolveProjectIdentity,\n sessionExpiresAtUtc,\n sha256Json,\n stableJsonValue,\n token,\n};\n"]}
@@ -0,0 +1,7 @@
1
+ declare function normalizeCredentialValue(value: unknown): string;
2
+ export declare function fingerprintSecret(value: string): string;
3
+ export declare function redactEmail(email: string): string;
4
+ export declare const __testInternals: {
5
+ normalizeCredentialValue: typeof normalizeCredentialValue;
6
+ };
7
+ export {};
@@ -0,0 +1,28 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { CliError } from './errors.js';
3
+ function normalizeCredentialValue(value) {
4
+ return typeof value === 'string' ? value.trim() : '';
5
+ }
6
+ export function fingerprintSecret(value) {
7
+ const normalized = normalizeCredentialValue(value);
8
+ if (!normalized) {
9
+ throw new CliError('Cannot fingerprint an empty secret value.', {
10
+ code: 'SECRET_FINGERPRINT_VALUE_REQUIRED',
11
+ exitCode: 2,
12
+ });
13
+ }
14
+ return `sha256:${createHash('sha256').update(normalized).digest('hex')}`;
15
+ }
16
+ export function redactEmail(email) {
17
+ const normalized = normalizeCredentialValue(email);
18
+ const [localPart, domainPart] = normalized.split('@');
19
+ if (!localPart || !domainPart) {
20
+ return '****';
21
+ }
22
+ if (localPart.length <= 2) {
23
+ return `****@${domainPart}`;
24
+ }
25
+ return `${localPart.slice(0, 2)}****@${domainPart}`;
26
+ }
27
+ export const __testInternals = { normalizeCredentialValue };
28
+ //# sourceMappingURL=credential-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-safety.js","sourceRoot":"","sources":["../../../src/lib/credential-safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,SAAS,wBAAwB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,QAAQ,CAAC,2CAA2C,EAAE;YAC9D,IAAI,EAAE,mCAAmC;YACzC,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,UAAU,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,UAAU,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,wBAAwB,EAAE,CAAC","sourcesContent":["import { createHash } from 'node:crypto';\nimport { CliError } from './errors.js';\n\nfunction normalizeCredentialValue(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nexport function fingerprintSecret(value: string): string {\n const normalized = normalizeCredentialValue(value);\n if (!normalized) {\n throw new CliError('Cannot fingerprint an empty secret value.', {\n code: 'SECRET_FINGERPRINT_VALUE_REQUIRED',\n exitCode: 2,\n });\n }\n\n return `sha256:${createHash('sha256').update(normalized).digest('hex')}`;\n}\n\nexport function redactEmail(email: string): string {\n const normalized = normalizeCredentialValue(email);\n const [localPart, domainPart] = normalized.split('@');\n if (!localPart || !domainPart) {\n return '****';\n }\n\n if (localPart.length <= 2) {\n return `****@${domainPart}`;\n }\n\n return `${localPart.slice(0, 2)}****@${domainPart}`;\n}\n\nexport const __testInternals = { normalizeCredentialValue };\n"]}
@@ -11,6 +11,7 @@ export type DatasetCommandTransport = {
11
11
  };
12
12
  declare function readOptionalRuleVerification(extraData?: JsonObject): boolean | null | undefined;
13
13
  declare function readOptionalModelId(extraData: JsonObject | undefined, allowNull: boolean): string | null | undefined;
14
+ declare function readOptionalModelVersion(extraData: JsonObject | undefined): string | null | undefined;
14
15
  export declare function deriveSupabaseFunctionsBaseUrl(apiBaseUrl: string): string;
15
16
  export declare function buildDatasetCommandTransport(options: {
16
17
  runtime: SupabaseDataRuntime;
@@ -48,6 +49,7 @@ export declare function deleteDatasetRecord(options: {
48
49
  export declare const __testInternals: {
49
50
  deriveSupabaseFunctionsBaseUrl: typeof deriveSupabaseFunctionsBaseUrl;
50
51
  readOptionalModelId: typeof readOptionalModelId;
52
+ readOptionalModelVersion: typeof readOptionalModelVersion;
51
53
  readOptionalRuleVerification: typeof readOptionalRuleVerification;
52
54
  };
53
55
  export {};
@@ -45,6 +45,17 @@ function readOptionalModelId(extraData, allowNull) {
45
45
  }
46
46
  return undefined;
47
47
  }
48
+ function readOptionalModelVersion(extraData) {
49
+ if (!extraData) {
50
+ return undefined;
51
+ }
52
+ const value = extraData.modelVersion ?? extraData.model_version;
53
+ const trimmed = trimToken(value);
54
+ if (trimmed) {
55
+ return trimmed;
56
+ }
57
+ return value === null ? null : undefined;
58
+ }
48
59
  function requireCommandSuccessPayload(payload, url) {
49
60
  const normalized = requireRemoteOkPayload(payload, url);
50
61
  if (!isRecord(normalized) || normalized.ok !== true) {
@@ -111,6 +122,10 @@ export async function createDatasetRecord(options) {
111
122
  if (modelId !== undefined) {
112
123
  body.modelId = modelId;
113
124
  }
125
+ const modelVersion = readOptionalModelVersion(options.extraData);
126
+ if (modelVersion !== undefined) {
127
+ body.modelVersion = modelVersion;
128
+ }
114
129
  const ruleVerification = readOptionalRuleVerification(options.extraData);
115
130
  if (ruleVerification !== undefined) {
116
131
  body.ruleVerification = ruleVerification;
@@ -133,6 +148,10 @@ export async function saveDraftDatasetRecord(options) {
133
148
  if (modelId !== undefined) {
134
149
  body.modelId = modelId;
135
150
  }
151
+ const modelVersion = readOptionalModelVersion(options.extraData);
152
+ if (modelVersion !== undefined) {
153
+ body.modelVersion = modelVersion;
154
+ }
136
155
  const ruleVerification = readOptionalRuleVerification(options.extraData);
137
156
  if (ruleVerification !== undefined) {
138
157
  body.ruleVerification = ruleVerification;
@@ -158,6 +177,7 @@ export async function deleteDatasetRecord(options) {
158
177
  export const __testInternals = {
159
178
  deriveSupabaseFunctionsBaseUrl,
160
179
  readOptionalModelId,
180
+ readOptionalModelVersion,
161
181
  readOptionalRuleVerification,
162
182
  };
163
183
  //# sourceMappingURL=dataset-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataset-command.js","sourceRoot":"","sources":["../../../src/lib/dataset-command.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport { postJson, requireRemoteOkPayload } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseDataRuntime,\n} from './supabase-client.js';\nimport { createSupabaseDataRuntime } from './supabase-session.js';\n\ntype JsonObject = Record<string, unknown>;\n\nexport type DatasetCommandTable =\n | 'contacts'\n | 'sources'\n | 'unitgroups'\n | 'flowproperties'\n | 'flows'\n | 'processes'\n | 'lifecyclemodels';\n\nexport type DatasetCommandTransport = {\n functionsBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n};\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 | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction readOptionalRuleVerification(extraData?: JsonObject): boolean | null | undefined {\n if (!extraData) {\n return undefined;\n }\n\n if ('ruleVerification' in extraData) {\n const value = extraData.ruleVerification;\n if (typeof value === 'boolean' || value === null) {\n return value;\n }\n return undefined;\n }\n\n if ('rule_verification' in extraData) {\n const value = extraData.rule_verification;\n if (typeof value === 'boolean' || value === null) {\n return value;\n }\n }\n\n return undefined;\n}\n\nfunction readOptionalModelId(\n extraData: JsonObject | undefined,\n allowNull: boolean,\n): string | null | undefined {\n if (!extraData) {\n return undefined;\n }\n\n const value = extraData.modelId ?? extraData.model_id;\n const trimmed = trimToken(value);\n if (trimmed) {\n return trimmed;\n }\n\n if (allowNull && value === null) {\n return null;\n }\n\n return undefined;\n}\n\nfunction requireCommandSuccessPayload(payload: unknown, url: string): JsonObject {\n const normalized = requireRemoteOkPayload(payload, url);\n if (!isRecord(normalized) || normalized.ok !== true) {\n throw new CliError(`Dataset command returned an unexpected payload for ${url}`, {\n code: 'REMOTE_RESPONSE_INVALID',\n exitCode: 1,\n details: normalized,\n });\n }\n\n return normalized;\n}\n\nasync function invokeDatasetCommand(options: {\n transport: DatasetCommandTransport;\n commandName: 'app_dataset_create' | 'app_dataset_save_draft' | 'app_dataset_delete';\n body: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const url = `${options.transport.functionsBaseUrl}/${options.commandName}`;\n try {\n options.beforeDispatch?.();\n } catch {\n throw new CliError('Dataset command was blocked before request dispatch.', {\n code: 'DATASET_COMMAND_BEFORE_DISPATCH_FAILED',\n exitCode: 1,\n });\n }\n return requireCommandSuccessPayload(\n await postJson({\n url,\n headers: {\n ...buildSupabaseAuthHeaders(\n options.transport.publishableKey,\n options.transport.accessToken,\n ),\n 'Content-Type': 'application/json',\n },\n body: options.body,\n timeoutMs: options.transport.timeoutMs,\n fetchImpl: options.transport.fetchImpl,\n }),\n url,\n );\n}\n\nexport function deriveSupabaseFunctionsBaseUrl(apiBaseUrl: string): string {\n return `${deriveSupabaseProjectBaseUrl(apiBaseUrl)}/functions/v1`;\n}\n\nexport async function buildDatasetCommandTransport(options: {\n runtime: SupabaseDataRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<DatasetCommandTransport> {\n return {\n functionsBaseUrl: deriveSupabaseFunctionsBaseUrl(options.runtime.apiBaseUrl),\n publishableKey: options.runtime.publishableKey,\n accessToken: await options.runtime.getAccessToken(),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n };\n}\n\nexport async function resolveDatasetCommandTransport(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<DatasetCommandTransport> {\n return buildDatasetCommandTransport({\n runtime: createSupabaseDataRuntime({\n runtime: requireSupabaseRestRuntime(options.env),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n }),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n}\n\nexport async function createDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n payload: JsonObject;\n extraData?: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const body: JsonObject = {\n table: options.table,\n id: options.id,\n jsonOrdered: options.payload,\n };\n const modelId = readOptionalModelId(options.extraData, true);\n if (modelId !== undefined) {\n body.modelId = modelId;\n }\n const ruleVerification = readOptionalRuleVerification(options.extraData);\n if (ruleVerification !== undefined) {\n body.ruleVerification = ruleVerification;\n }\n\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_create',\n body,\n beforeDispatch: options.beforeDispatch,\n });\n}\n\nexport async function saveDraftDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n version: string;\n payload: JsonObject;\n extraData?: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const body: JsonObject = {\n table: options.table,\n id: options.id,\n version: options.version,\n jsonOrdered: options.payload,\n };\n const modelId = readOptionalModelId(options.extraData, false);\n if (modelId !== undefined) {\n body.modelId = modelId;\n }\n const ruleVerification = readOptionalRuleVerification(options.extraData);\n if (ruleVerification !== undefined) {\n body.ruleVerification = ruleVerification;\n }\n\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_save_draft',\n body,\n beforeDispatch: options.beforeDispatch,\n });\n}\n\nexport async function deleteDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n version: string;\n}): Promise<JsonObject> {\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_delete',\n body: {\n table: options.table,\n id: options.id,\n version: options.version,\n },\n });\n}\n\nexport const __testInternals = {\n deriveSupabaseFunctionsBaseUrl,\n readOptionalModelId,\n readOptionalRuleVerification,\n};\n"]}
1
+ {"version":3,"file":"dataset-command.js","sourceRoot":"","sources":["../../../src/lib/dataset-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,0BAA0B,GAE3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAqBlE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,SAAS,4BAA4B,CAAC,SAAsB;IAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,kBAAkB,IAAI,SAAS,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,SAAS,CAAC,gBAAgB,CAAC;QACzC,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,mBAAmB,IAAI,SAAS,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,SAAS,CAAC,iBAAiB,CAAC;QAC1C,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB,CAC1B,SAAiC,EACjC,SAAkB;IAElB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,wBAAwB,CAAC,SAAiC;IACjE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,aAAa,CAAC;IAChE,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED,SAAS,4BAA4B,CAAC,OAAgB,EAAE,GAAW;IACjE,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,IAAI,QAAQ,CAAC,sDAAsD,GAAG,EAAE,EAAE;YAC9E,IAAI,EAAE,yBAAyB;YAC/B,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,OAKnC;IACC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAC3E,IAAI,CAAC;QACH,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,sDAAsD,EAAE;YACzE,IAAI,EAAE,wCAAwC;YAC9C,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,4BAA4B,CACjC,MAAM,QAAQ,CAAC;QACb,GAAG;QACH,OAAO,EAAE;YACP,GAAG,wBAAwB,CACzB,OAAO,CAAC,SAAS,CAAC,cAAc,EAChC,OAAO,CAAC,SAAS,CAAC,WAAW,CAC9B;YACD,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS;KACvC,CAAC,EACF,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,UAAkB;IAC/D,OAAO,GAAG,4BAA4B,CAAC,UAAU,CAAC,eAAe,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,OAIlD;IACC,OAAO;QACL,gBAAgB,EAAE,8BAA8B,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;QAC5E,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc;QAC9C,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE;QACnD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,OAIpD;IACC,OAAO,4BAA4B,CAAC;QAClC,OAAO,EAAE,yBAAyB,CAAC;YACjC,OAAO,EAAE,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC;YAChD,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;QACF,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAOzC;IACC,MAAM,IAAI,GAAe;QACvB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,WAAW,EAAE,OAAO,CAAC,OAAO;KAC7B,CAAC;IACF,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IACD,MAAM,YAAY,GAAG,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IACD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzE,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,OAAO,oBAAoB,CAAC;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW,EAAE,oBAAoB;QACjC,IAAI;QACJ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAQ5C;IACC,MAAM,IAAI,GAAe;QACvB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,OAAO;KAC7B,CAAC;IACF,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IACD,MAAM,YAAY,GAAG,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IACD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzE,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,OAAO,oBAAoB,CAAC;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW,EAAE,wBAAwB;QACrC,IAAI;QACJ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAKzC;IACC,OAAO,oBAAoB,CAAC;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW,EAAE,oBAAoB;QACjC,IAAI,EAAE;YACJ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,8BAA8B;IAC9B,mBAAmB;IACnB,wBAAwB;IACxB,4BAA4B;CAC7B,CAAC","sourcesContent":["import { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport { postJson, requireRemoteOkPayload } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseDataRuntime,\n} from './supabase-client.js';\nimport { createSupabaseDataRuntime } from './supabase-session.js';\n\ntype JsonObject = Record<string, unknown>;\n\nexport type DatasetCommandTable =\n | 'contacts'\n | 'sources'\n | 'unitgroups'\n | 'flowproperties'\n | 'flows'\n | 'processes'\n | 'lifecyclemodels';\n\nexport type DatasetCommandTransport = {\n functionsBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n};\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 | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction readOptionalRuleVerification(extraData?: JsonObject): boolean | null | undefined {\n if (!extraData) {\n return undefined;\n }\n\n if ('ruleVerification' in extraData) {\n const value = extraData.ruleVerification;\n if (typeof value === 'boolean' || value === null) {\n return value;\n }\n return undefined;\n }\n\n if ('rule_verification' in extraData) {\n const value = extraData.rule_verification;\n if (typeof value === 'boolean' || value === null) {\n return value;\n }\n }\n\n return undefined;\n}\n\nfunction readOptionalModelId(\n extraData: JsonObject | undefined,\n allowNull: boolean,\n): string | null | undefined {\n if (!extraData) {\n return undefined;\n }\n\n const value = extraData.modelId ?? extraData.model_id;\n const trimmed = trimToken(value);\n if (trimmed) {\n return trimmed;\n }\n\n if (allowNull && value === null) {\n return null;\n }\n\n return undefined;\n}\n\nfunction readOptionalModelVersion(extraData: JsonObject | undefined): string | null | undefined {\n if (!extraData) {\n return undefined;\n }\n\n const value = extraData.modelVersion ?? extraData.model_version;\n const trimmed = trimToken(value);\n if (trimmed) {\n return trimmed;\n }\n\n return value === null ? null : undefined;\n}\n\nfunction requireCommandSuccessPayload(payload: unknown, url: string): JsonObject {\n const normalized = requireRemoteOkPayload(payload, url);\n if (!isRecord(normalized) || normalized.ok !== true) {\n throw new CliError(`Dataset command returned an unexpected payload for ${url}`, {\n code: 'REMOTE_RESPONSE_INVALID',\n exitCode: 1,\n details: normalized,\n });\n }\n\n return normalized;\n}\n\nasync function invokeDatasetCommand(options: {\n transport: DatasetCommandTransport;\n commandName: 'app_dataset_create' | 'app_dataset_save_draft' | 'app_dataset_delete';\n body: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const url = `${options.transport.functionsBaseUrl}/${options.commandName}`;\n try {\n options.beforeDispatch?.();\n } catch {\n throw new CliError('Dataset command was blocked before request dispatch.', {\n code: 'DATASET_COMMAND_BEFORE_DISPATCH_FAILED',\n exitCode: 1,\n });\n }\n return requireCommandSuccessPayload(\n await postJson({\n url,\n headers: {\n ...buildSupabaseAuthHeaders(\n options.transport.publishableKey,\n options.transport.accessToken,\n ),\n 'Content-Type': 'application/json',\n },\n body: options.body,\n timeoutMs: options.transport.timeoutMs,\n fetchImpl: options.transport.fetchImpl,\n }),\n url,\n );\n}\n\nexport function deriveSupabaseFunctionsBaseUrl(apiBaseUrl: string): string {\n return `${deriveSupabaseProjectBaseUrl(apiBaseUrl)}/functions/v1`;\n}\n\nexport async function buildDatasetCommandTransport(options: {\n runtime: SupabaseDataRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<DatasetCommandTransport> {\n return {\n functionsBaseUrl: deriveSupabaseFunctionsBaseUrl(options.runtime.apiBaseUrl),\n publishableKey: options.runtime.publishableKey,\n accessToken: await options.runtime.getAccessToken(),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n };\n}\n\nexport async function resolveDatasetCommandTransport(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<DatasetCommandTransport> {\n return buildDatasetCommandTransport({\n runtime: createSupabaseDataRuntime({\n runtime: requireSupabaseRestRuntime(options.env),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n }),\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n}\n\nexport async function createDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n payload: JsonObject;\n extraData?: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const body: JsonObject = {\n table: options.table,\n id: options.id,\n jsonOrdered: options.payload,\n };\n const modelId = readOptionalModelId(options.extraData, true);\n if (modelId !== undefined) {\n body.modelId = modelId;\n }\n const modelVersion = readOptionalModelVersion(options.extraData);\n if (modelVersion !== undefined) {\n body.modelVersion = modelVersion;\n }\n const ruleVerification = readOptionalRuleVerification(options.extraData);\n if (ruleVerification !== undefined) {\n body.ruleVerification = ruleVerification;\n }\n\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_create',\n body,\n beforeDispatch: options.beforeDispatch,\n });\n}\n\nexport async function saveDraftDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n version: string;\n payload: JsonObject;\n extraData?: JsonObject;\n beforeDispatch?: () => void;\n}): Promise<JsonObject> {\n const body: JsonObject = {\n table: options.table,\n id: options.id,\n version: options.version,\n jsonOrdered: options.payload,\n };\n const modelId = readOptionalModelId(options.extraData, false);\n if (modelId !== undefined) {\n body.modelId = modelId;\n }\n const modelVersion = readOptionalModelVersion(options.extraData);\n if (modelVersion !== undefined) {\n body.modelVersion = modelVersion;\n }\n const ruleVerification = readOptionalRuleVerification(options.extraData);\n if (ruleVerification !== undefined) {\n body.ruleVerification = ruleVerification;\n }\n\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_save_draft',\n body,\n beforeDispatch: options.beforeDispatch,\n });\n}\n\nexport async function deleteDatasetRecord(options: {\n transport: DatasetCommandTransport;\n table: DatasetCommandTable;\n id: string;\n version: string;\n}): Promise<JsonObject> {\n return invokeDatasetCommand({\n transport: options.transport,\n commandName: 'app_dataset_delete',\n body: {\n table: options.table,\n id: options.id,\n version: options.version,\n },\n });\n}\n\nexport const __testInternals = {\n deriveSupabaseFunctionsBaseUrl,\n readOptionalModelId,\n readOptionalModelVersion,\n readOptionalRuleVerification,\n};\n"]}
@@ -951,7 +951,9 @@ function executionBatchActionContent(action) {
951
951
  };
952
952
  }
953
953
  async function renewExecutionOwnerToken(options) {
954
- const accessToken = await options.runtime.getAccessToken();
954
+ const accessToken = options.runtime.refreshAccessToken
955
+ ? await options.runtime.refreshAccessToken()
956
+ : await options.runtime.getAccessToken();
955
957
  const actor = decodeExecutionActor(accessToken);
956
958
  if (actor.user_id !== options.contract.owner.user_id ||
957
959
  actor.email !== options.contract.owner.email) {