@tailor-platform/sdk 2.0.0-next.10 → 2.0.0-next.11

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 (129) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/dist/{application-miwiXtB4.mjs → application-CM6hKnSK.mjs} +312 -89
  3. package/dist/application-CM6hKnSK.mjs.map +1 -0
  4. package/dist/application-CXNaUNhv.mjs +3 -0
  5. package/dist/cli/commands/deploy/aigateway.d.mts +1 -1
  6. package/dist/cli/commands/deploy/application.d.mts +1 -1
  7. package/dist/cli/commands/deploy/auth.d.mts +1 -1
  8. package/dist/cli/commands/deploy/deploy.d.mts +1 -0
  9. package/dist/cli/commands/deploy/executor.d.mts +1 -1
  10. package/dist/cli/commands/deploy/function-registry.d.mts +1 -2
  11. package/dist/cli/commands/deploy/idp.d.mts +1 -1
  12. package/dist/cli/commands/deploy/label.d.mts +2 -0
  13. package/dist/cli/commands/deploy/resolver.d.mts +1 -1
  14. package/dist/cli/commands/deploy/staticwebsite.d.mts +1 -1
  15. package/dist/cli/commands/deploy/tailordb/index.d.mts +2 -1
  16. package/dist/cli/commands/deploy/types.d.mts +2 -1
  17. package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +1 -2
  18. package/dist/cli/commands/deploy/workflow.d.mts +1 -1
  19. package/dist/cli/commands/executor/get.d.mts +1 -10
  20. package/dist/cli/commands/executor/jobs.d.mts +1 -38
  21. package/dist/cli/commands/executor/trigger.d.mts +1 -11
  22. package/dist/cli/commands/generate/seed/bundler.d.mts +2 -1
  23. package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +5 -0
  24. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
  25. package/dist/cli/commands/workflow/executions.d.mts +1 -13
  26. package/dist/cli/commands/workflow/get.d.mts +1 -10
  27. package/dist/cli/commands/workflow/start.d.mts +2 -14
  28. package/dist/cli/lib.d.mts +7 -11
  29. package/dist/cli/lib.mjs +99 -42
  30. package/dist/cli/lib.mjs.map +1 -1
  31. package/dist/cli/main.mjs +318 -124
  32. package/dist/cli/main.mjs.map +1 -1
  33. package/dist/cli/services/http-adapter/bundler.d.mts +1 -0
  34. package/dist/cli/services/workflow/bundler.d.mts +2 -1
  35. package/dist/cli/shared/client.d.mts +28 -3
  36. package/dist/cli/shared/config-loader.d.mts +11 -4
  37. package/dist/cli/shared/tsconfig-paths-plugin.d.mts +2 -0
  38. package/dist/cli/shared/type-generator.d.mts +4 -3
  39. package/dist/completion/zsh-worker.zsh +82 -22
  40. package/dist/configure/config/types.d.mts +26 -3
  41. package/dist/configure/index.d.mts +2 -2
  42. package/dist/configure/index.mjs +171 -3
  43. package/dist/configure/index.mjs.map +1 -1
  44. package/dist/configure/services/executor/index.d.mts +2 -2
  45. package/dist/configure/services/executor/trigger/event.d.mts +245 -2
  46. package/dist/configure/services/executor/trigger/index.d.mts +3 -3
  47. package/dist/configure/services/idp/index.d.mts +1 -1
  48. package/dist/configure/services/index.d.mts +2 -2
  49. package/dist/configure/services/tailordb/index.d.mts +0 -1
  50. package/dist/configure/services/workflow/execution-policy.d.mts +1 -1
  51. package/dist/configure/services/workflow/execution-policy.types.d.mts +1 -1
  52. package/dist/configure/services/workflow/job.d.mts +11 -2
  53. package/dist/configure/services/workflow/workflow.d.mts +10 -0
  54. package/dist/{globals-DQotNuwK.mjs → globals-TfAVItuK.mjs} +1 -2
  55. package/dist/globals-TfAVItuK.mjs.map +1 -0
  56. package/dist/node-builtins-CmaL2Cbq.mjs +36 -0
  57. package/dist/node-builtins-CmaL2Cbq.mjs.map +1 -0
  58. package/dist/plugin/builtin/enum-constants/index.mjs +115 -2
  59. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -0
  60. package/dist/plugin/builtin/file-utils/index.mjs +149 -2
  61. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -0
  62. package/dist/plugin/builtin/kysely-type/index.mjs +274 -2
  63. package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -0
  64. package/dist/plugin/builtin/seed/index.mjs +1 -1
  65. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +2 -0
  66. package/dist/{register-ts-hook-BAHMwxfG.mjs → register-ts-hook-LYV7zH-e.mjs} +2252 -797
  67. package/dist/register-ts-hook-LYV7zH-e.mjs.map +1 -0
  68. package/dist/registry-BIGVUrMB.mjs.map +1 -1
  69. package/dist/runtime/index.mjs +1 -1
  70. package/dist/runtime/workflow.d.mts +2 -20
  71. package/dist/runtime/workflow.mjs +1 -1
  72. package/dist/{seed-LUVr7jHL.mjs → seed-B-yckgQY.mjs} +42 -3
  73. package/dist/seed-B-yckgQY.mjs.map +1 -0
  74. package/dist/service-M7OYziQP.mjs +3 -0
  75. package/dist/{service-BNtPsK9Q.mjs → service-k1xy_A5G.mjs} +29 -2
  76. package/dist/{service-BNtPsK9Q.mjs.map → service-k1xy_A5G.mjs.map} +1 -1
  77. package/dist/{service_pb-BwZRiNug.mjs → service_pb-D5--My_M.mjs} +5 -5
  78. package/dist/service_pb-D5--My_M.mjs.map +1 -0
  79. package/dist/{service_pb-wRkxUta6.mjs → service_pb-i8CmnQP4.mjs} +1 -1
  80. package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +106 -1
  81. package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +24 -1
  82. package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +49 -1
  83. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +89 -6
  84. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +26 -1
  85. package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +101 -1
  86. package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +22 -1
  87. package/dist/types/executor.generated.d.mts +23 -3
  88. package/dist/types/idp.generated.d.mts +1 -1
  89. package/dist/utils/test/index.d.mts +1 -2
  90. package/dist/utils/test/index.mjs +1 -173
  91. package/dist/utils/test/index.mjs.map +1 -1
  92. package/dist/vitest/environment.mjs +1 -1
  93. package/dist/vitest/index.d.mts +2 -2
  94. package/dist/vitest/index.mjs +10 -52
  95. package/dist/vitest/index.mjs.map +1 -1
  96. package/dist/vitest/mocks/workflow.d.mts +0 -9
  97. package/dist/vitest/setup.mjs +1 -1
  98. package/dist/{workflow-CsaQ9qK-.mjs → workflow-Bamae_Yc.mjs} +1 -9
  99. package/dist/workflow-Bamae_Yc.mjs.map +1 -0
  100. package/dist/{workspace_resource_pb-UGK1SSn_.mjs → workspace_resource_pb-DXnO2AT-.mjs} +7 -7
  101. package/dist/workspace_resource_pb-DXnO2AT-.mjs.map +1 -0
  102. package/docs/cli/tailordb.md +39 -7
  103. package/docs/cli-reference.md +11 -10
  104. package/docs/configuration.md +50 -0
  105. package/docs/migration/v2.md +306 -9
  106. package/docs/runtime.md +1 -1
  107. package/docs/services/executor.md +83 -3
  108. package/docs/services/idp.md +8 -6
  109. package/docs/services/resolver.md +6 -4
  110. package/docs/services/tailordb-migration.md +17 -6
  111. package/docs/services/tailordb.md +6 -4
  112. package/docs/services/workflow.md +33 -3
  113. package/package.json +19 -17
  114. package/dist/application-DArFTTJ9.mjs +0 -3
  115. package/dist/application-miwiXtB4.mjs.map +0 -1
  116. package/dist/enum-constants-j9QBF0cB.mjs +0 -116
  117. package/dist/enum-constants-j9QBF0cB.mjs.map +0 -1
  118. package/dist/file-utils-yEiIS4nJ.mjs +0 -150
  119. package/dist/file-utils-yEiIS4nJ.mjs.map +0 -1
  120. package/dist/globals-DQotNuwK.mjs.map +0 -1
  121. package/dist/kysely-type-DqIRgDYR.mjs +0 -275
  122. package/dist/kysely-type-DqIRgDYR.mjs.map +0 -1
  123. package/dist/register-ts-hook-BAHMwxfG.mjs.map +0 -1
  124. package/dist/seed-LUVr7jHL.mjs.map +0 -1
  125. package/dist/service-D5jn05ZI.mjs +0 -3
  126. package/dist/service_pb-BwZRiNug.mjs.map +0 -1
  127. package/dist/utils/test/mock.d.mts +0 -86
  128. package/dist/workflow-CsaQ9qK-.mjs.map +0 -1
  129. package/dist/workspace_resource_pb-UGK1SSn_.mjs.map +0 -1
@@ -1,11 +1,13 @@
1
1
  import { n as isSdkBranded } from "./brand-Eo4pLXPJ.mjs";
2
2
  import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
3
3
  import { a as parseBoolean, n as logger, r as styles } from "./logger-CXQq9YIp.mjs";
4
- import { a as AuthConfigSchema, c as stripTailorDBTypeBuilderHelpers, d as applyRelationMetadataToFieldConfig, f as buildRelationInfo, g as functionSchema, h as loadFilesWithIgnores, l as TailorDBServiceConfigSchema, m as validateRelationConfig, n as loadExecutor, o as AuthInvokerSchema, p as processRelationMetadata, s as TailorFieldSchema, t as createExecutorService, u as TailorDBTypeSchema } from "./service-BNtPsK9Q.mjs";
4
+ import { a as AuthConfigSchema, c as stripTailorDBTypeBuilderHelpers, d as applyRelationMetadataToFieldConfig, f as buildRelationInfo, g as functionSchema, h as loadFilesWithIgnores, l as TailorDBServiceConfigSchema, m as validateRelationConfig, n as loadExecutor, o as AuthInvokerSchema, p as processRelationMetadata, s as TailorFieldSchema, t as createExecutorService, u as TailorDBTypeSchema } from "./service-k1xy_A5G.mjs";
5
5
  import { t as multiline } from "./multiline-sfHpTZZK.mjs";
6
6
  import { t as userAgent } from "./user-agent-Bgsszb5I.mjs";
7
+ import { t as createCLIError } from "./errors-D7583Zz7.mjs";
8
+ import { n as isNodeBuiltinImport, t as getNodeBuiltinMessage } from "./node-builtins-CmaL2Cbq.mjs";
7
9
  import { t as isPluginGeneratedType } from "./type-source-DH_LH20p.mjs";
8
- import { builtinModules, createRequire } from "node:module";
10
+ import { createRequire } from "node:module";
9
11
  import * as path from "pathe";
10
12
  import { resolve } from "pathe";
11
13
  import { resolveTSConfig } from "pkg-types";
@@ -17,11 +19,11 @@ import { MethodOptions_IdempotencyLevel } from "@bufbuild/protobuf/wkt";
17
19
  import { pathToFileURL } from "node:url";
18
20
  import { OAuth2Client } from "@badgateway/oauth2-client";
19
21
  import { Code, ConnectError, createClient } from "@connectrpc/connect";
20
- import { getGlobalDispatcher } from "undici";
21
22
  import pLimit from "p-limit";
22
23
  import * as crypto from "node:crypto";
23
24
  import * as rolldown from "rolldown";
24
25
  import { parseSync } from "oxc-parser";
26
+ import { createPathsMatcher, getTsconfig } from "get-tsconfig";
25
27
  import * as inflection from "inflection";
26
28
  import * as globals from "globals";
27
29
  import * as os from "node:os";
@@ -180,7 +182,7 @@ function initOAuth2Client(config) {
180
182
  */
181
183
  async function initOperatorClient(accessToken, config) {
182
184
  const platformConfig = config ?? getPlatformConfigForToken(accessToken);
183
- const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-e33JtsC-.mjs"), import("./service_pb-wRkxUta6.mjs")]);
185
+ const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-e33JtsC-.mjs"), import("./service_pb-i8CmnQP4.mjs")]);
184
186
  const interceptors = [
185
187
  await userAgentInterceptor(),
186
188
  await bearerTokenInterceptor(accessToken),
@@ -233,9 +235,10 @@ async function bearerTokenInterceptor(accessToken) {
233
235
  /**
234
236
  * Create an interceptor that retries failed unary requests with backoff.
235
237
  *
236
- * Retries unary methods on `Unavailable`/`ResourceExhausted`, and `Internal`
237
- * only for methods declared idempotent, up to 3 attempts. Workspace creation is
238
- * excluded because it has no idempotency key and a lost response is ambiguous.
238
+ * Retries unary methods on `Unavailable`/`ResourceExhausted`, and
239
+ * `Aborted`/`Internal` only for methods declared side-effect-free or idempotent,
240
+ * up to 3 attempts. Workspace creation is excluded because it has no idempotency
241
+ * key and a lost response is ambiguous.
239
242
  * As a targeted exception for the deploy/apply flow, a post-retry `AlreadyExists`
240
243
  * from an allowlisted Create (see `RETRY_SAFE_CREATE_METHODS`) is treated as
241
244
  * success, since it means a prior attempt already committed the resource
@@ -414,6 +417,7 @@ function isRetirable(error, idempotency) {
414
417
  switch (error.code) {
415
418
  case Code.ResourceExhausted:
416
419
  case Code.Unavailable: return true;
420
+ case Code.Aborted:
417
421
  case Code.Internal: return idempotency === MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS || idempotency === MethodOptions_IdempotencyLevel.IDEMPOTENT;
418
422
  default: return false;
419
423
  }
@@ -662,12 +666,20 @@ async function fetchPlatformMachineUserToken(clientId, clientSecret, config) {
662
666
  }).clientCredentials();
663
667
  }
664
668
  /**
665
- * Close undici's global HTTP connection pool to prevent libuv UV_HANDLE_CLOSING
669
+ * Close the global HTTP connection pool to prevent libuv UV_HANDLE_CLOSING
666
670
  * assertion failure on Windows at process exit (Node.js 23.x+).
667
671
  * See: https://github.com/nodejs/node/issues/56645
672
+ *
673
+ * The pool is reached through the global dispatcher symbol rather than the `undici`
674
+ * package: importing that package installs its own Agent over these same globals,
675
+ * replacing the HTTP stack Node's `fetch` already uses. The symbol is versioned per
676
+ * Dispatcher API generation, and the newest one wins because older symbols hold a
677
+ * wrapper around that same pool — closing both would destroy it twice.
668
678
  */
669
679
  async function closeConnectionPool() {
670
- await getGlobalDispatcher().close();
680
+ const globals = globalThis;
681
+ const dispatcher = globals[Symbol.for("undici.globalDispatcher.2")] ?? globals[Symbol.for("undici.globalDispatcher.1")];
682
+ if (typeof dispatcher?.close === "function") await dispatcher.close();
671
683
  }
672
684
 
673
685
  //#endregion
@@ -689,17 +701,27 @@ function hashFile(filePath) {
689
701
  const content = fs.readFileSync(filePath);
690
702
  return crypto.createHash("sha256").update(content).digest("hex");
691
703
  }
704
+ const MISSING_FILE_MARKER = "<missing>";
692
705
  /**
693
706
  * Compute a deterministic SHA-256 hash for multiple files.
694
707
  *
695
708
  * Paths are sorted alphabetically before hashing so that the result
696
709
  * is independent of the order the paths are supplied (e.g. glob ordering).
697
- * Each file's individual hash is concatenated and then hashed again.
710
+ * Each file's individual hash is concatenated and then hashed again. A path
711
+ * that does not exist contributes a fixed marker instead of a content hash.
698
712
  * @param filePaths - Array of absolute file paths
699
713
  * @returns Hex-encoded SHA-256 hash representing all files
700
714
  */
701
715
  function hashFiles(filePaths) {
702
- return hashContent(filePaths.toSorted().map((fp) => hashFile(fp)).join(""));
716
+ return hashContent(filePaths.toSorted().map((fp) => hashFileOrMissing(fp)).join(""));
717
+ }
718
+ function hashFileOrMissing(filePath) {
719
+ try {
720
+ return hashFile(filePath);
721
+ } catch (error) {
722
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return MISSING_FILE_MARKER;
723
+ throw error;
724
+ }
703
725
  }
704
726
 
705
727
  //#endregion
@@ -775,7 +797,7 @@ function computeBundlerContextHash(params) {
775
797
  */
776
798
  async function withCache(params) {
777
799
  const { cache, kind, namespace, name, sourceFile, contextHash, build } = params;
778
- if (!cache) return await build([]);
800
+ if (!cache) return await build([], () => {});
779
801
  const content = cache.tryRestore({
780
802
  kind,
781
803
  namespace,
@@ -786,15 +808,16 @@ async function withCache(params) {
786
808
  logger.debug(` ${styles.dim("cached")}: ${name}`);
787
809
  return content;
788
810
  }
811
+ const extraDependencies = /* @__PURE__ */ new Set();
789
812
  const { plugin, getResult } = createDepCollectorPlugin();
790
- const code = await build([plugin]);
813
+ const code = await build([plugin], (filePath) => extraDependencies.add(filePath));
791
814
  cache.save({
792
815
  kind,
793
816
  namespace,
794
817
  name,
795
818
  sourceFile,
796
819
  content: code,
797
- dependencyPaths: getResult(),
820
+ dependencyPaths: [...getResult(), ...extraDependencies],
798
821
  contextHash
799
822
  });
800
823
  return code;
@@ -825,7 +848,12 @@ function createBundleCache(store) {
825
848
  const { kind, namespace, name, sourceFile, content, dependencyPaths, contextHash } = params;
826
849
  const cacheKey = buildCacheKey(kind, name, namespace);
827
850
  const allDeps = dependencyPaths.includes(sourceFile) ? dependencyPaths : [sourceFile, ...dependencyPaths];
828
- const inputHash = combineHash(hashFiles(allDeps), contextHash);
851
+ let inputHash;
852
+ try {
853
+ inputHash = combineHash(hashFiles(allDeps), contextHash);
854
+ } catch {
855
+ return;
856
+ }
829
857
  const contentHash = hashContent(content);
830
858
  store.storeBundleContent(cacheKey, content);
831
859
  store.setEntry(cacheKey, {
@@ -2046,7 +2074,7 @@ function transformStartCalls(source, startContext, currentFilePath) {
2046
2074
  return needsNormalizerHelper && authNamespace ? buildNormalizerHelperSource(authNamespace) + transformed : transformed;
2047
2075
  }
2048
2076
  function createStartTransformPlugin(startContext) {
2049
- if (!startContext) return void 0;
2077
+ if (!startContext || startContext.modules.size === 0) return void 0;
2050
2078
  return {
2051
2079
  name: "start-transform",
2052
2080
  transform: {
@@ -2059,6 +2087,50 @@ function createStartTransformPlugin(startContext) {
2059
2087
  };
2060
2088
  }
2061
2089
 
2090
+ //#endregion
2091
+ //#region src/cli/shared/bundle-log.ts
2092
+ const ESCALATED_LOG_CODE = "UNRESOLVED_IMPORT";
2093
+ /**
2094
+ * Collect unresolved imports while keeping every other rolldown log suppressed.
2095
+ * @param options - Context used to explain which tsconfig was in effect
2096
+ * @returns Rolldown options and a post-build assertion
2097
+ */
2098
+ function createBundleLog(options = {}) {
2099
+ const unresolvedImports = /* @__PURE__ */ new Map();
2100
+ return {
2101
+ options: {
2102
+ logLevel: "warn",
2103
+ onLog: (_level, log) => {
2104
+ if (log.code !== ESCALATED_LOG_CODE) return;
2105
+ unresolvedImports.set(JSON.stringify([log.exporter, log.id]), log);
2106
+ }
2107
+ },
2108
+ assertAllResolved() {
2109
+ if (unresolvedImports.size > 0) throw unresolvedImportError([...unresolvedImports.values()], options.tsconfig);
2110
+ }
2111
+ };
2112
+ }
2113
+ function unresolvedImportError(logs, tsconfig) {
2114
+ const imports = logs.map(formatUnresolvedImport);
2115
+ return createCLIError({
2116
+ code: "UNRESOLVED_IMPORT",
2117
+ message: imports.length === 1 ? `Could not resolve ${imports[0]}.` : `Could not resolve ${imports.length} imports.`,
2118
+ details: imports.length === 1 ? void 0 : imports.map((item) => `- ${item}`).join("\n"),
2119
+ suggestion: unresolvedImportSuggestion(logs, tsconfig)
2120
+ });
2121
+ }
2122
+ function unresolvedImportSuggestion(logs, tsconfig) {
2123
+ const nodeSuggestions = logs.map((log) => log.exporter).filter((specifier) => specifier !== void 0).filter(isNodeBuiltinImport).map(getNodeBuiltinMessage);
2124
+ const hasOtherImports = logs.some((log) => log.exporter === void 0 || !isNodeBuiltinImport(log.exporter));
2125
+ const pathSuggestion = tsconfig ? `Check that each import path is correct, and that a \`compilerOptions.paths\` entry covering it is declared in the importing file's own tsconfig.json or an ancestor. The build used "${tsconfig}".` : "No tsconfig.json was found, so `compilerOptions.paths` aliases were not applied. Add a tsconfig.json declaring the aliases these files import.";
2126
+ return [.../* @__PURE__ */ new Set([...nodeSuggestions, ...hasOtherImports ? [pathSuggestion] : []])].join("\n");
2127
+ }
2128
+ function formatUnresolvedImport(log) {
2129
+ const specifier = log.exporter ?? "an imported module";
2130
+ const importerId = log.id?.startsWith("\0") ? `a generated entry (${log.id.slice(1)})` : log.id && `"${log.id}"`;
2131
+ return `"${specifier}"${importerId ? ` imported from ${importerId}` : ""}`;
2132
+ }
2133
+
2062
2134
  //#endregion
2063
2135
  //#region src/cli/shared/bundle-log-level.ts
2064
2136
  const INFO_LEVEL_CONSOLE_METHODS = [
@@ -2163,6 +2235,13 @@ const platformBundleDefinePlugin = {
2163
2235
  transform(code) {
2164
2236
  if (!code.includes("process.env.__TAILOR_PLATFORM_BUNDLE")) return null;
2165
2237
  return { code: code.replace(GATE, "true") };
2238
+ },
2239
+ resolveId(source) {
2240
+ if (source === "node:async_hooks") return {
2241
+ id: source,
2242
+ external: true
2243
+ };
2244
+ return null;
2166
2245
  }
2167
2246
  };
2168
2247
 
@@ -2193,6 +2272,83 @@ async function tryResolve(dir) {
2193
2272
  }
2194
2273
  }
2195
2274
 
2275
+ //#endregion
2276
+ //#region src/cli/shared/tsconfig-paths-plugin.ts
2277
+ /**
2278
+ * Create a {@link TsconfigLookupCache} to share across every bundle in a CLI run.
2279
+ * @returns A fresh, empty lookup cache
2280
+ */
2281
+ function createTsconfigLookupCache() {
2282
+ return {
2283
+ tsconfigCache: /* @__PURE__ */ new Map(),
2284
+ contextCache: /* @__PURE__ */ new Map()
2285
+ };
2286
+ }
2287
+ /**
2288
+ * Create the rolldown plugin that falls back to tsconfig `paths` aliases from
2289
+ * the importing file's own nearest tsconfig.
2290
+ * @param options - Resolution context for bundlers whose entry inlines user code
2291
+ * @returns Rolldown plugin to add to a bundler's plugin list
2292
+ */
2293
+ function createTsconfigPathsPlugin(options = {}) {
2294
+ const { tsconfigCache, contextCache } = options.cache ?? createTsconfigLookupCache();
2295
+ return {
2296
+ name: "tailor-tsconfig-paths",
2297
+ resolveId: {
2298
+ order: "post",
2299
+ async handler(source, importer) {
2300
+ if (!importer) return null;
2301
+ if (source.startsWith(".") || source.startsWith("/") || source.startsWith("\0")) return null;
2302
+ const resolutionBasis = importer.startsWith("\0") ? options.virtualEntrySourceFile : importer;
2303
+ if (!resolutionBasis) return null;
2304
+ const resolution = getResolutionContext(path.dirname(resolutionBasis), tsconfigCache, contextCache, options.onTsconfigRead);
2305
+ if (!resolution) return null;
2306
+ const candidates = resolution.matcher(source);
2307
+ if (candidates.length === 0) return null;
2308
+ if (await this.resolve(source, importer, { skipSelf: true })) return null;
2309
+ for (const candidate of candidates) {
2310
+ const resolved = await this.resolve(candidate, importer, { skipSelf: true });
2311
+ if (resolved) return resolved;
2312
+ }
2313
+ return null;
2314
+ }
2315
+ }
2316
+ };
2317
+ }
2318
+ function getResolutionContext(startDir, tsconfigCache, contextCache, onTsconfigRead) {
2319
+ const cached = contextCache.get(startDir);
2320
+ if (cached !== void 0) {
2321
+ reportTsconfigDependencies(tsconfigCache, onTsconfigRead);
2322
+ return cached;
2323
+ }
2324
+ const tsconfig = getTsconfig(startDir, "tsconfig.json", tsconfigCache);
2325
+ reportTsconfigDependencies(tsconfigCache, onTsconfigRead);
2326
+ const paths = tsconfig?.config.compilerOptions?.paths;
2327
+ const matcher = paths && Object.keys(paths).length > 0 ? createPathsMatcher(tsconfig) : null;
2328
+ const resolution = matcher ? { matcher } : null;
2329
+ contextCache.set(startDir, resolution);
2330
+ return resolution;
2331
+ }
2332
+ function reportTsconfigDependencies(cache, onTsconfigRead) {
2333
+ if (!onTsconfigRead) return;
2334
+ const directories = /* @__PURE__ */ new Set();
2335
+ const dependencies = /* @__PURE__ */ new Set();
2336
+ for (const [key, value] of cache) {
2337
+ const dependencyPath = dependencyPathFromCacheKey(key);
2338
+ if (!dependencyPath) continue;
2339
+ if (key.startsWith("statSync:") && isDirectoryStat(value)) directories.add(dependencyPath);
2340
+ else dependencies.add(dependencyPath);
2341
+ }
2342
+ for (const dependencyPath of dependencies) if (!directories.has(dependencyPath)) onTsconfigRead(dependencyPath);
2343
+ }
2344
+ function dependencyPathFromCacheKey(key) {
2345
+ if (key.startsWith("readFileSync:") && key.endsWith(":utf8")) return key.slice(13, -5);
2346
+ for (const prefix of ["existsSync:", "statSync:"]) if (key.startsWith(prefix)) return key.slice(prefix.length);
2347
+ }
2348
+ function isDirectoryStat(value) {
2349
+ return typeof value === "object" && value !== null && "isDirectory" in value && typeof value.isDirectory === "function" && value.isDirectory();
2350
+ }
2351
+
2196
2352
  //#endregion
2197
2353
  //#region src/cli/shared/virtual-entry.ts
2198
2354
  /**
@@ -2200,17 +2356,20 @@ async function tryResolve(dir) {
2200
2356
  * @param name - Logical entry name
2201
2357
  * @param code - Entry module source
2202
2358
  * @param sourceType - Parser type for the generated module
2359
+ * @param resolutionBasis - Source file whose directory resolves generated imports
2203
2360
  * @returns Rolldown input and plugin for loading the entry
2204
2361
  */
2205
- function createVirtualEntry(name, code, sourceType = "js") {
2362
+ function createVirtualEntry(name, code, sourceType = "js", resolutionBasis) {
2206
2363
  const input = `tailor-entry:${name}.${sourceType}`;
2207
2364
  const resolvedId = `\0${input}`;
2208
2365
  return {
2209
2366
  input,
2210
2367
  plugin: {
2211
2368
  name: "tailor-virtual-entry",
2212
- resolveId(source, importer) {
2213
- return source === input && importer === void 0 ? resolvedId : null;
2369
+ async resolveId(source, importer) {
2370
+ if (source === input && importer === void 0) return resolvedId;
2371
+ if (importer !== resolvedId || !resolutionBasis || source.startsWith(".") || path.isAbsolute(source) || source.startsWith("\0")) return null;
2372
+ return this.resolve(source, resolutionBasis, { skipSelf: true });
2214
2373
  },
2215
2374
  load(id) {
2216
2375
  return id === resolvedId ? code : null;
@@ -2218,6 +2377,27 @@ function createVirtualEntry(name, code, sourceType = "js") {
2218
2377
  }
2219
2378
  };
2220
2379
  }
2380
+ /**
2381
+ * Resolve bare imports in a generated on-disk entry from its owning project.
2382
+ *
2383
+ * Generated entries live under the CLI output directory, which may be outside
2384
+ * the project selected by a config path. Resolving their injected dependencies
2385
+ * from that output directory would ignore the selected project's installation.
2386
+ * @param entryPath - Absolute path of the generated entry
2387
+ * @param projectDir - Directory whose dependencies the generated entry uses
2388
+ * @returns Rolldown plugin that rebases generated bare imports
2389
+ */
2390
+ function createGeneratedEntryResolverPlugin(entryPath, projectDir) {
2391
+ const normalizedEntryPath = path.resolve(entryPath);
2392
+ const resolutionBasis = path.join(path.resolve(projectDir), "__tailor_sdk_generated_entry__.js");
2393
+ return {
2394
+ name: "tailor-generated-entry-resolver",
2395
+ async resolveId(source, importer) {
2396
+ if (importer === void 0 || path.resolve(importer) !== normalizedEntryPath || source.startsWith(".") || path.isAbsolute(source) || source.startsWith("\0")) return null;
2397
+ return this.resolve(source, resolutionBasis, { skipSelf: true });
2398
+ }
2399
+ };
2400
+ }
2221
2401
 
2222
2402
  //#endregion
2223
2403
  //#region src/cli/services/auth/bundler.ts
@@ -2231,7 +2411,7 @@ function createVirtualEntry(name, code, sourceType = "js") {
2231
2411
  * @returns Map of function name to bundled code
2232
2412
  */
2233
2413
  async function bundleAuthHooks(options) {
2234
- const { configPath, authName, handlerAccessPath, env = {}, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", baseDir } = options;
2414
+ const { configPath, authName, handlerAccessPath, env = {}, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", baseDir, tsconfigCache } = options;
2235
2415
  logger.newline();
2236
2416
  logger.log(`Bundling auth hook for ${styles.info(`"${authName}"`)}`);
2237
2417
  const absoluteConfigPath = path.resolve(configPath);
@@ -2250,7 +2430,7 @@ async function bundleAuthHooks(options) {
2250
2430
  bundleLogLevel,
2251
2431
  prefix: JSON.stringify(Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))))
2252
2432
  }),
2253
- async build(cachePlugins) {
2433
+ async build(cachePlugins, trackDependency) {
2254
2434
  const entryContent = multiline`
2255
2435
  import _config from "${absoluteConfigPath}";
2256
2436
  const __auth_hook_function = _config.${handlerAccessPath};
@@ -2259,12 +2439,16 @@ async function bundleAuthHooks(options) {
2259
2439
  return await __auth_hook_function({ ...args, env });
2260
2440
  }
2261
2441
  `;
2262
- const entry = createVirtualEntry(`auth-hook:${functionName}`, entryContent);
2442
+ const entry = createVirtualEntry(`auth-hook:${functionName}`, entryContent, "js", absoluteConfigPath);
2263
2443
  const startPlugin = createStartTransformPlugin(startContext);
2264
2444
  const plugins = [entry.plugin];
2265
2445
  if (startPlugin) plugins.push(startPlugin);
2266
- plugins.push(platformBundleDefinePlugin, ...cachePlugins);
2267
- return (await rolldown.build({
2446
+ plugins.push(createTsconfigPathsPlugin({
2447
+ onTsconfigRead: trackDependency,
2448
+ cache: tsconfigCache
2449
+ }), platformBundleDefinePlugin, ...cachePlugins);
2450
+ const bundleLog = createBundleLog({ tsconfig });
2451
+ const result = await rolldown.build({
2268
2452
  input: entry.input,
2269
2453
  write: false,
2270
2454
  output: {
@@ -2277,8 +2461,10 @@ async function bundleAuthHooks(options) {
2277
2461
  plugins,
2278
2462
  transform: { define: { "process.env.TAILOR_APP_LOG_LEVEL": JSON.stringify(bundleLogLevel) } },
2279
2463
  treeshake: composeFunctionTreeshakeOptions([createLogLevelTreeshakeOptions(bundleLogLevel)]),
2280
- logLevel: "silent"
2281
- })).output[0].code;
2464
+ ...bundleLog.options
2465
+ });
2466
+ bundleLog.assertAllResolved();
2467
+ return result.output[0].code;
2282
2468
  }
2283
2469
  });
2284
2470
  logger.log(`${styles.success("Bundled")} auth hook for ${styles.info(`"${authName}"`)}`);
@@ -3208,9 +3394,14 @@ async function bundleScriptTarget(args) {
3208
3394
  if (unresolved.length > 0) throw new Error(`${context} captures unresolvable variables (${unresolved.join(", ")}). Hooks and validators must not reference variables that cannot be resolved from the source file.
3209
3395
  ${kind}: ${fnSource}`);
3210
3396
  const entryContent = buildMinimalEntryFromResolved(imports, declarations, fnSource, sourceFilePath, kind === "typeValidate");
3211
- const entry = createVirtualEntry(`tailordb-script:${typeName}:${targetIndex}`, entryContent, "ts");
3212
- const bundledCode = (await rolldown.build({
3213
- plugins: [entry.plugin, platformBundleDefinePlugin],
3397
+ const entry = createVirtualEntry(`tailordb-script:${typeName}:${targetIndex}`, entryContent, "ts", sourceFilePath);
3398
+ const bundleLog = createBundleLog({ tsconfig });
3399
+ const buildResult = await rolldown.build({
3400
+ plugins: [
3401
+ entry.plugin,
3402
+ createTsconfigPathsPlugin({ virtualEntrySourceFile: sourceFilePath }),
3403
+ platformBundleDefinePlugin
3404
+ ],
3214
3405
  input: entry.input,
3215
3406
  write: false,
3216
3407
  output: {
@@ -3225,8 +3416,10 @@ async function bundleScriptTarget(args) {
3225
3416
  annotations: true,
3226
3417
  unknownGlobalSideEffects: false
3227
3418
  },
3228
- logLevel: "silent"
3229
- })).output[0].code;
3419
+ ...bundleLog.options
3420
+ });
3421
+ bundleLog.assertAllResolved();
3422
+ const bundledCode = buildResult.output[0].code;
3230
3423
  return assertParsableExpression(buildPrecompiledExpr(bundledCode, argsObject), context);
3231
3424
  }
3232
3425
  /**
@@ -3743,6 +3936,8 @@ function buildExecutorArgsExpr(triggerKind, env) {
3743
3936
  case "schedule": return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;
3744
3937
  case "resolverExecuted": return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, success: !!args.succeeded, result: args.succeeded?.result.resolver, error: args.failed?.error, ${envExpr} })`;
3745
3938
  case "incomingWebhook": return `({ ...args, appNamespace: args.namespaceName, rawBody: args.raw_body, ${envExpr} })`;
3939
+ case "workflowExecution":
3940
+ case "workflowJobExecution": return `({ ...args, event: args.eventType?.split(".").pop(), rawEvent: args.eventType, ${ACTOR_TRANSFORM_EXPR}, ...(args.succeeded ? { success: true } : args.failed ? { success: false, error: args.failed.error ?? "" } : {}), ${envExpr} })`;
3746
3941
  default: return `({ ...args, event: args.eventType?.split(".").pop(), rawEvent: args.eventType, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;
3747
3942
  }
3748
3943
  }
@@ -3880,7 +4075,7 @@ function buildResolverPermissionAndInputCheckExpr(permission) {
3880
4075
  */
3881
4076
  async function bundleExecutors(options) {
3882
4077
  const bundledCode = /* @__PURE__ */ new Map();
3883
- const { config, startContext, additionalFiles = [], cache, inlineSourcemap, bundleLogLevel = "DEBUG", baseDir } = options;
4078
+ const { config, startContext, additionalFiles = [], cache, inlineSourcemap, bundleLogLevel = "DEBUG", baseDir, tsconfigCache } = options;
3884
4079
  const files = [...loadFilesWithIgnores(config, baseDir), ...additionalFiles];
3885
4080
  if (files.length === 0) {
3886
4081
  logger.warn(`No executor files found for patterns: ${config.files.join(", ")}`);
@@ -3909,12 +4104,12 @@ async function bundleExecutors(options) {
3909
4104
  return bundledCode;
3910
4105
  }
3911
4106
  const tsconfig = await resolveTSConfigWithFallback(baseDir);
3912
- const results = await withBundleConcurrency(executors, (executor) => bundleSingleExecutor(executor, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel));
4107
+ const results = await withBundleConcurrency(executors, (executor) => bundleSingleExecutor(executor, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel, tsconfigCache));
3913
4108
  for (const [name, code] of results) bundledCode.set(name, code);
3914
4109
  logger.log(`${styles.success("Bundled")} ${styles.info("\"executor\"")}`);
3915
4110
  return bundledCode;
3916
4111
  }
3917
- async function bundleSingleExecutor(executor, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG") {
4112
+ async function bundleSingleExecutor(executor, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", tsconfigCache) {
3918
4113
  const serializedStartContext = serializeStartContext(startContext);
3919
4114
  const contextHash = computeBundlerContextHash({
3920
4115
  sourceFile: executor.sourceFile,
@@ -3929,9 +4124,10 @@ async function bundleSingleExecutor(executor, tsconfig, startContext, cache, inl
3929
4124
  name: executor.name,
3930
4125
  sourceFile: executor.sourceFile,
3931
4126
  contextHash,
3932
- async build(cachePlugins) {
4127
+ async build(cachePlugins, trackDependency) {
4128
+ const absoluteSourcePath = path.resolve(executor.sourceFile);
3933
4129
  const entryContent = multiline`
3934
- import _internalExecutor from "${path.resolve(executor.sourceFile)}";
4130
+ import _internalExecutor from "${absoluteSourcePath}";
3935
4131
 
3936
4132
  const __executor_function = async (args) => {
3937
4133
  const invoker = ${INVOKER_EXPR};
@@ -3940,12 +4136,16 @@ async function bundleSingleExecutor(executor, tsconfig, startContext, cache, inl
3940
4136
 
3941
4137
  export { __executor_function as main };
3942
4138
  `;
3943
- const entry = createVirtualEntry(`executor:${executor.name}`, entryContent);
4139
+ const entry = createVirtualEntry(`executor:${executor.name}`, entryContent, "js", absoluteSourcePath);
3944
4140
  const startPlugin = createStartTransformPlugin(startContext);
3945
4141
  const plugins = [entry.plugin];
3946
4142
  if (startPlugin) plugins.push(startPlugin);
3947
- plugins.push(platformBundleDefinePlugin, ...cachePlugins);
3948
- return (await rolldown.build({
4143
+ plugins.push(createTsconfigPathsPlugin({
4144
+ onTsconfigRead: trackDependency,
4145
+ cache: tsconfigCache
4146
+ }), platformBundleDefinePlugin, ...cachePlugins);
4147
+ const bundleLog = createBundleLog({ tsconfig });
4148
+ const result = await rolldown.build({
3949
4149
  input: entry.input,
3950
4150
  write: false,
3951
4151
  output: {
@@ -3957,22 +4157,15 @@ async function bundleSingleExecutor(executor, tsconfig, startContext, cache, inl
3957
4157
  tsconfig,
3958
4158
  plugins,
3959
4159
  treeshake: composeFunctionTreeshakeOptions([createLogLevelTreeshakeOptions(bundleLogLevel)]),
3960
- logLevel: "silent"
3961
- })).output[0].code;
4160
+ ...bundleLog.options
4161
+ });
4162
+ bundleLog.assertAllResolved();
4163
+ return result.output[0].code;
3962
4164
  }
3963
4165
  });
3964
4166
  return [executor.name, code];
3965
4167
  }
3966
4168
 
3967
- //#endregion
3968
- //#region src/cli/services/http-adapter/node-builtins.ts
3969
- const NODE_BUILTINS = new Set(builtinModules.filter((m) => !m.startsWith("_")));
3970
- function isNodeBuiltinImport(source) {
3971
- if (source.startsWith("node:")) return true;
3972
- const root = source.includes("/") ? source.slice(0, source.indexOf("/")) : source;
3973
- return NODE_BUILTINS.has(root);
3974
- }
3975
-
3976
4169
  //#endregion
3977
4170
  //#region src/parser/service/http-adapter/methods.ts
3978
4171
  /**
@@ -4021,9 +4214,10 @@ const GRAPHQL_WEB_MODULE = createRequire(import.meta.url).resolve("@0no-co/graph
4021
4214
  * @param baseDir - Directory the owning config's tsconfig is resolved against
4022
4215
  * @param cache - Optional bundle cache for skipping unchanged builds
4023
4216
  * @param bundleLogLevel - Controls which console calls are kept in bundled code
4217
+ * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run
4024
4218
  * @returns Bundled scripts keyed by adapter name
4025
4219
  */
4026
- async function bundleHttpAdapters(adapters, baseDir, cache, bundleLogLevel = "DEBUG") {
4220
+ async function bundleHttpAdapters(adapters, baseDir, cache, bundleLogLevel = "DEBUG", tsconfigCache) {
4027
4221
  if (adapters.length === 0) return {
4028
4222
  bundledInputs: /* @__PURE__ */ new Map(),
4029
4223
  bundledOutputs: /* @__PURE__ */ new Map()
@@ -4036,7 +4230,7 @@ async function bundleHttpAdapters(adapters, baseDir, cache, bundleLogLevel = "DE
4036
4230
  adapter,
4037
4231
  kind
4038
4232
  }));
4039
- }), ({ adapter, kind }) => bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel));
4233
+ }), ({ adapter, kind }) => bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel, tsconfigCache));
4040
4234
  const bundledInputs = /* @__PURE__ */ new Map();
4041
4235
  const bundledOutputs = /* @__PURE__ */ new Map();
4042
4236
  for (const [name, kind, code] of results) if (kind === "input") bundledInputs.set(name, code);
@@ -4047,7 +4241,7 @@ async function bundleHttpAdapters(adapters, baseDir, cache, bundleLogLevel = "DE
4047
4241
  bundledOutputs
4048
4242
  };
4049
4243
  }
4050
- async function bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel = "DEBUG") {
4244
+ async function bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel = "DEBUG", tsconfigCache) {
4051
4245
  const contextHash = computeBundlerContextHash({
4052
4246
  sourceFile: adapter.sourceFile,
4053
4247
  extraContext: kind === "input" ? adapter.methods.join(",") : "",
@@ -4062,16 +4256,16 @@ async function bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLeve
4062
4256
  name: adapter.name,
4063
4257
  sourceFile: adapter.sourceFile,
4064
4258
  contextHash,
4065
- async build(cachePlugins) {
4259
+ async build(cachePlugins, trackDependency) {
4066
4260
  const absoluteSourcePath = path.resolve(adapter.sourceFile);
4067
4261
  const entryContent = kind === "input" ? buildInputEntry(absoluteSourcePath, adapter.methods, GRAPHQL_WEB_MODULE) : buildOutputEntry(absoluteSourcePath);
4068
- const entry = createVirtualEntry(`http-adapter:${adapter.name}:${kind}`, entryContent);
4262
+ const entry = createVirtualEntry(`http-adapter:${adapter.name}:${kind}`, entryContent, "js", absoluteSourcePath);
4069
4263
  const plugins = [
4070
4264
  entry.plugin,
4071
4265
  {
4072
4266
  name: "http-adapter-reject-node-imports",
4073
4267
  resolveId(source) {
4074
- if (isNodeBuiltinImport(source)) throw new Error(`HTTP adapter "${adapter.name}" imports Node module "${source}", which is unavailable in the gateway runtime`);
4268
+ if (isNodeBuiltinImport(source)) throw new Error(`HTTP adapter "${adapter.name}": ${getNodeBuiltinMessage(source)}`);
4075
4269
  return null;
4076
4270
  }
4077
4271
  },
@@ -4089,9 +4283,14 @@ async function bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLeve
4089
4283
  return null;
4090
4284
  }
4091
4285
  },
4286
+ createTsconfigPathsPlugin({
4287
+ onTsconfigRead: trackDependency,
4288
+ cache: tsconfigCache
4289
+ }),
4092
4290
  ...cachePlugins
4093
4291
  ];
4094
- const bundled = (await rolldown.build({
4292
+ const bundleLog = createBundleLog({ tsconfig });
4293
+ const result = await rolldown.build({
4095
4294
  input: entry.input,
4096
4295
  write: false,
4097
4296
  output: {
@@ -4104,8 +4303,10 @@ async function bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLeve
4104
4303
  plugins,
4105
4304
  transform: { target: "es2017" },
4106
4305
  treeshake: composeFunctionTreeshakeOptions([createLogLevelTreeshakeOptions(bundleLogLevel)]),
4107
- logLevel: "silent"
4108
- })).output[0].code;
4306
+ ...bundleLog.options
4307
+ });
4308
+ bundleLog.assertAllResolved();
4309
+ const bundled = result.output[0].code;
4109
4310
  const byteLength = Buffer.byteLength(bundled, "utf8");
4110
4311
  if (byteLength > ADAPTER_BUNDLE_ERROR_BYTES) throw new Error(`HTTP adapter "${adapter.name}" ${kind} script is ${byteLength} bytes, exceeding the ${ADAPTER_BUNDLE_ERROR_BYTES} byte limit`);
4111
4312
  if (byteLength > ADAPTER_BUNDLE_WARN_BYTES) logger.warn(`HTTP adapter "${adapter.name}" ${kind} script is ${byteLength} bytes, larger than the recommended ${ADAPTER_BUNDLE_WARN_BYTES} byte limit`);
@@ -4350,9 +4551,10 @@ async function loadResolver(resolverFilePath) {
4350
4551
  * @param cache - Optional bundle cache for skipping unchanged builds
4351
4552
  * @param inlineSourcemap - Whether to enable inline sourcemaps
4352
4553
  * @param bundleLogLevel - Controls which console calls are kept in bundled code
4554
+ * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run
4353
4555
  * @returns Map of resolver name to bundled code
4354
4556
  */
4355
- async function bundleResolvers(namespace, config, baseDir, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG") {
4557
+ async function bundleResolvers(namespace, config, baseDir, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", tsconfigCache) {
4356
4558
  const bundledCode = /* @__PURE__ */ new Map();
4357
4559
  const files = loadFilesWithIgnores(config, baseDir);
4358
4560
  if (files.length === 0) {
@@ -4375,12 +4577,12 @@ async function bundleResolvers(namespace, config, baseDir, startContext, cache,
4375
4577
  });
4376
4578
  }
4377
4579
  const tsconfig = await resolveTSConfigWithFallback(baseDir);
4378
- const results = await withBundleConcurrency(resolvers, (resolver) => bundleSingleResolver(namespace, resolver, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel));
4580
+ const results = await withBundleConcurrency(resolvers, (resolver) => bundleSingleResolver(namespace, resolver, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel, tsconfigCache));
4379
4581
  for (const [name, code] of results) bundledCode.set(name, code);
4380
4582
  logger.log(`${styles.success("Bundled")} ${styles.info(`"${namespace}"`)}`);
4381
4583
  return bundledCode;
4382
4584
  }
4383
- async function bundleSingleResolver(namespace, resolver, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG") {
4585
+ async function bundleSingleResolver(namespace, resolver, tsconfig, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", tsconfigCache) {
4384
4586
  const serializedStartContext = serializeStartContext(startContext);
4385
4587
  const contextHash = computeBundlerContextHash({
4386
4588
  sourceFile: resolver.sourceFile,
@@ -4396,9 +4598,10 @@ async function bundleSingleResolver(namespace, resolver, tsconfig, startContext,
4396
4598
  name: resolver.name,
4397
4599
  sourceFile: resolver.sourceFile,
4398
4600
  contextHash,
4399
- async build(cachePlugins) {
4601
+ async build(cachePlugins, trackDependency) {
4602
+ const absoluteSourcePath = path.resolve(resolver.sourceFile);
4400
4603
  const entryContent = multiline`
4401
- import _internalResolver from "${path.resolve(resolver.sourceFile)}";
4604
+ import _internalResolver from "${absoluteSourcePath}";
4402
4605
  import { t } from "@tailor-platform/sdk";
4403
4606
 
4404
4607
  const $tailor_resolver_body = async (context) => {
@@ -4409,12 +4612,16 @@ async function bundleSingleResolver(namespace, resolver, tsconfig, startContext,
4409
4612
 
4410
4613
  export { $tailor_resolver_body as main };
4411
4614
  `;
4412
- const entry = createVirtualEntry(`resolver:${resolver.name}`, entryContent);
4615
+ const entry = createVirtualEntry(`resolver:${resolver.name}`, entryContent, "js", absoluteSourcePath);
4413
4616
  const startPlugin = createStartTransformPlugin(startContext);
4414
4617
  const plugins = [entry.plugin];
4415
4618
  if (startPlugin) plugins.push(startPlugin);
4416
- plugins.push(platformBundleDefinePlugin, ...cachePlugins);
4417
- return (await rolldown.build({
4619
+ plugins.push(createTsconfigPathsPlugin({
4620
+ onTsconfigRead: trackDependency,
4621
+ cache: tsconfigCache
4622
+ }), platformBundleDefinePlugin, ...cachePlugins);
4623
+ const bundleLog = createBundleLog({ tsconfig });
4624
+ const result = await rolldown.build({
4418
4625
  input: entry.input,
4419
4626
  write: false,
4420
4627
  output: {
@@ -4426,8 +4633,10 @@ async function bundleSingleResolver(namespace, resolver, tsconfig, startContext,
4426
4633
  tsconfig,
4427
4634
  plugins,
4428
4635
  treeshake: composeFunctionTreeshakeOptions([createLogLevelTreeshakeOptions(bundleLogLevel)]),
4429
- logLevel: "silent"
4430
- })).output[0].code;
4636
+ ...bundleLog.options
4637
+ });
4638
+ bundleLog.assertAllResolved();
4639
+ return result.output[0].code;
4431
4640
  }
4432
4641
  });
4433
4642
  return [resolver.name, code];
@@ -4627,9 +4836,10 @@ function safeRealpath(p) {
4627
4836
  * @param cache - Optional bundle cache for skipping unchanged builds
4628
4837
  * @param inlineSourcemap - Whether to enable inline sourcemaps
4629
4838
  * @param bundleLogLevel - Controls which console calls are kept in bundled code
4839
+ * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run
4630
4840
  * @returns Workflow job bundling result
4631
4841
  */
4632
- async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, startContext, baseDir, cache, inlineSourcemap, bundleLogLevel = "DEBUG") {
4842
+ async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, startContext, baseDir, cache, inlineSourcemap, bundleLogLevel = "DEBUG", tsconfigCache) {
4633
4843
  if (allJobs.length === 0) {
4634
4844
  logger.warn("No workflow jobs to bundle");
4635
4845
  return {
@@ -4642,7 +4852,7 @@ async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, startContext,
4642
4852
  logger.newline();
4643
4853
  logger.log(`Bundling ${styles.highlight(usedJobs.length.toString())} files for ${styles.info("\"workflow-job\"")}`);
4644
4854
  const tsconfig = await resolveTSConfigWithFallback(baseDir);
4645
- const results = await withBundleConcurrency(usedJobs, (job) => bundleSingleJob(job, usedJobs, tsconfig, env, startContext, cache, inlineSourcemap, bundleLogLevel));
4855
+ const results = await withBundleConcurrency(usedJobs, (job) => bundleSingleJob(job, usedJobs, tsconfig, env, startContext, cache, inlineSourcemap, bundleLogLevel, tsconfigCache));
4646
4856
  const bundledCode = /* @__PURE__ */ new Map();
4647
4857
  for (const [name, code] of results) bundledCode.set(name, code);
4648
4858
  logger.log(`${styles.success("Bundled")} ${styles.info("\"workflow-job\"")}`);
@@ -4718,7 +4928,7 @@ async function filterUsedJobs(allJobs, mainJobNames, startContext) {
4718
4928
  mainJobDeps
4719
4929
  };
4720
4930
  }
4721
- async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG") {
4931
+ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache, inlineSourcemap, bundleLogLevel = "DEBUG", tsconfigCache) {
4722
4932
  const serializedStartContext = serializeStartContext(startContext);
4723
4933
  const sortedEnvPrefix = JSON.stringify(Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))));
4724
4934
  const contextHash = computeBundlerContextHash({
@@ -4735,7 +4945,7 @@ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache,
4735
4945
  name: job.name,
4736
4946
  sourceFile: job.sourceFile,
4737
4947
  contextHash,
4738
- async build(cachePlugins) {
4948
+ async build(cachePlugins, trackDependency) {
4739
4949
  const absoluteSourcePath = path.resolve(job.sourceFile);
4740
4950
  const entryContent = multiline`
4741
4951
  import { ${job.exportName} } from "${absoluteSourcePath}";
@@ -4746,7 +4956,7 @@ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache,
4746
4956
  return await ${job.exportName}.body(input, { env, invoker });
4747
4957
  }
4748
4958
  `;
4749
- const entry = createVirtualEntry(`workflow-job:${job.name}`, entryContent);
4959
+ const entry = createVirtualEntry(`workflow-job:${job.name}`, entryContent, "js", absoluteSourcePath);
4750
4960
  const resolvedSourceFile = safeRealpath(job.sourceFile);
4751
4961
  const otherJobExportNames = allJobs.filter((candidate) => candidate.name !== job.name && safeRealpath(candidate.sourceFile) === resolvedSourceFile).map((j) => j.exportName);
4752
4962
  const plugins = [
@@ -4765,10 +4975,15 @@ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache,
4765
4975
  }
4766
4976
  }
4767
4977
  },
4978
+ createTsconfigPathsPlugin({
4979
+ onTsconfigRead: trackDependency,
4980
+ cache: tsconfigCache
4981
+ }),
4768
4982
  platformBundleDefinePlugin,
4769
4983
  ...cachePlugins
4770
4984
  ];
4771
- return (await rolldown.build({
4985
+ const bundleLog = createBundleLog({ tsconfig });
4986
+ const result = await rolldown.build({
4772
4987
  input: entry.input,
4773
4988
  write: false,
4774
4989
  output: {
@@ -4780,8 +4995,10 @@ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache,
4780
4995
  tsconfig,
4781
4996
  plugins,
4782
4997
  treeshake: composeFunctionTreeshakeOptions([createLogLevelTreeshakeOptions(bundleLogLevel)]),
4783
- logLevel: "silent"
4784
- })).output[0].code;
4998
+ ...bundleLog.options
4999
+ });
5000
+ bundleLog.assertAllResolved();
5001
+ return result.output[0].code;
4785
5002
  }
4786
5003
  });
4787
5004
  return [job.name, code];
@@ -4792,7 +5009,8 @@ async function bundleSingleJob(job, allJobs, tsconfig, env, startContext, cache,
4792
5009
  const WorkflowJobSchema = z.strictObject({
4793
5010
  name: z.string().describe("Job name (must be unique across the project)"),
4794
5011
  start: functionSchema.describe("Start function that initiates the job"),
4795
- body: functionSchema.describe("Job implementation function")
5012
+ body: functionSchema.describe("Job implementation function"),
5013
+ publishEvents: z.boolean().optional().describe("Enable publishing job execution events for this job")
4796
5014
  });
4797
5015
  const durationUnits = [
4798
5016
  "ms",
@@ -4828,7 +5046,7 @@ const RetryPolicySchema = z.strictObject({
4828
5046
  });
4829
5047
  const ConcurrencyPolicySchema = z.strictObject({ maxConcurrentExecutions: z.number().int().min(1).max(1e3).describe("Maximum number of concurrent executions (1-1000)") });
4830
5048
  const ExecutionPolicyNameSchema = z.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/, "Invalid execution policy name: must match [a-z0-9-] (3-63 chars; must start and end with [a-z0-9])").describe("Workspace-unique execution policy name embedded in the resource TRN");
4831
- const ExecutionPolicyKeySchema = z.string().regex(/^[a-z0-9][a-z0-9_:.-]{0,62}[a-z0-9*]$/, "Invalid execution policy key: must match [a-z0-9_:.-] (2-64 chars; must start with [a-z0-9] and end with [a-z0-9] or a trailing '*')").describe("Execution policy key passed to execJobFunction's (or its alias startJobFunction's) executionPolicyKey option");
5049
+ const ExecutionPolicyKeySchema = z.string().regex(/^[a-z0-9][a-z0-9_:.-]{0,62}[a-z0-9*]$/, "Invalid execution policy key: must match [a-z0-9_:.-] (2-64 chars; must start with [a-z0-9] and end with [a-z0-9] or a trailing '*')").describe("Execution policy key passed to execJobFunction's executionPolicyKey option");
4832
5050
  const WorkflowJobFunctionExecutionPolicySchema = z.strictObject({
4833
5051
  name: ExecutionPolicyNameSchema,
4834
5052
  key: ExecutionPolicyKeySchema,
@@ -4838,7 +5056,8 @@ const WorkflowSchema = z.strictObject({
4838
5056
  name: z.string().describe("Workflow name"),
4839
5057
  mainJob: WorkflowJobSchema.describe("Main job that starts the workflow"),
4840
5058
  retryPolicy: RetryPolicySchema.optional().describe("Retry policy for the workflow"),
4841
- concurrencyPolicy: ConcurrencyPolicySchema.optional().describe("Concurrency policy for the workflow")
5059
+ concurrencyPolicy: ConcurrencyPolicySchema.optional().describe("Concurrency policy for the workflow"),
5060
+ publishEvents: z.boolean().optional().describe("Enable publishing workflow execution events for this workflow")
4842
5061
  });
4843
5062
 
4844
5063
  //#endregion
@@ -4965,7 +5184,8 @@ async function loadFileContent(filePath) {
4965
5184
  if (jobResult.success) jobs.push({
4966
5185
  name: jobResult.data.name,
4967
5186
  exportName,
4968
- sourceFile: filePath
5187
+ sourceFile: filePath,
5188
+ ...jobResult.data.publishEvents !== void 0 ? { publishEvents: jobResult.data.publishEvents } : {}
4969
5189
  });
4970
5190
  else if (isSdkBranded(exportValue, ["workflow", "workflow-job"])) throw jobResult.error;
4971
5191
  }
@@ -5192,7 +5412,7 @@ const IdPSchema = z.strictObject({
5192
5412
  clients: z.array(z.string()).describe("OAuth2 client names that can use this IdP"),
5193
5413
  lang: IdPLangSchema.optional().describe("UI language for IdP pages"),
5194
5414
  userAuthPolicy: IdPUserAuthPolicySchema.transform((input) => IdPUserAuthPolicySchema.parse(input ?? {})).optional().describe("User authentication policy configuration"),
5195
- publishUserEvents: z.boolean().optional().describe("Enable publishing user lifecycle events"),
5415
+ publishEvents: z.boolean().optional().describe("Enable publishing user lifecycle events"),
5196
5416
  gqlOperations: IdPGqlOperationsSchema.optional().describe("Configure which GraphQL operations are enabled"),
5197
5417
  emailConfig: IdPEmailConfigSchema.optional().describe("Namespace-level email configuration defaults"),
5198
5418
  permission: IdPPermissionSchema.optional().describe("Per-operation permission policies for IdP users")
@@ -5523,6 +5743,7 @@ async function loadApplication(params) {
5523
5743
  }), baseDir);
5524
5744
  const inlineSourcemap = resolveInlineSourcemap(config.inlineSourcemap);
5525
5745
  const bundleLogLevel = resolveBundleLogLevel(config.logLevel);
5746
+ const tsconfigCache = createTsconfigLookupCache();
5526
5747
  const bundledScripts = {
5527
5748
  resolvers: /* @__PURE__ */ new Map(),
5528
5749
  executors: /* @__PURE__ */ new Map(),
@@ -5530,7 +5751,7 @@ async function loadApplication(params) {
5530
5751
  authHooks: /* @__PURE__ */ new Map()
5531
5752
  };
5532
5753
  for (const pipeline of resolverResult.resolverServices) {
5533
- const resolverBundles = await bundleResolvers(pipeline.namespace, pipeline.config, baseDir, startContext, bundleCache, inlineSourcemap, bundleLogLevel);
5754
+ const resolverBundles = await bundleResolvers(pipeline.namespace, pipeline.config, baseDir, startContext, bundleCache, inlineSourcemap, bundleLogLevel, tsconfigCache);
5534
5755
  for (const [name, code] of resolverBundles) bundledScripts.resolvers.set(resolverBundleKey(pipeline.namespace, name), code);
5535
5756
  }
5536
5757
  if (executorService) bundledScripts.executors = await bundleExecutors({
@@ -5540,12 +5761,13 @@ async function loadApplication(params) {
5540
5761
  cache: bundleCache,
5541
5762
  inlineSourcemap,
5542
5763
  bundleLogLevel,
5543
- baseDir
5764
+ baseDir,
5765
+ tsconfigCache
5544
5766
  });
5545
5767
  let workflowBuildResult;
5546
5768
  if (workflowService && workflowService.jobs.length > 0) {
5547
5769
  const mainJobNames = workflowService.workflowSources.map((ws) => ws.workflow.mainJob.name);
5548
- workflowBuildResult = await bundleWorkflowJobs(workflowService.jobs, mainJobNames, config.env ?? {}, startContext, baseDir, bundleCache, inlineSourcemap, bundleLogLevel);
5770
+ workflowBuildResult = await bundleWorkflowJobs(workflowService.jobs, mainJobNames, config.env ?? {}, startContext, baseDir, bundleCache, inlineSourcemap, bundleLogLevel, tsconfigCache);
5549
5771
  bundledScripts.workflowJobs = workflowBuildResult.bundledCode;
5550
5772
  }
5551
5773
  let httpAdapterBuildResult;
@@ -5554,7 +5776,7 @@ async function loadApplication(params) {
5554
5776
  sourceFile: a.sourceFile,
5555
5777
  methods: a.methods,
5556
5778
  hasOutput: a.hasOutput
5557
- })), baseDir, bundleCache, bundleLogLevel);
5779
+ })), baseDir, bundleCache, bundleLogLevel, tsconfigCache);
5558
5780
  if (authResult.authService?.config.hooks?.beforeLogin) {
5559
5781
  const authName = authResult.authService.config.name;
5560
5782
  bundledScripts.authHooks = await bundleAuthHooks({
@@ -5566,7 +5788,8 @@ async function loadApplication(params) {
5566
5788
  cache: bundleCache,
5567
5789
  inlineSourcemap,
5568
5790
  bundleLogLevel,
5569
- baseDir
5791
+ baseDir,
5792
+ tsconfigCache
5570
5793
  });
5571
5794
  }
5572
5795
  for (const pipeline of resolverResult.resolverServices) await pipeline.loadResolvers();
@@ -5600,5 +5823,5 @@ async function loadApplication(params) {
5600
5823
  }
5601
5824
 
5602
5825
  //#endregion
5603
- export { defaultPlatformBaseUrl as A, getPlatformBaseUrl as B, getPluginGenerationDependencies as C, hashContent as D, getDistDir as E, fetchPlatformMachineUserToken as F, normalizeBaseUrl as G, initOperatorClient as H, fetchUserInfo as I, byName as J, rememberPlatformConfigForToken as K, getConsoleBaseUrl as L, fetchAllTolerant as M, fetchMachineUserToken as N, hashFile as O, fetchPaged as P, getOAuth2ClientId as R, resolveBundleLogLevel as S, createBundleCache as T, isDefaultPlatform as U, initOAuth2Client as V, isNotFoundError as W, LOG_LEVELS as X, createApplyLimiter as Y, stringifyFunction as _, resolveInlineSourcemap as a, composeFunctionTreeshakeOptions as b, WorkflowJobSchema as c, INVOKER_EXPR as d, buildExecutorArgsExpr as f, assertUniqueTailorDBTypeNamesWithExternal as g, assertUniqueLocalTailorDBTypeNames as h, resolverBundleKey as i, fetchAll as j, closeConnectionPool as k, ResolverSchema as l, buildResolverPermissionAndInputCheckExpr as m, generatePluginFilesIfNeeded as n, getApplicationAuthNamespace as o, buildResolverOperationHookExpr as p, resolveStaticWebsiteUrls as q, loadApplication as r, WorkflowJobFunctionExecutionPolicySchema as s, defineApplication as t, HTTP_METHODS as u, resolveTSConfigWithFallback as v, hasGenerationHooks as w, createLogLevelTreeshakeOptions as x, platformBundleDefinePlugin as y, getOrNull as z };
5604
- //# sourceMappingURL=application-miwiXtB4.mjs.map
5826
+ export { LOG_LEVELS as $, hashContent as A, getConsoleBaseUrl as B, createLogLevelTreeshakeOptions as C, hasGenerationHooks as D, getPluginGenerationDependencies as E, fetchAllTolerant as F, initOperatorClient as G, getOrNull as H, fetchMachineUserToken as I, normalizeBaseUrl as J, isDefaultPlatform as K, fetchPaged as L, closeConnectionPool as M, defaultPlatformBaseUrl as N, createBundleCache as O, fetchAll as P, createApplyLimiter as Q, fetchPlatformMachineUserToken as R, composeFunctionTreeshakeOptions as S, createBundleLog as T, getPlatformBaseUrl as U, getOAuth2ClientId as V, initOAuth2Client as W, resolveStaticWebsiteUrls as X, rememberPlatformConfigForToken as Y, byName as Z, stringifyFunction as _, resolveInlineSourcemap as a, resolveTSConfigWithFallback as b, WorkflowJobSchema as c, INVOKER_EXPR as d, buildExecutorArgsExpr as f, assertUniqueTailorDBTypeNamesWithExternal as g, assertUniqueLocalTailorDBTypeNames as h, resolverBundleKey as i, hashFile as j, getDistDir as k, ResolverSchema as l, buildResolverPermissionAndInputCheckExpr as m, generatePluginFilesIfNeeded as n, getApplicationAuthNamespace as o, buildResolverOperationHookExpr as p, isNotFoundError as q, loadApplication as r, WorkflowJobFunctionExecutionPolicySchema as s, defineApplication as t, HTTP_METHODS as u, createGeneratedEntryResolverPlugin as v, resolveBundleLogLevel as w, platformBundleDefinePlugin as x, createTsconfigPathsPlugin as y, fetchUserInfo as z };
5827
+ //# sourceMappingURL=application-CM6hKnSK.mjs.map