@tailor-platform/sdk 1.57.0 → 1.59.0

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 (88) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/{application-CdkoGX27.mjs → application-FnWOxBk7.mjs} +48 -28
  3. package/dist/application-FnWOxBk7.mjs.map +1 -0
  4. package/dist/application-VOdgMtOD.mjs +4 -0
  5. package/dist/{authconnection-TsdLYaLs.d.mts → authconnection-BIYzEh2p.d.mts} +2 -2
  6. package/dist/authconnection-D8SJGMpj.mjs.map +1 -1
  7. package/dist/cli/erd-viewer-assets/app.js +4 -4
  8. package/dist/cli/index.mjs +172 -20
  9. package/dist/cli/index.mjs.map +1 -1
  10. package/dist/cli/lib.d.mts +581 -2
  11. package/dist/cli/lib.mjs +4 -3
  12. package/dist/cli/lib.mjs.map +1 -1
  13. package/dist/client-B-jRdlC_.mjs +4 -0
  14. package/dist/{client-DLPEPJ_s.mjs → client-W5P4NYYX.mjs} +154 -12
  15. package/dist/client-W5P4NYYX.mjs.map +1 -0
  16. package/dist/configure/index.d.mts +2 -2
  17. package/dist/configure/index.mjs +8 -8
  18. package/dist/configure/index.mjs.map +1 -1
  19. package/dist/{crashreport-Bm2mN5tg.mjs → crashreport-D3DvAzdg.mjs} +3 -3
  20. package/dist/crashreport-D3DvAzdg.mjs.map +1 -0
  21. package/dist/{crashreport-C5oHvHUC.mjs → crashreport-lnVTnbB5.mjs} +1 -1
  22. package/dist/file-B58Dm-2P.mjs.map +1 -1
  23. package/dist/{file-VTJbbOL3.d.mts → file-BzK8z3X-.d.mts} +2 -2
  24. package/dist/globals-ByrCoDip.mjs +109 -0
  25. package/dist/globals-ByrCoDip.mjs.map +1 -0
  26. package/dist/iconv-DreIffeM.mjs.map +1 -1
  27. package/dist/{iconv-Chu6Hit2.d.mts → iconv-kwrmd1U_.d.mts} +2 -2
  28. package/dist/{idp-Di9N4FSJ.d.mts → idp-BlBPtXJ-.d.mts} +2 -2
  29. package/dist/idp-Ch95ag8h.mjs.map +1 -1
  30. package/dist/{index-B61gFI9a.d.mts → index-Cr6ufjZ5.d.mts} +12 -9
  31. package/dist/{index-DTSQthwF.d.mts → index-DRhMpdnA.d.mts} +7 -7
  32. package/dist/{job-CEAJLiGp.mjs → job-BpsFXPbi.mjs} +8 -17
  33. package/dist/job-BpsFXPbi.mjs.map +1 -0
  34. package/dist/mock-Dpu__UeJ.mjs +805 -0
  35. package/dist/mock-Dpu__UeJ.mjs.map +1 -0
  36. package/dist/registry-D0uB0OrK.mjs +178 -0
  37. package/dist/registry-D0uB0OrK.mjs.map +1 -0
  38. package/dist/{repl-editor-ihh8koiR.mjs → repl-editor-Y9QJDL0K.mjs} +3 -9
  39. package/dist/{repl-editor-ihh8koiR.mjs.map → repl-editor-Y9QJDL0K.mjs.map} +1 -1
  40. package/dist/runtime/authconnection.d.mts +1 -1
  41. package/dist/runtime/file.d.mts +1 -1
  42. package/dist/runtime/globals.d.mts +5 -5
  43. package/dist/runtime/iconv.d.mts +1 -1
  44. package/dist/runtime/idp.d.mts +1 -1
  45. package/dist/runtime/index.d.mts +7 -7
  46. package/dist/runtime/secretmanager.d.mts +1 -1
  47. package/dist/runtime/workflow.d.mts +1 -1
  48. package/dist/{runtime-1YuaoNr8.mjs → runtime-CrUa8Z2k.mjs} +383 -402
  49. package/dist/runtime-CrUa8Z2k.mjs.map +1 -0
  50. package/dist/secretmanager-B9h-U_8U.mjs.map +1 -1
  51. package/dist/{secretmanager-BhpDmxwT.d.mts → secretmanager-CKLB3wAQ.d.mts} +2 -2
  52. package/dist/utils/test/index.d.mts +6 -6
  53. package/dist/utils/test/index.mjs +7 -7
  54. package/dist/utils/test/index.mjs.map +1 -1
  55. package/dist/vitest/environment.mjs +3 -4
  56. package/dist/vitest/environment.mjs.map +1 -1
  57. package/dist/vitest/index.d.mts +167 -120
  58. package/dist/vitest/index.mjs +6 -6
  59. package/dist/vitest/index.mjs.map +1 -1
  60. package/dist/vitest/setup.d.mts +1 -1
  61. package/dist/vitest/setup.mjs +4 -3
  62. package/dist/vitest/setup.mjs.map +1 -1
  63. package/dist/workflow--aPbA8Uq.mjs.map +1 -1
  64. package/dist/{workflow-dYYH7QFa.d.mts → workflow-CMamswkK.d.mts} +2 -2
  65. package/dist/{workflow.generated-Kz-nQrTf.d.mts → workflow.generated-CV77NlFp.d.mts} +3 -2
  66. package/docs/cli/application.md +5 -5
  67. package/docs/cli/auth.md +55 -6
  68. package/docs/cli/function.md +2 -2
  69. package/docs/cli/staticwebsite.md +137 -0
  70. package/docs/cli-reference.md +17 -14
  71. package/docs/configuration.md +1 -1
  72. package/docs/generator/builtin.md +1 -1
  73. package/docs/runtime.md +9 -12
  74. package/docs/services/auth.md +0 -11
  75. package/docs/services/staticwebsite.md +13 -0
  76. package/docs/testing.md +92 -85
  77. package/package.json +8 -8
  78. package/dist/application-CdkoGX27.mjs.map +0 -1
  79. package/dist/application-x_mURdR0.mjs +0 -4
  80. package/dist/client-DLPEPJ_s.mjs.map +0 -1
  81. package/dist/client-DrzwCD1W.mjs +0 -4
  82. package/dist/crashreport-Bm2mN5tg.mjs.map +0 -1
  83. package/dist/job-CEAJLiGp.mjs.map +0 -1
  84. package/dist/mock-B6PI49C_.mjs +0 -844
  85. package/dist/mock-B6PI49C_.mjs.map +0 -1
  86. package/dist/runtime-1YuaoNr8.mjs.map +0 -1
  87. package/dist/test-env-key-CSnK4W1Y.mjs +0 -30
  88. package/dist/test-env-key-CSnK4W1Y.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
 
2
2
  import { t as db } from "./schema-DKsNhbav.mjs";
3
- import { $ as FilterSchema, A as FunctionExecution_Status, B as AuthOAuth2Client_GrantType, C as TailorDBType_Permission_Operator, D as IdPLang, E as PipelineResolver_OperationType, F as AuthConnection_Type, H as AuthSCIMAttribute_Type, I as AuthHookPoint, J as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, K as TenantProviderConfig_TenantProviderType, L as AuthIDPConfig_AuthType, M as ExecutorJobStatus, N as ExecutorTargetType, O as IdPPermissionOperator, P as ExecutorTriggerType, Q as Condition_Operator, R as AuthInvokerSchema, S as TailorDBGQLPermission_Permit, T as TailorDBType_PermitAction, U as AuthSCIMAttribute_Uniqueness, V as AuthSCIMAttribute_Mutability, W as AuthSCIMConfig_AuthorizationType, X as Subgraph_ServiceType, Y as ApplicationSchemaUpdateAttemptStatus, Z as ConditionSchema, _ as WorkspacePlatformUserRole, a as fetchMachineUserToken, b as TailorDBGQLPermission_Action, d as initOperatorClient, et as PageDirection, g as OperatorService, h as userAgent, i as fetchAll, k as IdPPermissionPermit, m as resolveStaticWebsiteUrls, o as fetchPaged, p as platformBaseUrl, q as UserProfileProviderConfig_UserProfileProviderType, v as WorkflowExecution_Status, w as TailorDBType_Permission_Permit, x as TailorDBGQLPermission_Operator, y as WorkflowJobExecution_Status, z as AuthOAuth2Client_ClientType } from "./client-DLPEPJ_s.mjs";
3
+ import { $ as Subgraph_ServiceType, A as IdPLang, B as AuthIDPConfig_AuthType, C as TailorDBGQLPermission_Operator, D as TailorDBType_PermitAction, E as TailorDBType_Permission_Permit, F as ExecutorJobStatus, G as AuthSCIMAttribute_Type, H as AuthOAuth2Client_ClientType, I as ExecutorTargetType, K as AuthSCIMAttribute_Uniqueness, L as ExecutorTriggerType, M as IdPPermissionPermit, N as FunctionExecution_Status, Q as ApplicationSchemaUpdateAttemptStatus, R as AuthConnection_Type, S as TailorDBGQLPermission_Action, T as TailorDBType_Permission_Operator, U as AuthOAuth2Client_GrantType, V as AuthInvokerSchema, W as AuthSCIMAttribute_Mutability, X as UserProfileProviderConfig_UserProfileProviderType, Y as TenantProviderConfig_TenantProviderType, Z as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, _ as userAgent, a as fetchAll, b as WorkflowExecution_Status, et as ConditionSchema, f as initOperatorClient, h as resolveStaticWebsiteUrls, j as IdPPermissionOperator, k as PipelineResolver_OperationType, m as platformBaseUrl, nt as FilterSchema, o as fetchMachineUserToken, q as AuthSCIMConfig_AuthorizationType, rt as PageDirection, s as fetchPaged, tt as Condition_Operator, v as OperatorService, w as TailorDBGQLPermission_Permit, x as WorkflowJobExecution_Status, y as WorkspacePlatformUserRole, z as AuthHookPoint } from "./client-W5P4NYYX.mjs";
4
4
  import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-DpJyJvNz.mjs";
5
- import { C as loadConfig, D as loadConfigPath, E as loadAccessToken, M as writePlatformConfig, O as loadWorkspaceId, S as hashFile, b as getDistDir, c as createExecutorService, d as buildExecutorArgsExpr, f as buildResolverOperationHookExpr, h as loadFilesWithIgnores, k as readPlatformConfig, m as stringifyFunction, n as generatePluginFilesIfNeeded, p as TailorDBTypeSchema, r as loadApplication, s as HTTP_METHODS, t as defineApplication, y as createBundleCache } from "./application-CdkoGX27.mjs";
5
+ import { A as readPlatformConfig, C as hashFile, D as loadAccessToken, N as writePlatformConfig, O as loadConfigPath, b as createBundleCache, c as createExecutorService, d as buildExecutorArgsExpr, f as buildResolverOperationHookExpr, g as platformBundleDefinePlugin, h as loadFilesWithIgnores, k as loadWorkspaceId, m as stringifyFunction, n as generatePluginFilesIfNeeded, p as TailorDBTypeSchema, r as loadApplication, s as HTTP_METHODS, t as defineApplication, w as loadConfig, x as getDistDir } from "./application-FnWOxBk7.mjs";
6
6
  import { t as multiline } from "./multiline-Cf9ODpr1.mjs";
7
7
  import { t as readPackageJson } from "./package-json-DcQApfPQ.mjs";
8
8
  import { n as isCLIError, t as createCLIError } from "./errors-EsY4XO6O.mjs";
@@ -337,7 +337,7 @@ async function apiCall(options) {
337
337
  //#region src/cli/commands/api/proto-reflect.ts
338
338
  const UNARY_METHODS = OperatorService.methods.filter((m) => m.methodKind === "unary");
339
339
  function listMethodNames() {
340
- return UNARY_METHODS.map((m) => m.name).sort();
340
+ return UNARY_METHODS.map((m) => m.name).toSorted();
341
341
  }
342
342
  /**
343
343
  * Returns every accepted form of the `endpoint` positional — bare method name
@@ -348,7 +348,7 @@ function listMethodNames() {
348
348
  * @returns Sorted list of accepted endpoint values
349
349
  */
350
350
  function listMethodChoices() {
351
- return UNARY_METHODS.flatMap((m) => [m.name, `${OperatorService.typeName}/${m.name}`]).sort();
351
+ return UNARY_METHODS.flatMap((m) => [m.name, `${OperatorService.typeName}/${m.name}`]).toSorted();
352
352
  }
353
353
  function getMethodDescriptor(methodName) {
354
354
  return UNARY_METHODS.find((m) => m.name === methodName);
@@ -636,7 +636,7 @@ const inspectCommand = defineAppCommand({
636
636
  const listCommand$10 = defineAppCommand({
637
637
  name: "list",
638
638
  description: "List all invocable OperatorService methods.",
639
- notes: "Only unary RPCs are listed; streaming methods are excluded because `tailor-sdk api run` issues a single JSON POST and reads one JSON response.",
639
+ notes: "Only single-request (non-streaming) methods are listed, because the CLI issues a single JSON request and reads one JSON response.",
640
640
  args: z.object({}).strict(),
641
641
  run: () => {
642
642
  const names = listMethodNames();
@@ -793,7 +793,7 @@ const apiCommand = defineAppCommand({
793
793
  description: "Call Tailor Platform API endpoints directly.",
794
794
  notes: `Use \`tailor-sdk api list\` to enumerate invocable methods and \`tailor-sdk api inspect <endpoint>\` to print an endpoint's input message tree (combine with \`--json\` for machine-readable output).
795
795
 
796
- The request body is inferred from the proto definition of the target endpoint, and commonly required fields are auto-injected so they can be omitted from \`--body\`:
796
+ The request body is inferred from the target endpoint's request schema, and commonly required fields are auto-injected so they can be omitted from \`--body\`:
797
797
 
798
798
  - \`workspaceId\` — resolved from \`-w\` / \`TAILOR_PLATFORM_WORKSPACE_ID\` / the selected profile.
799
799
  - \`namespaceName\` — resolved from \`tailor.config.ts\` based on the endpoint's service:
@@ -802,7 +802,7 @@ The request body is inferred from the proto definition of the target endpoint, a
802
802
 
803
803
  Values already present in \`--body\` are never overridden. If a value cannot be resolved (e.g. no config found), injection is silently skipped and the server-side validation error takes precedence.
804
804
 
805
- Use \`--field key=value\` (repeatable) to set request body fields without writing JSON. Dotted keys (e.g. \`application.name=foo\`) build nested objects. \`--field\` overrides matching fields in \`--body\` and tab-completes from the endpoint's proto schema.`,
805
+ Use \`--field key=value\` (repeatable) to set request body fields without writing JSON. Dotted keys (e.g. \`application.name=foo\`) build nested objects. \`--field\` overrides matching fields in \`--body\` and tab-completes from the endpoint's request schema.`,
806
806
  examples: [
807
807
  {
808
808
  cmd: "GetApplication -b '{\"applicationName\":\"app-1\"}'",
@@ -1694,7 +1694,7 @@ function formatPlanSummary(summary) {
1694
1694
  */
1695
1695
  function stableStringify(value) {
1696
1696
  if (Array.isArray(value)) return `[${value.map((item) => item === void 0 ? "null" : stableStringify(item)).join(",")}]`;
1697
- if (value && typeof value === "object") return `{${Object.entries(value).filter(([key, entryValue]) => key !== "$typeName" && entryValue !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`;
1697
+ if (value && typeof value === "object") return `{${Object.entries(value).filter(([key, entryValue]) => key !== "$typeName" && entryValue !== void 0).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`;
1698
1698
  if (typeof value === "bigint") return JSON.stringify(value.toString());
1699
1699
  return JSON.stringify(value);
1700
1700
  }
@@ -1713,7 +1713,7 @@ function normalizeProtoConfig(value) {
1713
1713
  * @returns Sorted values
1714
1714
  */
1715
1715
  function normalizeStringArray(values) {
1716
- return [...values ?? []].sort();
1716
+ return (values ?? []).toSorted();
1717
1717
  }
1718
1718
  /**
1719
1719
  * Compare two values after proto normalization.
@@ -1735,6 +1735,16 @@ function areNormalizedEqual(left, right) {
1735
1735
  function trnPrefix(workspaceId) {
1736
1736
  return `trn:v1:workspace:${workspaceId}`;
1737
1737
  }
1738
+ /**
1739
+ * Build the TRN for a workspace resource.
1740
+ * @param workspaceId - Workspace ID
1741
+ * @param kind - Resource kind segment
1742
+ * @param name - Resource name
1743
+ * @returns Fully-qualified TRN string
1744
+ */
1745
+ function resourceTrn(workspaceId, kind, name) {
1746
+ return `${trnPrefix(workspaceId)}:${kind}:${name}`;
1747
+ }
1738
1748
  const sdkNameLabelKey = "sdk-name";
1739
1749
  const sdkVersionLabelKey = "sdk-version";
1740
1750
  const sdkAppIdLabelKey = "sdk-app-id";
@@ -1784,7 +1794,7 @@ async function buildMetaRequest(params) {
1784
1794
  return {
1785
1795
  trn,
1786
1796
  labels: {
1787
- ...existingLabels ?? {},
1797
+ ...existingLabels,
1788
1798
  [sdkNameLabelKey]: appName,
1789
1799
  [sdkVersionLabelKey]: sdkVersion,
1790
1800
  ...appId ? { [sdkAppIdLabelKey]: toAppIdLabelValue(appId) } : {}
@@ -1817,17 +1827,14 @@ async function applyApplication(client, changeSet, phase = "create-update") {
1817
1827
  await client.deleteApplication(del.request);
1818
1828
  }));
1819
1829
  }
1820
- function trn$6(workspaceId, name) {
1821
- return `trn:v1:workspace:${workspaceId}:application:${name}`;
1822
- }
1823
1830
  function sortStrings(values) {
1824
- return [...values ?? []].sort();
1831
+ return (values ?? []).toSorted();
1825
1832
  }
1826
1833
  function normalizeSubgraphs(subgraphs) {
1827
1834
  return [...subgraphs ?? []].map((subgraph) => ({
1828
1835
  serviceType: subgraph.serviceType,
1829
1836
  serviceNamespace: subgraph.serviceNamespace ?? ""
1830
- })).sort((left, right) => {
1837
+ })).toSorted((left, right) => {
1831
1838
  if (left.serviceType !== right.serviceType) return left.serviceType - right.serviceType;
1832
1839
  return left.serviceNamespace.localeCompare(right.serviceNamespace);
1833
1840
  });
@@ -1841,7 +1848,7 @@ function normalizeHttpAdapters(httpAdapters) {
1841
1848
  outputScript: adapter.outputScript ?? "",
1842
1849
  enabled: adapter.enabled ?? true,
1843
1850
  priority: adapter.priority ?? 0
1844
- })).sort((left, right) => left.name.localeCompare(right.name));
1851
+ })).toSorted((left, right) => left.name.localeCompare(right.name));
1845
1852
  }
1846
1853
  function toComparableApplication(input) {
1847
1854
  return {
@@ -1944,7 +1951,7 @@ async function planApplication(context, httpAdapterBuildResult) {
1944
1951
  if (idpConfigs.length > 0) authIdpConfigName = idpConfigs[0].name;
1945
1952
  }
1946
1953
  const metaRequest = await buildMetaRequest({
1947
- trn: trn$6(workspaceId, application.name),
1954
+ trn: resourceTrn(workspaceId, "application", application.name),
1948
1955
  appName: application.name,
1949
1956
  appId: application.id
1950
1957
  });
@@ -2003,7 +2010,7 @@ async function planApplication(context, httpAdapterBuildResult) {
2003
2010
  }
2004
2011
  async function fetchAppLabels(client, workspaceId, appName) {
2005
2012
  try {
2006
- const { metadata } = await client.getMetadata({ trn: trn$6(workspaceId, appName) });
2013
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "application", appName) });
2007
2014
  return metadata?.labels;
2008
2015
  } catch (error) {
2009
2016
  if (error instanceof ConnectError && error.code === Code.NotFound) return;
@@ -2038,7 +2045,7 @@ function diffHttpAdapterDisplay(existingAdapters, desiredAdapters) {
2038
2045
  name,
2039
2046
  symbol: symbols.delete
2040
2047
  });
2041
- return entries.sort((left, right) => left.name.localeCompare(right.name)).map((entry) => `${entry.symbol} ${entry.name} (httpAdapter)`);
2048
+ return entries.toSorted((left, right) => left.name.localeCompare(right.name)).map((entry) => `${entry.symbol} ${entry.name} (httpAdapter)`);
2042
2049
  }
2043
2050
  function buildHttpAdapters(application, httpAdapterBuildResult) {
2044
2051
  const adapters = application.httpAdapterService?.adapters ?? [];
@@ -2133,9 +2140,6 @@ function hashValue(value) {
2133
2140
 
2134
2141
  //#endregion
2135
2142
  //#region src/cli/commands/deploy/auth-connection.ts
2136
- function connectionTrn(workspaceId, name) {
2137
- return `${trnPrefix(workspaceId)}:auth_connection:${name}`;
2138
- }
2139
2143
  function buildConnectionRequest(workspaceId, name, config) {
2140
2144
  return {
2141
2145
  workspaceId,
@@ -2203,7 +2207,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2203
2207
  });
2204
2208
  const existingConnections = {};
2205
2209
  await Promise.all(existingList.map(async (resource) => {
2206
- const { metadata } = await client.getMetadata({ trn: connectionTrn(workspaceId, resource.name) });
2210
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "auth_connection", resource.name) });
2207
2211
  existingConnections[resource.name] = {
2208
2212
  resource,
2209
2213
  label: metadata?.labels[sdkNameLabelKey],
@@ -2214,7 +2218,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2214
2218
  for (const [name, config] of Object.entries(desiredConnections)) {
2215
2219
  const existing = existingConnections[name];
2216
2220
  const metaRequest = await buildMetaRequest({
2217
- trn: connectionTrn(workspaceId, name),
2221
+ trn: resourceTrn(workspaceId, "auth_connection", name),
2218
2222
  appName,
2219
2223
  appId
2220
2224
  });
@@ -2232,7 +2236,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2232
2236
  const storedHash = state.connections?.[name];
2233
2237
  if (hasNonSecretFieldChanged(existing.resource, config) || currentHash !== storedHash) changeSet.replaces.push({
2234
2238
  name,
2235
- revokeRequest: {
2239
+ deleteRequest: {
2236
2240
  workspaceId,
2237
2241
  connectionName: name
2238
2242
  },
@@ -2302,7 +2306,7 @@ async function applyAuthConnections(client, result, phase) {
2302
2306
  await client.setMetadata(create.metaRequest);
2303
2307
  }));
2304
2308
  for (const replace of changeSet.replaces) {
2305
- await client.revokeAuthConnection(replace.revokeRequest);
2309
+ await client.deleteAuthConnection(replace.deleteRequest);
2306
2310
  await client.createAuthConnection(replace.createRequest);
2307
2311
  await client.setMetadata(replace.metaRequest);
2308
2312
  }
@@ -2322,7 +2326,7 @@ async function applyAuthConnections(client, result, phase) {
2322
2326
  saveSecretsState(state);
2323
2327
  } else if (phase === "delete-resources" || phase === "delete") {
2324
2328
  await Promise.all(changeSet.deletes.map(async (del) => {
2325
- await client.revokeAuthConnection(del.request);
2329
+ await client.deleteAuthConnection(del.request);
2326
2330
  }));
2327
2331
  if (changeSet.deletes.length > 0) {
2328
2332
  const state = loadSecretsState();
@@ -2345,9 +2349,6 @@ const CHUNK_SIZE = 64 * 1024;
2345
2349
  function computeContentHash(content) {
2346
2350
  return crypto$1.createHash("sha256").update(content, "utf-8").digest("hex");
2347
2351
  }
2348
- function functionRegistryTrn$1(workspaceId, name) {
2349
- return `trn:v1:workspace:${workspaceId}:function_registry:${name}`;
2350
- }
2351
2352
  const RESOLVER_PREFIX = "resolver--";
2352
2353
  const EXECUTOR_PREFIX = "executor--";
2353
2354
  const WORKFLOW_PREFIX = "workflow--";
@@ -2539,7 +2540,7 @@ async function planFunctionRegistry(client, workspaceId, appName, appId, entries
2539
2540
  });
2540
2541
  const existingMap = {};
2541
2542
  await Promise.all(existingFunctions.map(async (func) => {
2542
- const { metadata } = await client.getMetadata({ trn: functionRegistryTrn$1(workspaceId, func.name) });
2543
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "function_registry", func.name) });
2543
2544
  existingMap[func.name] = {
2544
2545
  resource: func,
2545
2546
  label: metadata?.labels[sdkNameLabelKey],
@@ -2549,7 +2550,7 @@ async function planFunctionRegistry(client, workspaceId, appName, appId, entries
2549
2550
  for (const entry of entries) {
2550
2551
  const existing = existingMap[entry.name];
2551
2552
  const metaRequest = await buildMetaRequest({
2552
- trn: functionRegistryTrn$1(workspaceId, entry.name),
2553
+ trn: resourceTrn(workspaceId, "function_registry", entry.name),
2553
2554
  appName,
2554
2555
  appId
2555
2556
  });
@@ -3104,9 +3105,6 @@ async function planIdP(context) {
3104
3105
  resourceOwners
3105
3106
  };
3106
3107
  }
3107
- function trn$5(workspaceId, name) {
3108
- return `trn:v1:workspace:${workspaceId}:idp:${name}`;
3109
- }
3110
3108
  function normalizeComparableUserAuthPolicy(policy) {
3111
3109
  return {
3112
3110
  useNonEmailIdentifier: policy?.useNonEmailIdentifier ?? false,
@@ -3117,7 +3115,7 @@ function normalizeComparableUserAuthPolicy(policy) {
3117
3115
  passwordRequireNumeric: policy?.passwordRequireNumeric ?? false,
3118
3116
  passwordMinLength: policy?.passwordMinLength ?? 0,
3119
3117
  passwordMaxLength: policy?.passwordMaxLength ?? 0,
3120
- allowedEmailDomains: [...policy?.allowedEmailDomains ?? []].sort(),
3118
+ allowedEmailDomains: (policy?.allowedEmailDomains ?? []).toSorted(),
3121
3119
  allowGoogleOauth: policy?.allowGoogleOauth ?? false,
3122
3120
  disablePasswordAuth: policy?.disablePasswordAuth ?? false,
3123
3121
  allowMicrosoftOauth: policy?.allowMicrosoftOauth ?? false
@@ -3201,7 +3199,7 @@ async function planServices$3(client, workspaceId, appName, appId, idps, idpUser
3201
3199
  const existingServices = {};
3202
3200
  await Promise.all(withoutLabel.map(async (resource) => {
3203
3201
  if (!resource.namespace?.name) return;
3204
- const { metadata } = await client.getMetadata({ trn: trn$5(workspaceId, resource.namespace.name) });
3202
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "idp", resource.namespace.name) });
3205
3203
  existingServices[resource.namespace.name] = {
3206
3204
  resource,
3207
3205
  label: metadata?.labels[sdkNameLabelKey],
@@ -3212,7 +3210,7 @@ async function planServices$3(client, workspaceId, appName, appId, idps, idpUser
3212
3210
  const namespaceName = idp.name;
3213
3211
  const existing = existingServices[namespaceName];
3214
3212
  const metaRequest = await buildMetaRequest({
3215
- trn: trn$5(workspaceId, namespaceName),
3213
+ trn: resourceTrn(workspaceId, "idp", namespaceName),
3216
3214
  appName,
3217
3215
  appId
3218
3216
  });
@@ -3571,9 +3569,6 @@ async function planAuth(context) {
3571
3569
  resourceOwners: new Set([...resourceOwners, ...connectionResult.resourceOwners])
3572
3570
  };
3573
3571
  }
3574
- function trn$4(workspaceId, name) {
3575
- return `trn:v1:workspace:${workspaceId}:auth:${name}`;
3576
- }
3577
3572
  async function planServices$2(client, workspaceId, appName, appId, auths, forceApplyAll = false) {
3578
3573
  const changeSet = createChangeSet("Auth services");
3579
3574
  const conflicts = [];
@@ -3595,7 +3590,7 @@ async function planServices$2(client, workspaceId, appName, appId, auths, forceA
3595
3590
  const existingServices = {};
3596
3591
  await Promise.all(withoutLabel.map(async (resource) => {
3597
3592
  if (!resource.namespace?.name) return;
3598
- const { metadata } = await client.getMetadata({ trn: trn$4(workspaceId, resource.namespace.name) });
3593
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "auth", resource.namespace.name) });
3599
3594
  existingServices[resource.namespace.name] = {
3600
3595
  resource,
3601
3596
  label: metadata?.labels[sdkNameLabelKey],
@@ -3606,7 +3601,7 @@ async function planServices$2(client, workspaceId, appName, appId, auths, forceA
3606
3601
  const { config } = auth;
3607
3602
  const existing = existingServices[config.name];
3608
3603
  const metaRequest = await buildMetaRequest({
3609
- trn: trn$4(workspaceId, config.name),
3604
+ trn: resourceTrn(workspaceId, "auth", config.name),
3610
3605
  appName,
3611
3606
  appId
3612
3607
  });
@@ -3764,7 +3759,7 @@ function normalizeComparableAuthIdPConfig(idpConfig) {
3764
3759
  config: configCase === "oidc" ? { config: {
3765
3760
  case: "oidc",
3766
3761
  value: {
3767
- ...oidcValue ?? {},
3762
+ ...oidcValue,
3768
3763
  issuerUrl: oidcValue && "issuerUrl" in oidcValue ? oidcValue.issuerUrl || void 0 : void 0
3769
3764
  }
3770
3765
  } } : idpConfig.config
@@ -4152,7 +4147,7 @@ function normalizeComparableOAuth2Client(client) {
4152
4147
  ...client,
4153
4148
  description: client.description || void 0,
4154
4149
  redirectUris: normalizeStringArray(client.redirectUris),
4155
- grantTypes: [...client.grantTypes ?? []].sort((left, right) => left - right),
4150
+ grantTypes: (client.grantTypes ?? []).toSorted((left, right) => left - right),
4156
4151
  accessTokenLifetime: accessTokenLifetime ?? 86400,
4157
4152
  refreshTokenLifetime: refreshTokenLifetime ?? 604800,
4158
4153
  requireDpop: client.requireDpop ?? false
@@ -4934,9 +4929,6 @@ async function applyExecutor(client, result, phase = "create-update") {
4934
4929
  })]);
4935
4930
  else if (phase === "delete") await Promise.all(changeSet.deletes.map((del) => client.deleteExecutorExecutor(del.request)));
4936
4931
  }
4937
- function trn$3(workspaceId, name) {
4938
- return `trn:v1:workspace:${workspaceId}:executor:${name}`;
4939
- }
4940
4932
  /**
4941
4933
  * Plan executor-related changes based on current and desired state.
4942
4934
  * @param context - Planning context
@@ -4960,13 +4952,13 @@ async function planExecutor(context) {
4960
4952
  return [executors, nextPageToken];
4961
4953
  },
4962
4954
  getName: (resource) => resource.name,
4963
- getTrn: trn$3
4955
+ getTrn: (workspaceId, name) => resourceTrn(workspaceId, "executor", name)
4964
4956
  });
4965
4957
  const executors = forRemoval ? {} : await application.executorService?.loadExecutors() ?? {};
4966
4958
  for (const executor of Object.values(executors)) {
4967
4959
  const existing = existingExecutors[executor.name];
4968
4960
  const metaRequest = await buildMetaRequest({
4969
- trn: trn$3(workspaceId, executor.name),
4961
+ trn: resourceTrn(workspaceId, "executor", executor.name),
4970
4962
  appName: application.name,
4971
4963
  appId: application.id
4972
4964
  });
@@ -5051,7 +5043,7 @@ function formatExecutorChangeEntries(changeSet, executors, functionRegistryExecu
5051
5043
  }
5052
5044
  function normalizeComparableExecutor(executor) {
5053
5045
  const normalized = normalizeProtoConfig(executor) ?? {};
5054
- const webhookHeaders = normalized.targetConfig?.config?.case === "webhook" ? [...normalized.targetConfig.config.value.headers ?? []].sort((left, right) => (left.key ?? "").localeCompare(right.key ?? "")) : void 0;
5046
+ const webhookHeaders = normalized.targetConfig?.config?.case === "webhook" ? (normalized.targetConfig.config.value.headers ?? []).toSorted((left, right) => (left.key ?? "").localeCompare(right.key ?? "")) : void 0;
5055
5047
  const triggerConfig = normalized.triggerConfig?.config?.case === "incomingWebhook" ? {
5056
5048
  ...normalized.triggerConfig,
5057
5049
  config: {
@@ -5182,10 +5174,10 @@ function protoExecutor(application, executor) {
5182
5174
  triggerType = ExecutorTriggerType.INCOMING_WEBHOOK;
5183
5175
  triggerConfig = { config: {
5184
5176
  case: "incomingWebhook",
5185
- value: { ...trigger.response ? { response: {
5177
+ value: trigger.response ? { response: {
5186
5178
  ...trigger.response.body ? { body: { expr: `(${stringifyFunction(trigger.response.body)})(${argsExpr})` } } : {},
5187
5179
  ...trigger.response.statusCode != null ? { statusCode: trigger.response.statusCode } : {}
5188
- } } : {} }
5180
+ } } : {}
5189
5181
  } };
5190
5182
  break;
5191
5183
  case "idpUser":
@@ -5380,9 +5372,6 @@ async function planPipeline(context) {
5380
5372
  resourceOwners
5381
5373
  };
5382
5374
  }
5383
- function trn$2(workspaceId, name) {
5384
- return `trn:v1:workspace:${workspaceId}:pipeline:${name}`;
5385
- }
5386
5375
  async function planServices$1(client, workspaceId, appName, appId, pipelines) {
5387
5376
  const changeSet = createChangeSet("Pipeline services");
5388
5377
  const conflicts = [];
@@ -5404,7 +5393,7 @@ async function planServices$1(client, workspaceId, appName, appId, pipelines) {
5404
5393
  const existingServices = {};
5405
5394
  await Promise.all(withoutLabel.map(async (resource) => {
5406
5395
  if (!resource.namespace?.name) return;
5407
- const { metadata } = await client.getMetadata({ trn: trn$2(workspaceId, resource.namespace.name) });
5396
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "pipeline", resource.namespace.name) });
5408
5397
  existingServices[resource.namespace.name] = {
5409
5398
  resource,
5410
5399
  label: metadata?.labels[sdkNameLabelKey],
@@ -5414,7 +5403,7 @@ async function planServices$1(client, workspaceId, appName, appId, pipelines) {
5414
5403
  for (const pipeline of pipelines) {
5415
5404
  const existing = existingServices[pipeline.namespace];
5416
5405
  const metaRequest = await buildMetaRequest({
5417
- trn: trn$2(workspaceId, pipeline.namespace),
5406
+ trn: resourceTrn(workspaceId, "pipeline", pipeline.namespace),
5418
5407
  appName,
5419
5408
  appId
5420
5409
  });
@@ -5702,7 +5691,7 @@ async function planSecretManager(context) {
5702
5691
  });
5703
5692
  const existingVaults = {};
5704
5693
  await Promise.all(existingVaultList.map(async (resource) => {
5705
- const { metadata } = await client.getMetadata({ trn: vaultTrn$1(workspaceId, resource.name) });
5694
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "vault", resource.name) });
5706
5695
  existingVaults[resource.name] = {
5707
5696
  resource,
5708
5697
  label: metadata?.labels[sdkNameLabelKey],
@@ -5716,7 +5705,7 @@ async function planSecretManager(context) {
5716
5705
  const existing = existingVaults[vaultName];
5717
5706
  if (existing) {
5718
5707
  const metaRequest = await buildMetaRequest({
5719
- trn: vaultTrn$1(workspaceId, vaultName),
5708
+ trn: resourceTrn(workspaceId, "vault", vaultName),
5720
5709
  appName: application.name,
5721
5710
  appId: application.id
5722
5711
  });
@@ -5829,9 +5818,6 @@ async function planSecretManager(context) {
5829
5818
  resourceOwners
5830
5819
  };
5831
5820
  }
5832
- function vaultTrn$1(workspaceId, name) {
5833
- return `trn:v1:workspace:${workspaceId}:vault:${name}`;
5834
- }
5835
5821
  /**
5836
5822
  * Apply secret manager changes for the given phase.
5837
5823
  * @param client - Operator client instance
@@ -5850,7 +5836,7 @@ async function applySecretManager(client, result, phase = "create-update", appli
5850
5836
  });
5851
5837
  if (application) {
5852
5838
  const metaRequest = await buildMetaRequest({
5853
- trn: vaultTrn$1(create.workspaceId, create.name),
5839
+ trn: resourceTrn(create.workspaceId, "vault", create.name),
5854
5840
  appName: application.name,
5855
5841
  appId: application.id
5856
5842
  });
@@ -5859,7 +5845,7 @@ async function applySecretManager(client, result, phase = "create-update", appli
5859
5845
  }));
5860
5846
  if (application) await Promise.all(vaultChangeSet.updates.map(async (update) => {
5861
5847
  const metaRequest = await buildMetaRequest({
5862
- trn: vaultTrn$1(update.workspaceId, update.name),
5848
+ trn: resourceTrn(update.workspaceId, "vault", update.name),
5863
5849
  appName: application.name,
5864
5850
  appId: application.id
5865
5851
  });
@@ -5917,23 +5903,28 @@ async function applySecretManager(client, result, phase = "create-update", appli
5917
5903
  * @returns Promise that resolves when static websites are applied
5918
5904
  */
5919
5905
  async function applyStaticWebsite(client, result, phase = "create-update") {
5920
- const { changeSet } = result;
5921
- if (phase === "create-update") await Promise.all([...changeSet.creates.map(async (create) => {
5922
- await client.createStaticWebsite(create.request);
5923
- await client.setMetadata(create.metaRequest);
5924
- }), ...changeSet.updates.map(async (update) => {
5925
- await client.updateStaticWebsite(update.request);
5926
- await client.setMetadata(update.metaRequest);
5927
- })]);
5928
- else if (phase === "delete") await Promise.all(changeSet.deletes.map((del) => client.deleteStaticWebsite(del.request)));
5906
+ const { changeSet, customDomainChangeSet } = result;
5907
+ if (phase === "create-update") {
5908
+ await Promise.all([...changeSet.creates.map(async (create) => {
5909
+ await client.createStaticWebsite(create.request);
5910
+ await client.setMetadata(create.metaRequest);
5911
+ }), ...changeSet.updates.map(async (update) => {
5912
+ await client.updateStaticWebsite(update.request);
5913
+ await client.setMetadata(update.metaRequest);
5914
+ })]);
5915
+ await Promise.all([...customDomainChangeSet.creates.map(async (add) => {
5916
+ await client.addCustomDomain(add.request);
5917
+ await client.setMetadata(add.metaRequest);
5918
+ }), ...customDomainChangeSet.deletes.map((del) => client.removeCustomDomain(del.request))]);
5919
+ } else if (phase === "delete") await Promise.all(changeSet.deletes.map((del) => client.deleteStaticWebsite(del.request)));
5929
5920
  }
5930
- function trn$1(workspaceId, name) {
5931
- return `trn:v1:workspace:${workspaceId}:staticwebsite:${name}`;
5921
+ function customDomainTrn(workspaceId, websiteName, domain) {
5922
+ return `trn:v1:workspace:${workspaceId}:staticwebsite:${websiteName}:custom_domain:${domain}`;
5932
5923
  }
5933
5924
  function normalizeComparableStaticWebsiteShape(input) {
5934
5925
  return {
5935
5926
  description: input.description,
5936
- allowedIpAddresses: [...input.allowedIpAddresses].sort()
5927
+ allowedIpAddresses: input.allowedIpAddresses.toSorted()
5937
5928
  };
5938
5929
  }
5939
5930
  function normalizeComparableStaticWebsite(input) {
@@ -5953,6 +5944,7 @@ function areStaticWebsitesEqual(existing, desired) {
5953
5944
  async function planStaticWebsite(context) {
5954
5945
  const { client, workspaceId, application, forRemoval } = context;
5955
5946
  const changeSet = createChangeSet("StaticWebsites");
5947
+ const customDomainChangeSet = createChangeSet("CustomDomains");
5956
5948
  const conflicts = [];
5957
5949
  const unmanaged = [];
5958
5950
  const resourceOwners = /* @__PURE__ */ new Set();
@@ -5968,15 +5960,16 @@ async function planStaticWebsite(context) {
5968
5960
  return [staticwebsites, nextPageToken];
5969
5961
  },
5970
5962
  getName: (resource) => resource.name,
5971
- getTrn: trn$1
5963
+ getTrn: (workspaceId, name) => resourceTrn(workspaceId, "staticwebsite", name)
5972
5964
  });
5965
+ const ownedWebsiteNames = /* @__PURE__ */ new Set();
5973
5966
  const staticWebsiteServices = forRemoval ? [] : application.staticWebsiteServices;
5974
5967
  for (const websiteService of staticWebsiteServices) {
5975
5968
  const config = websiteService;
5976
5969
  const name = websiteService.name;
5977
5970
  const existing = existingWebsites[name];
5978
5971
  const metaRequest = await buildMetaRequest({
5979
- trn: trn$1(workspaceId, name),
5972
+ trn: resourceTrn(workspaceId, "staticwebsite", name),
5980
5973
  appName: application.name,
5981
5974
  appId: application.id
5982
5975
  });
@@ -5990,7 +5983,7 @@ async function planStaticWebsite(context) {
5990
5983
  }
5991
5984
  };
5992
5985
  if (existing) {
5993
- if (trackDesiredResourceOwnership({
5986
+ const owned = trackDesiredResourceOwnership({
5994
5987
  labels: existing.allLabels,
5995
5988
  ownerLabel: existing.label,
5996
5989
  appName: application.name,
@@ -5999,18 +5992,23 @@ async function planStaticWebsite(context) {
5999
5992
  resourceName: name,
6000
5993
  conflicts,
6001
5994
  unmanaged
6002
- }) && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) && areStaticWebsitesEqual(existing.resource, desired)) changeSet.unchanged.push({ name });
5995
+ });
5996
+ if (owned && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) && areStaticWebsitesEqual(existing.resource, desired)) changeSet.unchanged.push({ name });
6003
5997
  else changeSet.updates.push({
6004
5998
  name,
6005
5999
  request,
6006
6000
  metaRequest
6007
6001
  });
6002
+ if (owned) ownedWebsiteNames.add(name);
6008
6003
  delete existingWebsites[name];
6009
- } else changeSet.creates.push({
6010
- name,
6011
- request,
6012
- metaRequest
6013
- });
6004
+ } else {
6005
+ changeSet.creates.push({
6006
+ name,
6007
+ request,
6008
+ metaRequest
6009
+ });
6010
+ ownedWebsiteNames.add(name);
6011
+ }
6014
6012
  }
6015
6013
  Object.entries(existingWebsites).forEach(([name]) => {
6016
6014
  const entry = existingWebsites[name];
@@ -6029,8 +6027,63 @@ async function planStaticWebsite(context) {
6029
6027
  }
6030
6028
  });
6031
6029
  });
6030
+ const desiredDomainsByWebsite = /* @__PURE__ */ new Map();
6031
+ for (const service of staticWebsiteServices) if (service.customDomains !== void 0 && ownedWebsiteNames.has(service.name)) desiredDomainsByWebsite.set(service.name, service.customDomains);
6032
+ const existingDomainsByWebsite = /* @__PURE__ */ new Map();
6033
+ const websitesToFetchDomains = [...ownedWebsiteNames].filter((name) => !changeSet.creates.some((c) => c.name === name));
6034
+ await Promise.all(websitesToFetchDomains.map(async (name) => {
6035
+ try {
6036
+ const { customDomains } = await client.listCustomDomains({
6037
+ workspaceId,
6038
+ staticWebsiteName: name
6039
+ });
6040
+ const domainsWithLabels = await Promise.all(customDomains.map(async (d) => {
6041
+ const { metadata } = await client.getMetadata({ trn: customDomainTrn(workspaceId, name, d.domain) });
6042
+ return {
6043
+ domain: d.domain,
6044
+ allLabels: metadata?.labels
6045
+ };
6046
+ }));
6047
+ existingDomainsByWebsite.set(name, domainsWithLabels);
6048
+ } catch (error) {
6049
+ if (error instanceof ConnectError && error.code === Code.NotFound) return;
6050
+ throw error;
6051
+ }
6052
+ }));
6053
+ for (const name of ownedWebsiteNames) {
6054
+ const desired = new Set(desiredDomainsByWebsite.get(name) ?? []);
6055
+ const existingDomains = existingDomainsByWebsite.get(name) ?? [];
6056
+ const existingSet = new Set(existingDomains.map((d) => d.domain));
6057
+ const sdkOwnedDomains = new Set(existingDomains.filter((d) => isOwnedByApp(d.allLabels, application.name, application.id)).map((d) => d.domain));
6058
+ for (const domain of desired) if (!existingSet.has(domain)) {
6059
+ const metaRequest = await buildMetaRequest({
6060
+ trn: customDomainTrn(workspaceId, name, domain),
6061
+ appName: application.name,
6062
+ appId: application.id
6063
+ });
6064
+ customDomainChangeSet.creates.push({
6065
+ name: domain,
6066
+ request: {
6067
+ workspaceId,
6068
+ staticWebsiteName: name,
6069
+ domain
6070
+ },
6071
+ metaRequest
6072
+ });
6073
+ } else customDomainChangeSet.unchanged.push({ name: domain });
6074
+ if (desiredDomainsByWebsite.has(name)) {
6075
+ for (const domain of sdkOwnedDomains) if (!desired.has(domain)) customDomainChangeSet.deletes.push({
6076
+ name: domain,
6077
+ request: {
6078
+ workspaceId,
6079
+ domain
6080
+ }
6081
+ });
6082
+ }
6083
+ }
6032
6084
  return {
6033
6085
  changeSet,
6086
+ customDomainChangeSet,
6034
6087
  conflicts,
6035
6088
  unmanaged,
6036
6089
  resourceOwners
@@ -6594,8 +6647,7 @@ function getMigrationFiles(migrationsDir) {
6594
6647
  path: diffPath
6595
6648
  });
6596
6649
  }
6597
- migrations.sort((a, b) => a.number - b.number);
6598
- return migrations;
6650
+ return migrations.toSorted((a, b) => a.number - b.number);
6599
6651
  }
6600
6652
  /**
6601
6653
  * Get the next migration number for a directory
@@ -7204,7 +7256,7 @@ function validateMigrationFiles(migrationsDir) {
7204
7256
  message: `Schema file found at migration ${formatMigrationNumber(num)}, but schema should only exist at ${formatMigrationNumber(0)}`,
7205
7257
  migrationNumber: num
7206
7258
  });
7207
- const allNumbers = [...new Set([...schemaFiles, ...diffFiles])].sort((a, b) => a - b);
7259
+ const allNumbers = [...new Set([...schemaFiles, ...diffFiles])].toSorted((a, b) => a - b);
7208
7260
  if (allNumbers.length === 0) return errors;
7209
7261
  for (const num of schemaFiles) if (num !== 0 && diffFiles.includes(num)) errors.push({
7210
7262
  type: "duplicate",
@@ -7413,6 +7465,70 @@ function formatSchemaDrifts(drifts) {
7413
7465
  //#endregion
7414
7466
  //#region src/cli/commands/tailordb/migrate/snapshot-manifest.ts
7415
7467
  /**
7468
+ * Snapshot-based Proto manifest generation for TailorDB migrations
7469
+ *
7470
+ * This module provides utilities for generating TailorDB proto manifests
7471
+ * directly from schema snapshots, enabling migration-based deployments
7472
+ * without relying on local TypeScript definitions.
7473
+ */
7474
+ /**
7475
+ * Generate a TailorDB type manifest from a snapshot type
7476
+ * @param {TailorDBSnapshotType} snapshotType - Snapshot type to generate manifest from
7477
+ * @param {GenerateManifestOptions} options - Generation options
7478
+ * @returns {MessageInitShape<typeof TailorDBTypeSchema>} Type manifest
7479
+ */
7480
+ function generateTailorDBTypeManifestFromSnapshot(snapshotType, options = {}) {
7481
+ const pluralForm = inflection.camelize(snapshotType.pluralForm, true);
7482
+ const defaultSettings = {
7483
+ aggregation: snapshotType.settings?.aggregation ?? false,
7484
+ bulkUpsert: snapshotType.settings?.bulkUpsert ?? false,
7485
+ draft: false,
7486
+ defaultQueryLimitSize: 100n,
7487
+ maxBulkUpsertSize: 1000n,
7488
+ pluralForm,
7489
+ publishRecordEvents: snapshotType.settings?.publishEvents ?? options.publishRecordEvents ?? false
7490
+ };
7491
+ const ops = snapshotType.settings?.gqlOperations ?? options.namespaceGqlOperations;
7492
+ if (ops) defaultSettings.disableGqlOperations = {
7493
+ create: ops.create === false,
7494
+ update: ops.update === false,
7495
+ delete: ops.delete === false,
7496
+ read: ops.read === false
7497
+ };
7498
+ const fields = {};
7499
+ for (const [fieldName, fieldConfig] of Object.entries(snapshotType.fields)) {
7500
+ if (fieldName === "id") continue;
7501
+ fields[fieldName] = convertFieldConfigToProto(fieldConfig);
7502
+ }
7503
+ const relationships = {};
7504
+ if (snapshotType.forwardRelationships) for (const [relationName, rel] of Object.entries(snapshotType.forwardRelationships)) relationships[relationName] = convertRelationshipToProto(rel, "forward");
7505
+ if (snapshotType.backwardRelationships) for (const [relationName, rel] of Object.entries(snapshotType.backwardRelationships)) relationships[relationName] = convertRelationshipToProto(rel, "backward");
7506
+ const indexes = {};
7507
+ if (snapshotType.indexes) for (const [indexName, indexConfig] of Object.entries(snapshotType.indexes)) indexes[indexName] = convertIndexToProto(indexConfig);
7508
+ const files = {};
7509
+ if (snapshotType.files) for (const [fileName, description] of Object.entries(snapshotType.files)) files[fileName] = { description: description || "" };
7510
+ const permission = snapshotType.permissions?.record ? convertRecordPermissionToProto(snapshotType.permissions.record) : {
7511
+ create: [],
7512
+ read: [],
7513
+ update: [],
7514
+ delete: []
7515
+ };
7516
+ return {
7517
+ name: snapshotType.name,
7518
+ schema: {
7519
+ description: snapshotType.description || "",
7520
+ fields,
7521
+ relationships,
7522
+ settings: defaultSettings,
7523
+ extends: false,
7524
+ directives: [],
7525
+ indexes,
7526
+ files,
7527
+ permission
7528
+ }
7529
+ };
7530
+ }
7531
+ /**
7416
7532
  * Convert a snapshot field config to proto format
7417
7533
  * @param {SnapshotFieldConfig} config - Snapshot field config
7418
7534
  * @returns {MessageInitShape<typeof TailorDBType_FieldConfigSchema>} Proto field config
@@ -7501,6 +7617,141 @@ function processNestedFieldsFromSnapshot(fields) {
7501
7617
  };
7502
7618
  return nestedFields;
7503
7619
  }
7620
+ /**
7621
+ * Convert a snapshot relationship to proto format
7622
+ * @param {SnapshotRelationship} rel - Snapshot relationship
7623
+ * @param {"forward" | "backward"} direction - Relationship direction
7624
+ * @returns {MessageInitShape<typeof TailorDBType_RelationshipConfigSchema>} Proto relationship config
7625
+ */
7626
+ function convertRelationshipToProto(rel, direction) {
7627
+ if (direction === "forward") return {
7628
+ refType: rel.targetType,
7629
+ refField: rel.sourceField,
7630
+ srcField: rel.targetField,
7631
+ array: rel.isArray,
7632
+ description: rel.description
7633
+ };
7634
+ return {
7635
+ refType: rel.targetType,
7636
+ refField: rel.targetField,
7637
+ srcField: rel.sourceField,
7638
+ array: rel.isArray,
7639
+ description: rel.description
7640
+ };
7641
+ }
7642
+ /**
7643
+ * Convert a snapshot index config to proto format
7644
+ * @param {SnapshotIndexConfig} indexConfig - Snapshot index config
7645
+ * @returns {MessageInitShape<typeof TailorDBType_IndexSchema>} Proto index config
7646
+ */
7647
+ function convertIndexToProto(indexConfig) {
7648
+ return {
7649
+ fieldNames: indexConfig.fields,
7650
+ unique: indexConfig.unique ?? false
7651
+ };
7652
+ }
7653
+ /**
7654
+ * Convert a snapshot record permission to proto format
7655
+ * @param {SnapshotRecordPermission} permission - Snapshot record permission
7656
+ * @returns {MessageInitShape<typeof TailorDBType_PermissionSchema>} Proto permission
7657
+ */
7658
+ function convertRecordPermissionToProto(permission) {
7659
+ return {
7660
+ create: permission.create.map(convertActionPermissionToProto),
7661
+ read: permission.read.map(convertActionPermissionToProto),
7662
+ update: permission.update.map(convertActionPermissionToProto),
7663
+ delete: permission.delete.map(convertActionPermissionToProto)
7664
+ };
7665
+ }
7666
+ /**
7667
+ * Convert a snapshot action permission to proto format
7668
+ * @param {SnapshotActionPermission} policy - Snapshot action permission
7669
+ * @returns {MessageInitShape<typeof TailorDBType_Permission_PolicySchema>} Proto policy
7670
+ */
7671
+ function convertActionPermissionToProto(policy) {
7672
+ let permit;
7673
+ switch (policy.permit) {
7674
+ case "allow":
7675
+ permit = TailorDBType_Permission_Permit.ALLOW;
7676
+ break;
7677
+ case "deny":
7678
+ permit = TailorDBType_Permission_Permit.DENY;
7679
+ break;
7680
+ default: throw new Error(`Unknown permission: ${policy.permit}`);
7681
+ }
7682
+ return {
7683
+ conditions: policy.conditions.map(convertConditionToProto),
7684
+ permit,
7685
+ description: policy.description
7686
+ };
7687
+ }
7688
+ /**
7689
+ * Convert a snapshot permission condition to proto format
7690
+ * @param {SnapshotPermissionCondition} condition - Snapshot permission condition
7691
+ * @returns {MessageInitShape<typeof TailorDBType_Permission_ConditionSchema>} Proto condition
7692
+ */
7693
+ function convertConditionToProto(condition) {
7694
+ const [left, operator, right] = condition;
7695
+ const l = convertOperandToProto(left);
7696
+ const r = convertOperandToProto(right);
7697
+ let op;
7698
+ switch (operator) {
7699
+ case "eq":
7700
+ op = TailorDBType_Permission_Operator.EQ;
7701
+ break;
7702
+ case "ne":
7703
+ op = TailorDBType_Permission_Operator.NE;
7704
+ break;
7705
+ case "in":
7706
+ op = TailorDBType_Permission_Operator.IN;
7707
+ break;
7708
+ case "nin":
7709
+ op = TailorDBType_Permission_Operator.NIN;
7710
+ break;
7711
+ case "hasAny":
7712
+ op = TailorDBType_Permission_Operator.HAS_ANY;
7713
+ break;
7714
+ case "nhasAny":
7715
+ op = TailorDBType_Permission_Operator.NHAS_ANY;
7716
+ break;
7717
+ default: throw new Error(`Unknown operator: ${operator}`);
7718
+ }
7719
+ return {
7720
+ left: l,
7721
+ operator: op,
7722
+ right: r
7723
+ };
7724
+ }
7725
+ /**
7726
+ * Convert a snapshot permission operand to proto format
7727
+ * @param {SnapshotPermissionOperand} operand - Snapshot permission operand
7728
+ * @returns {MessageInitShape<typeof TailorDBType_Permission_OperandSchema>} Proto operand
7729
+ */
7730
+ function convertOperandToProto(operand) {
7731
+ if (isSnapshotFieldRefOperand(operand)) {
7732
+ if ("user" in operand) return { kind: {
7733
+ case: "userField",
7734
+ value: operand.user
7735
+ } };
7736
+ if ("record" in operand) return { kind: {
7737
+ case: "recordField",
7738
+ value: operand.record
7739
+ } };
7740
+ if ("newRecord" in operand) return { kind: {
7741
+ case: "newRecordField",
7742
+ value: operand.newRecord
7743
+ } };
7744
+ if ("oldRecord" in operand) return { kind: {
7745
+ case: "oldRecordField",
7746
+ value: operand.oldRecord
7747
+ } };
7748
+ throw new Error(`Unknown field-ref operand shape: ${JSON.stringify(operand)}`);
7749
+ }
7750
+ return { kind: {
7751
+ case: "value",
7752
+ value: fromJson(ValueSchema, operand)
7753
+ } };
7754
+ }
7504
7755
 
7505
7756
  //#endregion
7506
7757
  //#region src/cli/commands/tailordb/migrate/pre-migration-schema.ts
@@ -7655,6 +7906,7 @@ async function bundleMigrationScript(sourceFile, namespace, migrationNumber, env
7655
7906
  namespace,
7656
7907
  migrationNumber,
7657
7908
  bundledCode: (await rolldown.build({
7909
+ plugins: [platformBundleDefinePlugin],
7658
7910
  input: entryPath,
7659
7911
  write: false,
7660
7912
  output: {
@@ -7812,7 +8064,7 @@ function installSignalHook() {
7812
8064
  if (signalHookInstalled) return;
7813
8065
  signalHookInstalled = true;
7814
8066
  const handler = () => {
7815
- for (const s of [...activeSpinners]) s.stop();
8067
+ for (const s of activeSpinners) s.stop();
7816
8068
  };
7817
8069
  process.prependListener("SIGINT", handler);
7818
8070
  process.prependListener("SIGTERM", handler);
@@ -7952,7 +8204,7 @@ function spinner(options) {
7952
8204
  */
7953
8205
  async function getCurrentMigrationNumber(client, workspaceId, namespace) {
7954
8206
  try {
7955
- const trn = `${trnPrefix(workspaceId)}:tailordb:${namespace}`;
8207
+ const trn = resourceTrn(workspaceId, "tailordb", namespace);
7956
8208
  const { metadata } = await client.getMetadata({ trn });
7957
8209
  const label = metadata?.labels[MIGRATION_LABEL_KEY];
7958
8210
  if (!label) return 0;
@@ -7995,11 +8247,10 @@ async function detectPendingMigrations(client, workspaceId, namespacesWithMigrat
7995
8247
  });
7996
8248
  }
7997
8249
  }
7998
- pendingMigrations.sort((a, b) => {
8250
+ return pendingMigrations.toSorted((a, b) => {
7999
8251
  if (a.namespace !== b.namespace) return a.namespace.localeCompare(b.namespace);
8000
8252
  return a.number - b.number;
8001
8253
  });
8002
- return pendingMigrations;
8003
8254
  }
8004
8255
  /**
8005
8256
  * Execute a single migration script
@@ -8033,7 +8284,7 @@ async function executeSingleMigration(options, migration) {
8033
8284
  * @returns {Promise<void>}
8034
8285
  */
8035
8286
  async function updateMigrationLabel(client, workspaceId, namespace, migrationNumber) {
8036
- const trn = `${trnPrefix(workspaceId)}:tailordb:${namespace}`;
8287
+ const trn = resourceTrn(workspaceId, "tailordb", namespace);
8037
8288
  const { metadata } = await client.getMetadata({ trn });
8038
8289
  const existingLabels = metadata?.labels ?? {};
8039
8290
  const newLabel = `m${formatMigrationNumber(migrationNumber)}`;
@@ -8148,7 +8399,7 @@ async function fetchRemoteTypes(client, workspaceId, namespace) {
8148
8399
  */
8149
8400
  async function getRemoteMigrationNumber(client, workspaceId, namespace) {
8150
8401
  try {
8151
- const trn = `${trnPrefix(workspaceId)}:tailordb:${namespace}`;
8402
+ const trn = resourceTrn(workspaceId, "tailordb", namespace);
8152
8403
  const { metadata } = await client.getMetadata({ trn });
8153
8404
  const label = metadata?.labels?.["sdk-migration"];
8154
8405
  if (!label) return null;
@@ -8464,7 +8715,11 @@ const migrationSnapshotCache = {
8464
8715
  function buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes) {
8465
8716
  const snapshotType = migrationSnapshotCache.load(migration).types[typeName];
8466
8717
  if (!snapshotType) return void 0;
8467
- return generateTailorDBTypeManifest(snapshotType, executorUsedTypes, tailorDBInputs.find((i) => i.namespace === migration.namespace)?.config.gqlOperations);
8718
+ const input = tailorDBInputs.find((i) => i.namespace === migration.namespace);
8719
+ return generateTailorDBTypeManifestFromSnapshot(snapshotType, {
8720
+ publishRecordEvents: executorUsedTypes.has(snapshotType.name),
8721
+ namespaceGqlOperations: input?.config.gqlOperations
8722
+ });
8468
8723
  }
8469
8724
  /**
8470
8725
  * Execute pre-migration phase for a single migration
@@ -8702,9 +8957,6 @@ function formatTailorDBResourceChangeEntries(typeChangeSet, gqlPermissionChangeS
8702
8957
  ...collectTailorDBDisplayEntries("replace", typeChangeSet.replaces, gqlPermissionChangeSet.replaces)
8703
8958
  ];
8704
8959
  }
8705
- function trn(workspaceId, name) {
8706
- return `${trnPrefix(workspaceId)}:tailordb:${name}`;
8707
- }
8708
8960
  function normalizeComparableTailorDBService(service) {
8709
8961
  return normalizeProtoConfig({
8710
8962
  namespace: service.namespace,
@@ -8741,7 +8993,7 @@ async function planServices(client, workspaceId, appName, appId, tailordbs) {
8741
8993
  const existingServices = {};
8742
8994
  await Promise.all(withoutLabel.map(async (resource) => {
8743
8995
  if (!resource.namespace?.name) return;
8744
- const { metadata } = await client.getMetadata({ trn: trn(workspaceId, resource.namespace.name) });
8996
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "tailordb", resource.namespace.name) });
8745
8997
  existingServices[resource.namespace.name] = {
8746
8998
  resource,
8747
8999
  label: metadata?.labels[sdkNameLabelKey],
@@ -8751,7 +9003,7 @@ async function planServices(client, workspaceId, appName, appId, tailordbs) {
8751
9003
  for (const tailordb of tailordbs) {
8752
9004
  const existing = existingServices[tailordb.namespace];
8753
9005
  const metaRequest = await buildMetaRequest({
8754
- trn: trn(workspaceId, tailordb.namespace),
9006
+ trn: resourceTrn(workspaceId, "tailordb", tailordb.namespace),
8755
9007
  appName,
8756
9008
  appId,
8757
9009
  existingLabels: existing?.allLabels
@@ -8833,7 +9085,10 @@ async function planTypes(client, workspaceId, tailordbs, executorUsedTypes, dele
8833
9085
  const existingTypesMap = new Map(existingTypes.map((type) => [type.name, type]));
8834
9086
  const types = filteredTypesByNamespace?.get(tailordb.namespace) ?? tailordb.types;
8835
9087
  for (const typeName of Object.keys(types)) {
8836
- const tailordbType = generateTailorDBTypeManifest(types[typeName], executorUsedTypes, tailordb.config.gqlOperations);
9088
+ const tailordbType = generateTailorDBTypeManifestFromSnapshot(types[typeName], {
9089
+ publishRecordEvents: executorUsedTypes.has(typeName),
9090
+ namespaceGqlOperations: tailordb.config.gqlOperations
9091
+ });
8837
9092
  const existingType = existingTypesMap.get(typeName);
8838
9093
  if (existingType) {
8839
9094
  if (!forceApplyAll && areNormalizedEqual(normalizeComparableTailorDBType(existingType), normalizeComparableTailorDBType(tailordbType))) changeSet.unchanged.push({ name: typeName });
@@ -8950,247 +9205,6 @@ function matchesNumericStringPath(path) {
8950
9205
  function isNumericLikeValue(value) {
8951
9206
  return typeof value === "number" || typeof value === "bigint" || /^-?\d+$/.test(value);
8952
9207
  }
8953
- /**
8954
- * Generate a TailorDB type manifest from snapshot-shaped type
8955
- * @param {TailorDBSnapshotType} type - Snapshot-shaped TailorDB type
8956
- * @param {ReadonlySet<string>} executorUsedTypes - Set of types used by executors
8957
- * @param {GqlOperations} [namespaceGqlOperations] - Default gqlOperations for the namespace (already normalized)
8958
- * @returns {MessageInitShape<typeof TailorDBTypeSchema>} Type manifest
8959
- */
8960
- function generateTailorDBTypeManifest(type, executorUsedTypes, namespaceGqlOperations) {
8961
- const pluralForm = inflection.camelize(type.pluralForm, true);
8962
- const defaultSettings = {
8963
- aggregation: type.settings?.aggregation || false,
8964
- bulkUpsert: type.settings?.bulkUpsert || false,
8965
- draft: false,
8966
- defaultQueryLimitSize: 100n,
8967
- maxBulkUpsertSize: 1000n,
8968
- pluralForm,
8969
- publishRecordEvents: false
8970
- };
8971
- if (type.settings?.publishEvents !== void 0) defaultSettings.publishRecordEvents = type.settings.publishEvents;
8972
- else if (executorUsedTypes.has(type.name)) defaultSettings.publishRecordEvents = true;
8973
- const ops = type.settings?.gqlOperations ?? namespaceGqlOperations;
8974
- if (ops) defaultSettings.disableGqlOperations = {
8975
- create: ops.create === false,
8976
- update: ops.update === false,
8977
- delete: ops.delete === false,
8978
- read: ops.read === false
8979
- };
8980
- const fields = {};
8981
- Object.keys(type.fields).filter((fieldName) => fieldName !== "id").forEach((fieldName) => {
8982
- const fieldConfig = type.fields[fieldName];
8983
- const fieldType = fieldConfig.type;
8984
- const fieldEntry = {
8985
- type: fieldType,
8986
- allowedValues: fieldType === "enum" ? fieldConfig.allowedValues || [] : [],
8987
- description: fieldConfig.description || "",
8988
- validate: toProtoFieldValidate(fieldConfig),
8989
- array: fieldConfig.array || false,
8990
- index: fieldConfig.index || false,
8991
- unique: fieldConfig.unique || false,
8992
- foreignKey: fieldConfig.foreignKey || false,
8993
- foreignKeyType: fieldConfig.foreignKeyType,
8994
- foreignKeyField: fieldConfig.foreignKeyField,
8995
- required: fieldConfig.required,
8996
- vector: fieldConfig.vector || false,
8997
- ...toProtoFieldHooks(fieldConfig),
8998
- ...fieldConfig.serial && { serial: {
8999
- start: fieldConfig.serial.start,
9000
- ...fieldConfig.serial.maxValue && { maxValue: fieldConfig.serial.maxValue },
9001
- ...fieldConfig.serial.format && { format: fieldConfig.serial.format }
9002
- } },
9003
- ...fieldConfig.scale !== void 0 && { scale: fieldConfig.scale }
9004
- };
9005
- if (fieldConfig.type === "nested" && fieldConfig.fields) fieldEntry.fields = processNestedFields(fieldConfig.fields);
9006
- fields[fieldName] = fieldEntry;
9007
- });
9008
- const relationships = {};
9009
- for (const [relationName, rel] of Object.entries(type.forwardRelationships ?? {})) relationships[relationName] = {
9010
- refType: rel.targetType,
9011
- refField: rel.sourceField,
9012
- srcField: rel.targetField,
9013
- array: rel.isArray,
9014
- description: rel.description
9015
- };
9016
- for (const [relationName, rel] of Object.entries(type.backwardRelationships ?? {})) relationships[relationName] = {
9017
- refType: rel.targetType,
9018
- refField: rel.targetField,
9019
- srcField: rel.sourceField,
9020
- array: rel.isArray,
9021
- description: rel.description
9022
- };
9023
- const indexes = {};
9024
- if (type.indexes) Object.entries(type.indexes).forEach(([key, index]) => {
9025
- indexes[key] = {
9026
- fieldNames: index.fields,
9027
- unique: index.unique || false
9028
- };
9029
- });
9030
- const files = {};
9031
- if (type.files) Object.entries(type.files).forEach(([key, description]) => {
9032
- files[key] = { description: description || "" };
9033
- });
9034
- const permission = type.permissions?.record ? protoPermission(type.permissions.record) : {
9035
- create: [],
9036
- read: [],
9037
- update: [],
9038
- delete: []
9039
- };
9040
- return {
9041
- name: type.name,
9042
- schema: {
9043
- description: type.description || "",
9044
- fields,
9045
- relationships,
9046
- settings: defaultSettings,
9047
- extends: false,
9048
- directives: [],
9049
- indexes,
9050
- files,
9051
- permission
9052
- }
9053
- };
9054
- }
9055
- function toProtoFieldValidate(fieldConfig) {
9056
- return (fieldConfig.validate || []).map((val) => ({
9057
- action: TailorDBType_PermitAction.DENY,
9058
- errorMessage: val.errorMessage || "",
9059
- ...val.script && { script: { expr: val.script.expr ? `!${val.script.expr}` : "" } }
9060
- }));
9061
- }
9062
- function toProtoFieldHooks(fieldConfig) {
9063
- if (!fieldConfig.hooks) return {};
9064
- return { hooks: {
9065
- create: fieldConfig.hooks.create ? { expr: fieldConfig.hooks.create.expr || "" } : void 0,
9066
- update: fieldConfig.hooks.update ? { expr: fieldConfig.hooks.update.expr || "" } : void 0
9067
- } };
9068
- }
9069
- function processNestedFields(fields) {
9070
- const nestedFields = {};
9071
- Object.entries(fields).forEach(([nestedFieldName, nestedFieldConfig]) => {
9072
- const nestedType = nestedFieldConfig.type;
9073
- if (nestedType === "nested" && nestedFieldConfig.fields) {
9074
- const deepNestedFields = processNestedFields(nestedFieldConfig.fields);
9075
- nestedFields[nestedFieldName] = {
9076
- type: "nested",
9077
- allowedValues: nestedFieldConfig.allowedValues || [],
9078
- description: nestedFieldConfig.description || "",
9079
- validate: toProtoFieldValidate(nestedFieldConfig),
9080
- required: nestedFieldConfig.required,
9081
- array: nestedFieldConfig.array ?? false,
9082
- index: false,
9083
- unique: false,
9084
- foreignKey: false,
9085
- vector: false,
9086
- ...toProtoFieldHooks(nestedFieldConfig),
9087
- fields: deepNestedFields,
9088
- ...nestedFieldConfig.scale !== void 0 && { scale: nestedFieldConfig.scale }
9089
- };
9090
- } else nestedFields[nestedFieldName] = {
9091
- type: nestedType,
9092
- allowedValues: nestedType === "enum" ? nestedFieldConfig.allowedValues || [] : [],
9093
- description: nestedFieldConfig.description || "",
9094
- validate: toProtoFieldValidate(nestedFieldConfig),
9095
- required: nestedFieldConfig.required,
9096
- array: nestedFieldConfig.array ?? false,
9097
- index: false,
9098
- unique: false,
9099
- foreignKey: false,
9100
- vector: false,
9101
- ...toProtoFieldHooks(nestedFieldConfig),
9102
- ...nestedFieldConfig.serial && { serial: {
9103
- start: nestedFieldConfig.serial.start,
9104
- ...nestedFieldConfig.serial.maxValue && { maxValue: nestedFieldConfig.serial.maxValue },
9105
- ...nestedFieldConfig.serial.format && { format: nestedFieldConfig.serial.format }
9106
- } },
9107
- ...nestedFieldConfig.scale !== void 0 && { scale: nestedFieldConfig.scale }
9108
- };
9109
- });
9110
- return nestedFields;
9111
- }
9112
- function protoPermission(permission) {
9113
- return {
9114
- create: permission.create.map((policy) => protoPolicy(policy)),
9115
- read: permission.read.map((policy) => protoPolicy(policy)),
9116
- update: permission.update.map((policy) => protoPolicy(policy)),
9117
- delete: permission.delete.map((policy) => protoPolicy(policy))
9118
- };
9119
- }
9120
- function protoPolicy(policy) {
9121
- let permit;
9122
- switch (policy.permit) {
9123
- case "allow":
9124
- permit = TailorDBType_Permission_Permit.ALLOW;
9125
- break;
9126
- case "deny":
9127
- permit = TailorDBType_Permission_Permit.DENY;
9128
- break;
9129
- default: throw new Error(`Unknown permission: ${policy.permit}`);
9130
- }
9131
- return {
9132
- conditions: policy.conditions.map((cond) => protoCondition(cond)),
9133
- permit,
9134
- description: policy.description
9135
- };
9136
- }
9137
- function protoCondition(condition) {
9138
- const [left, operator, right] = condition;
9139
- const l = protoOperand(left);
9140
- const r = protoOperand(right);
9141
- let op;
9142
- switch (operator) {
9143
- case "eq":
9144
- op = TailorDBType_Permission_Operator.EQ;
9145
- break;
9146
- case "ne":
9147
- op = TailorDBType_Permission_Operator.NE;
9148
- break;
9149
- case "in":
9150
- op = TailorDBType_Permission_Operator.IN;
9151
- break;
9152
- case "nin":
9153
- op = TailorDBType_Permission_Operator.NIN;
9154
- break;
9155
- case "hasAny":
9156
- op = TailorDBType_Permission_Operator.HAS_ANY;
9157
- break;
9158
- case "nhasAny":
9159
- op = TailorDBType_Permission_Operator.NHAS_ANY;
9160
- break;
9161
- default: throw new Error(`Unknown operator: ${operator}`);
9162
- }
9163
- return {
9164
- left: l,
9165
- operator: op,
9166
- right: r
9167
- };
9168
- }
9169
- function protoOperand(operand) {
9170
- if (isSnapshotFieldRefOperand(operand)) {
9171
- if ("user" in operand) return { kind: {
9172
- case: "userField",
9173
- value: operand.user
9174
- } };
9175
- if ("record" in operand) return { kind: {
9176
- case: "recordField",
9177
- value: operand.record
9178
- } };
9179
- if ("newRecord" in operand) return { kind: {
9180
- case: "newRecordField",
9181
- value: operand.newRecord
9182
- } };
9183
- if ("oldRecord" in operand) return { kind: {
9184
- case: "oldRecordField",
9185
- value: operand.oldRecord
9186
- } };
9187
- throw new Error(`Unknown field-ref operand shape: ${JSON.stringify(operand)}`);
9188
- }
9189
- return { kind: {
9190
- case: "value",
9191
- value: fromJson(ValueSchema, operand)
9192
- } };
9193
- }
9194
9208
  async function planGqlPermissions(client, workspaceId, tailordbs, deletedServices, forceApplyAll = false) {
9195
9209
  const changeSet = createChangeSet("TailorDB gqlPermissions");
9196
9210
  const fetchGqlPermissions = (namespaceName) => {
@@ -9269,7 +9283,7 @@ async function planGqlPermissions(client, workspaceId, tailordbs, deletedService
9269
9283
  function normalizeComparableGqlPermission(permission) {
9270
9284
  return { policies: (normalizeProtoConfig(permission)?.policies ?? []).map((policy) => ({
9271
9285
  ...policy,
9272
- actions: [...policy.actions ?? []].sort((left, right) => left - right)
9286
+ actions: (policy.actions ?? []).toSorted((left, right) => left - right)
9273
9287
  })) };
9274
9288
  }
9275
9289
  function protoGqlPermission(permission) {
@@ -9518,7 +9532,7 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
9518
9532
  scriptRef: workflowJobFunctionName(jobName)
9519
9533
  });
9520
9534
  await client.setMetadata(await buildMetaRequest({
9521
- trn: jobFunctionTrn(workspaceId, jobName),
9535
+ trn: resourceTrn(workspaceId, "workflow_job_function", jobName),
9522
9536
  appName,
9523
9537
  appId
9524
9538
  }));
@@ -9531,9 +9545,9 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
9531
9545
  }
9532
9546
  const unusedJobFunctions = existingJobFunctions.filter((jobName) => !allUsedJobNames.has(jobName));
9533
9547
  await Promise.all(unusedJobFunctions.map(async (jobName) => {
9534
- const { metadata } = await client.getMetadata({ trn: jobFunctionTrn(workspaceId, jobName) });
9548
+ const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "workflow_job_function", jobName) });
9535
9549
  if (isOwnedByApp(metadata?.labels, appName, appId)) await client.setMetadata({
9536
- trn: jobFunctionTrn(workspaceId, jobName),
9550
+ trn: resourceTrn(workspaceId, "workflow_job_function", jobName),
9537
9551
  labels: { [sdkNameLabelKey]: "" }
9538
9552
  });
9539
9553
  }));
@@ -9559,12 +9573,6 @@ function toRetryPolicy(policy) {
9559
9573
  function toConcurrencyPolicy(policy) {
9560
9574
  return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
9561
9575
  }
9562
- function workflowTrn$1(workspaceId, name) {
9563
- return `trn:v1:workspace:${workspaceId}:workflow:${name}`;
9564
- }
9565
- function jobFunctionTrn(workspaceId, name) {
9566
- return `trn:v1:workspace:${workspaceId}:workflow_job_function:${name}`;
9567
- }
9568
9576
  /**
9569
9577
  * Plan workflow changes and job functions based on current and desired state.
9570
9578
  * @param client - Operator client instance
@@ -9594,12 +9602,12 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
9594
9602
  return [response.workflows, response.nextPageToken];
9595
9603
  },
9596
9604
  getName: (resource) => resource.name,
9597
- getTrn: workflowTrn$1
9605
+ getTrn: (workspaceId, name) => resourceTrn(workspaceId, "workflow", name)
9598
9606
  });
9599
9607
  for (const workflow of Object.values(workflows)) {
9600
9608
  const existing = existingWorkflows[workflow.name];
9601
9609
  const metaRequest = await buildMetaRequest({
9602
- trn: workflowTrn$1(workspaceId, workflow.name),
9610
+ trn: resourceTrn(workspaceId, "workflow", workflow.name),
9603
9611
  appName,
9604
9612
  appId
9605
9613
  });
@@ -9704,12 +9712,12 @@ function normalizeComparableConcurrencyPolicy(policy) {
9704
9712
  return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
9705
9713
  }
9706
9714
  function normalizeComparableWorkflowJobNames(jobFunctions) {
9707
- return Array.isArray(jobFunctions) ? [...jobFunctions].sort() : Object.keys(jobFunctions ?? {}).sort();
9715
+ return Array.isArray(jobFunctions) ? jobFunctions.toSorted() : Object.keys(jobFunctions ?? {}).toSorted();
9708
9716
  }
9709
9717
  function getExistingWorkflowJobNames(existing) {
9710
9718
  const jobNames = new Set(Object.keys(existing.jobFunctions ?? {}));
9711
9719
  if (existing.mainJobFunctionName) jobNames.add(existing.mainJobFunctionName);
9712
- return [...jobNames].sort();
9720
+ return [...jobNames].toSorted();
9713
9721
  }
9714
9722
  function normalizeRetryPolicyForCompare(policy) {
9715
9723
  return {
@@ -9728,36 +9736,6 @@ function normalizeRetryPolicyForCompare(policy) {
9728
9736
 
9729
9737
  //#endregion
9730
9738
  //#region src/cli/commands/deploy/deploy.ts
9731
- function applicationTrn(workspaceId, name) {
9732
- return `trn:v1:workspace:${workspaceId}:application:${name}`;
9733
- }
9734
- function functionRegistryTrn(workspaceId, name) {
9735
- return `trn:v1:workspace:${workspaceId}:function_registry:${name}`;
9736
- }
9737
- function pipelineTrn(workspaceId, name) {
9738
- return `trn:v1:workspace:${workspaceId}:pipeline:${name}`;
9739
- }
9740
- function idpTrn(workspaceId, name) {
9741
- return `trn:v1:workspace:${workspaceId}:idp:${name}`;
9742
- }
9743
- function authTrn(workspaceId, name) {
9744
- return `trn:v1:workspace:${workspaceId}:auth:${name}`;
9745
- }
9746
- function executorTrn(workspaceId, name) {
9747
- return `trn:v1:workspace:${workspaceId}:executor:${name}`;
9748
- }
9749
- function workflowTrn(workspaceId, name) {
9750
- return `trn:v1:workspace:${workspaceId}:workflow:${name}`;
9751
- }
9752
- function staticWebsiteTrn(workspaceId, name) {
9753
- return `trn:v1:workspace:${workspaceId}:staticwebsite:${name}`;
9754
- }
9755
- function tailorDBTrn(workspaceId, name) {
9756
- return `trn:v1:workspace:${workspaceId}:tailordb:${name}`;
9757
- }
9758
- function vaultTrn(workspaceId, name) {
9759
- return `trn:v1:workspace:${workspaceId}:vault:${name}`;
9760
- }
9761
9739
  /**
9762
9740
  * Resolve the set of IdP names that have at least one executor subscribed to
9763
9741
  * their user events. When an executor's idpUser trigger omits the `idp` option
@@ -9779,36 +9757,36 @@ function collectIdpUserTriggerTargets(application) {
9779
9757
  }
9780
9758
  async function shouldForceApplyAll(client, workspaceId, application, functionEntries) {
9781
9759
  const desiredLabels = (await buildMetaRequest({
9782
- trn: applicationTrn(workspaceId, application.name),
9760
+ trn: resourceTrn(workspaceId, "application", application.name),
9783
9761
  appName: application.name,
9784
9762
  appId: application.id
9785
9763
  })).labels;
9786
9764
  const candidateTrns = /* @__PURE__ */ new Set();
9787
- if (application.subgraphs.length > 0) candidateTrns.add(applicationTrn(workspaceId, application.name));
9765
+ if (application.subgraphs.length > 0) candidateTrns.add(resourceTrn(workspaceId, "application", application.name));
9788
9766
  application.staticWebsiteServices.forEach((website) => {
9789
- candidateTrns.add(staticWebsiteTrn(workspaceId, website.name));
9767
+ candidateTrns.add(resourceTrn(workspaceId, "staticwebsite", website.name));
9790
9768
  });
9791
9769
  application.resolverServices.forEach((pipeline) => {
9792
- candidateTrns.add(pipelineTrn(workspaceId, pipeline.namespace));
9770
+ candidateTrns.add(resourceTrn(workspaceId, "pipeline", pipeline.namespace));
9793
9771
  });
9794
9772
  application.idpServices.forEach((idp) => {
9795
- candidateTrns.add(idpTrn(workspaceId, idp.name));
9773
+ candidateTrns.add(resourceTrn(workspaceId, "idp", idp.name));
9796
9774
  });
9797
- if (application.authService) candidateTrns.add(authTrn(workspaceId, application.authService.config.name));
9775
+ if (application.authService) candidateTrns.add(resourceTrn(workspaceId, "auth", application.authService.config.name));
9798
9776
  Object.values(application.executorService?.executors ?? {}).forEach((executor) => {
9799
- candidateTrns.add(executorTrn(workspaceId, executor.name));
9777
+ candidateTrns.add(resourceTrn(workspaceId, "executor", executor.name));
9800
9778
  });
9801
9779
  Object.values(application.workflowService?.workflows ?? {}).forEach((workflow) => {
9802
- candidateTrns.add(workflowTrn(workspaceId, workflow.name));
9780
+ candidateTrns.add(resourceTrn(workspaceId, "workflow", workflow.name));
9803
9781
  });
9804
9782
  application.tailorDBServices.forEach((service) => {
9805
- candidateTrns.add(tailorDBTrn(workspaceId, service.namespace));
9783
+ candidateTrns.add(resourceTrn(workspaceId, "tailordb", service.namespace));
9806
9784
  });
9807
9785
  application.secrets.forEach((vault) => {
9808
- candidateTrns.add(vaultTrn(workspaceId, vault.vaultName));
9786
+ candidateTrns.add(resourceTrn(workspaceId, "vault", vault.vaultName));
9809
9787
  });
9810
9788
  functionEntries.forEach((entry) => {
9811
- candidateTrns.add(functionRegistryTrn(workspaceId, entry.name));
9789
+ candidateTrns.add(resourceTrn(workspaceId, "function_registry", entry.name));
9812
9790
  });
9813
9791
  for (const trn of candidateTrns) try {
9814
9792
  const { metadata } = await client.getMetadata({ trn });
@@ -9865,6 +9843,7 @@ function printPlanResults(results) {
9865
9843
  const idpServiceActions = extractServiceActions(results.idp.changeSet.service);
9866
9844
  const authServiceActions = extractServiceActions(results.auth.changeSet.service);
9867
9845
  results.staticWebsite.changeSet.print();
9846
+ results.staticWebsite.customDomainChangeSet.print();
9868
9847
  results.app.print();
9869
9848
  printGroupedDisplaySection("TailorDB", tailorDBEntries, tailorDBServiceActions);
9870
9849
  printGroupedDisplaySection("Resolver", pipelineEntries, pipelineServiceActions);
@@ -9914,6 +9893,7 @@ function summarizePlanResults(results, displayEntries, serviceActions) {
9914
9893
  const nonGrouped = summarizeChangeSets([
9915
9894
  otherChanges,
9916
9895
  results.staticWebsite.changeSet,
9896
+ results.staticWebsite.customDomainChangeSet,
9917
9897
  results.app,
9918
9898
  results.secretManager.vaultChangeSet,
9919
9899
  results.secretManager.secretChangeSet
@@ -14488,7 +14468,7 @@ async function generate(options) {
14488
14468
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
14489
14469
  let pluginManager;
14490
14470
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
14491
- const { defineApplication } = await import("./application-x_mURdR0.mjs");
14471
+ const { defineApplication } = await import("./application-VOdgMtOD.mjs");
14492
14472
  const application = defineApplication({
14493
14473
  config,
14494
14474
  pluginManager
@@ -15821,6 +15801,7 @@ async function bundleQueryScript(engine) {
15821
15801
  tsconfig = void 0;
15822
15802
  }
15823
15803
  return (await rolldown.build({
15804
+ plugins: [platformBundleDefinePlugin],
15824
15805
  input: entryPath,
15825
15806
  write: false,
15826
15807
  output: {
@@ -16347,7 +16328,7 @@ async function runRepl(options) {
16347
16328
  const execute = await prepareQueryExecutor(options);
16348
16329
  const historyPath = getReplHistoryPath(options.engine, options.profile, options.workspaceId);
16349
16330
  const validate = createReplValidator(options.engine);
16350
- const { highlightSqlLine, highlightGraphqlLine, replTransform } = await import("./repl-editor-ihh8koiR.mjs");
16331
+ const { highlightSqlLine, highlightGraphqlLine, replTransform } = await import("./repl-editor-Y9QJDL0K.mjs");
16351
16332
  const highlight = options.engine === "sql" ? highlightSqlLine : highlightGraphqlLine;
16352
16333
  const prompt = createPrompt({
16353
16334
  prefix: "",
@@ -16680,5 +16661,5 @@ function isDeno() {
16680
16661
  }
16681
16662
 
16682
16663
  //#endregion
16683
- export { listCommand$5 as $, compareSnapshots as $t, truncate as A, toPageDirection as An, startCommand as At, logBetaWarning as B, getExecutor as Bt, listCommand$2 as C, commonArgs as Cn, triggerExecutor as Ct, resumeWorkflow as D, isVerbose as Dn, jobsCommand as Dt, resumeCommand as E, deploymentArgs as En, getExecutorJob as Et, writeDbTypesFile as F, getWorkflowExecution as Ft, organizationTree as G, parseMigrationLabelNumber as Gt, removeCommand$1 as H, executeScript as Ht, getConfiguredEditorCommand as I, listWorkflowExecutions as It, listOrganizations as J, DIFF_FILE_NAME as Jt, treeCommand as K, bundleMigrationScript as Kt, openInConfiguredEditor as L, functionExecutionStatusToString as Lt, generate as M, getCommand$5 as Mt, generateCommand as N, getWorkflow as Nt, listCommand$3 as O, pagedLogArgs as On, listExecutorJobs as Ot, generateMigrationScript as P, executionsCommand as Pt, updateFolder as Q, compareLocalTypesWithSnapshot as Qt, show as R, formatKeyValueTable as Rt, listApps as S, defineAppCommand as Sn, triggerCommand as St, healthCommand as T, confirmationArgs as Tn, listExecutors as Tt, updateCommand$1 as U, waitForExecution$1 as Ut, remove as V, deploy as Vt, updateOrganization as W, MIGRATION_LABEL_KEY as Wt, getOrganization as X, MIGRATE_FILE_NAME as Xt, getCommand$1 as Y, INITIAL_SCHEMA_NUMBER as Yt, updateCommand$2 as Z, SCHEMA_FILE_NAME as Zt, getWorkspace as _, generateUserTypes as _n, listFunctionRegistries as _t, updateUser as a, getNextMigrationNumber as an, createCommand$1 as at, createCommand as b, apiCall as bn, listWebhookExecutors as bt, listCommand as c, reconstructSnapshotFromMigrations as cn, listOAuth2Clients as ct, inviteUser as d, formatMigrationDiff as dn, getMachineUserToken as dt, createSnapshotFromLocalTypes as en, listFolders as et, restoreCommand as f, hasChanges as fn, tokenCommand as ft, getCommand as g, PluginManager as gn, listCommand$8 as gt, listWorkspaces as h, trnPrefix as hn, generate$1 as ht, updateCommand as i, getMigrationFiles as in, deleteFolder as it, truncateCommand as j, workspaceArgs as jn, startWorkflow as jt, listWorkflows as k, paginationArgs as kn, watchExecutorJob as kt, listUsers as l, formatMigrationNumber as ln, getCommand$3 as lt, listCommand$1 as m, sdkNameLabelKey as mn, listMachineUsers as mt, query as n, getMigrationDirPath as nn, getFolder as nt, removeCommand as o, isValidMigrationNumber as on, createFolder as ot, restoreWorkspace as p, getNamespacesWithMigrations as pn, listCommand$7 as pt, listCommand$4 as q, DB_TYPES_FILE_NAME as qt, queryCommand as r, getMigrationFilePath as rn, deleteCommand$1 as rt, removeUser as s, loadDiff as sn, listCommand$6 as st, isNativeTypeScriptRuntime as t, getLatestMigrationNumber as tn, getCommand$2 as tt, inviteCommand as u, formatDiffSummary as un, getOAuth2Client as ut, deleteCommand as v, prompt as vn, getCommand$4 as vt, getAppHealth as w, configArg as wn, listCommand$9 as wt, createWorkspace as x, assertWritable as xn, webhookCommand as xt, deleteWorkspace as y, apiCommand as yn, getFunctionRegistry as yt, showCommand as z, getCommand$6 as zt };
16684
- //# sourceMappingURL=runtime-1YuaoNr8.mjs.map
16664
+ export { listCommand$5 as $, compareSnapshots as $t, truncate as A, toPageDirection as An, startCommand as At, logBetaWarning as B, getExecutor as Bt, listCommand$2 as C, commonArgs as Cn, triggerExecutor as Ct, resumeWorkflow as D, isVerbose as Dn, jobsCommand as Dt, resumeCommand as E, deploymentArgs as En, getExecutorJob as Et, writeDbTypesFile as F, getWorkflowExecution as Ft, organizationTree as G, parseMigrationLabelNumber as Gt, removeCommand$1 as H, executeScript as Ht, getConfiguredEditorCommand as I, listWorkflowExecutions as It, listOrganizations as J, DIFF_FILE_NAME as Jt, treeCommand as K, bundleMigrationScript as Kt, openInConfiguredEditor as L, functionExecutionStatusToString as Lt, generate as M, getCommand$5 as Mt, generateCommand as N, getWorkflow as Nt, listCommand$3 as O, pagedLogArgs as On, listExecutorJobs as Ot, generateMigrationScript as P, executionsCommand as Pt, updateFolder as Q, compareLocalTypesWithSnapshot as Qt, show as R, formatKeyValueTable as Rt, listApps as S, defineAppCommand as Sn, triggerCommand as St, healthCommand as T, confirmationArgs as Tn, listExecutors as Tt, updateCommand$1 as U, waitForExecution$1 as Ut, remove as V, deploy as Vt, updateOrganization as W, MIGRATION_LABEL_KEY as Wt, getOrganization as X, MIGRATE_FILE_NAME as Xt, getCommand$1 as Y, INITIAL_SCHEMA_NUMBER as Yt, updateCommand$2 as Z, SCHEMA_FILE_NAME as Zt, getWorkspace as _, generateUserTypes as _n, listFunctionRegistries as _t, updateUser as a, getNextMigrationNumber as an, createCommand$1 as at, createCommand as b, apiCall as bn, listWebhookExecutors as bt, listCommand as c, reconstructSnapshotFromMigrations as cn, listOAuth2Clients as ct, inviteUser as d, formatMigrationDiff as dn, getMachineUserToken as dt, createSnapshotFromLocalTypes as en, listFolders as et, restoreCommand as f, hasChanges as fn, tokenCommand as ft, getCommand as g, PluginManager as gn, listCommand$8 as gt, listWorkspaces as h, sdkNameLabelKey as hn, generate$1 as ht, updateCommand as i, getMigrationFiles as in, deleteFolder as it, truncateCommand as j, workspaceArgs as jn, startWorkflow as jt, listWorkflows as k, paginationArgs as kn, watchExecutorJob as kt, listUsers as l, formatMigrationNumber as ln, getCommand$3 as lt, listCommand$1 as m, resourceTrn as mn, listMachineUsers as mt, query as n, getMigrationDirPath as nn, getFolder as nt, removeCommand as o, isValidMigrationNumber as on, createFolder as ot, restoreWorkspace as p, getNamespacesWithMigrations as pn, listCommand$7 as pt, listCommand$4 as q, DB_TYPES_FILE_NAME as qt, queryCommand as r, getMigrationFilePath as rn, deleteCommand$1 as rt, removeUser as s, loadDiff as sn, listCommand$6 as st, isNativeTypeScriptRuntime as t, getLatestMigrationNumber as tn, getCommand$2 as tt, inviteCommand as u, formatDiffSummary as un, getOAuth2Client as ut, deleteCommand as v, prompt as vn, getCommand$4 as vt, getAppHealth as w, configArg as wn, listCommand$9 as wt, createWorkspace as x, assertWritable as xn, webhookCommand as xt, deleteWorkspace as y, apiCommand as yn, getFunctionRegistry as yt, showCommand as z, getCommand$6 as zt };
16665
+ //# sourceMappingURL=runtime-CrUa8Z2k.mjs.map