@workflow/builders 5.0.0-beta.4 → 5.0.0-beta.5

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 (55) hide show
  1. package/dist/base-builder.d.ts +69 -2
  2. package/dist/base-builder.d.ts.map +1 -1
  3. package/dist/base-builder.js +368 -19
  4. package/dist/base-builder.js.map +1 -1
  5. package/dist/config-helpers.d.ts +2 -1
  6. package/dist/config-helpers.d.ts.map +1 -1
  7. package/dist/config-helpers.js +1 -0
  8. package/dist/config-helpers.js.map +1 -1
  9. package/dist/constants.d.ts +3 -13
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/constants.js +3 -13
  12. package/dist/constants.js.map +1 -1
  13. package/dist/discover-entries-esbuild-plugin.d.ts.map +1 -1
  14. package/dist/discover-entries-esbuild-plugin.js +16 -1
  15. package/dist/discover-entries-esbuild-plugin.js.map +1 -1
  16. package/dist/external-package-warning.test.d.ts +2 -0
  17. package/dist/external-package-warning.test.d.ts.map +1 -0
  18. package/dist/external-package-warning.test.js +219 -0
  19. package/dist/external-package-warning.test.js.map +1 -0
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/module-specifier.d.ts.map +1 -1
  25. package/dist/module-specifier.js +47 -9
  26. package/dist/module-specifier.js.map +1 -1
  27. package/dist/module-specifier.test.js +20 -0
  28. package/dist/module-specifier.test.js.map +1 -1
  29. package/dist/node-module-esbuild-plugin.d.ts.map +1 -1
  30. package/dist/node-module-esbuild-plugin.js +72 -22
  31. package/dist/node-module-esbuild-plugin.js.map +1 -1
  32. package/dist/node-module-esbuild-plugin.test.js +96 -0
  33. package/dist/node-module-esbuild-plugin.test.js.map +1 -1
  34. package/dist/resolve-sourcemap.test.d.ts +2 -0
  35. package/dist/resolve-sourcemap.test.d.ts.map +1 -0
  36. package/dist/resolve-sourcemap.test.js +126 -0
  37. package/dist/resolve-sourcemap.test.js.map +1 -0
  38. package/dist/standalone.d.ts +0 -3
  39. package/dist/standalone.d.ts.map +1 -1
  40. package/dist/standalone.js +10 -39
  41. package/dist/standalone.js.map +1 -1
  42. package/dist/swc-esbuild-plugin.d.ts +9 -0
  43. package/dist/swc-esbuild-plugin.d.ts.map +1 -1
  44. package/dist/swc-esbuild-plugin.js +63 -8
  45. package/dist/swc-esbuild-plugin.js.map +1 -1
  46. package/dist/swc-esbuild-plugin.test.js +279 -3
  47. package/dist/swc-esbuild-plugin.test.js.map +1 -1
  48. package/dist/types.d.ts +29 -0
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/types.js.map +1 -1
  51. package/dist/vercel-build-output-api.d.ts +0 -2
  52. package/dist/vercel-build-output-api.d.ts.map +1 -1
  53. package/dist/vercel-build-output-api.js +24 -55
  54. package/dist/vercel-build-output-api.js.map +1 -1
  55. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,cAAuB;IAC7B,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,SAAS;IACnB,iBAAiB,EAAE,CAAC,EAAE,sCAAsC;IAC5D,mBAAmB,EAAE,CAAC,EAAE,mDAAmD;CAC5E,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,cAAuB;IAC7B,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE,SAAS;IACnB,iBAAiB,EAAE,CAAC,EAAE,sCAAsC;IAC5D,mBAAmB,EAAE,CAAC,EAAE,mDAAmD;CAC5E,CAAC","sourcesContent":["/**\n * Queue trigger configuration for workflow step execution.\n * Steps are queued to the __wkf_step_* topic.\n */\nexport const STEP_QUEUE_TRIGGER = {\n type: 'queue/v2beta' as const,\n topic: '__wkf_step_*',\n consumer: 'default',\n retryAfterSeconds: 5, // Delay between retries (default: 60)\n initialDelaySeconds: 0, // Initial delay before first delivery (default: 0)\n};\n\n/**\n * Queue trigger configuration for workflow orchestration.\n * Workflows are queued to the __wkf_workflow_* topic.\n */\nexport const WORKFLOW_QUEUE_TRIGGER = {\n type: 'queue/v2beta' as const,\n topic: '__wkf_workflow_*',\n consumer: 'default',\n retryAfterSeconds: 5, // Delay between retries (default: 60)\n initialDelaySeconds: 0, // Initial delay before first delivery (default: 0)\n};\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,cAAuB;IAC7B,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE,SAAS;IACnB,iBAAiB,EAAE,CAAC,EAAE,sCAAsC;IAC5D,mBAAmB,EAAE,CAAC,EAAE,mDAAmD;CAC5E,CAAC","sourcesContent":["/**\n * Queue trigger configuration for the workflow handler.\n * Handles both workflow orchestration and step execution on the same route.\n * Background steps are queued back to __wkf_workflow_* with a stepId.\n */\nexport const WORKFLOW_QUEUE_TRIGGER = {\n type: 'queue/v2beta' as const,\n topic: '__wkf_workflow_*',\n consumer: 'default',\n retryAfterSeconds: 5, // Delay between retries (default: 60)\n initialDelaySeconds: 0, // Initial delay before first delivery (default: 0)\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"discover-entries-esbuild-plugin.d.ts","sourceRoot":"","sources":["../src/discover-entries-esbuild-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAUtC,eAAO,MAAM,SAAS,QAAuC,CAAC;AAwB9D,eAAO,MAAM,aAAa,0BAAiC,CAAC;AAK5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CA0B3E;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE;IACL,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC,EACD,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAiIR"}
1
+ {"version":3,"file":"discover-entries-esbuild-plugin.d.ts","sourceRoot":"","sources":["../src/discover-entries-esbuild-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA2BtC,eAAO,MAAM,SAAS,QAAuC,CAAC;AAwB9D,eAAO,MAAM,aAAa,0BAAiC,CAAC;AAK5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CA0B3E;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE;IACL,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC,EACD,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAiIR"}
@@ -3,7 +3,22 @@ import { promisify } from 'node:util';
3
3
  import enhancedResolveOriginal from 'enhanced-resolve';
4
4
  import { applySwcTransform } from './apply-swc-transform.js';
5
5
  import { detectWorkflowPatterns, isGeneratedWorkflowFile, } from './transform-utils.js';
6
- const enhancedResolve = promisify(enhancedResolveOriginal);
6
+ const enhancedResolve = promisify(enhancedResolveOriginal.create({
7
+ extensions: [
8
+ '.ts',
9
+ '.tsx',
10
+ '.mts',
11
+ '.cts',
12
+ '.js',
13
+ '.jsx',
14
+ '.mjs',
15
+ '.cjs',
16
+ '.json',
17
+ '.node',
18
+ ],
19
+ fullySpecified: false,
20
+ conditionNames: ['node', 'import', 'require'],
21
+ }));
7
22
  export const jsTsRegex = /\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;
8
23
  /** Returns true if a manifest section has at least one entry. */
9
24
  function hasManifestEntries(section) {
@@ -1 +1 @@
1
- {"version":3,"file":"discover-entries-esbuild-plugin.js","sourceRoot":"","sources":["../src/discover-entries-esbuild-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport enhancedResolveOriginal from 'enhanced-resolve';\nimport type { Plugin } from 'esbuild';\nimport type { WorkflowManifest } from './apply-swc-transform.js';\nimport { applySwcTransform } from './apply-swc-transform.js';\nimport {\n detectWorkflowPatterns,\n isGeneratedWorkflowFile,\n} from './transform-utils.js';\n\nconst enhancedResolve = promisify(enhancedResolveOriginal);\n\nexport const jsTsRegex = /\\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;\n\n/** Returns true if a manifest section has at least one entry. */\nfunction hasManifestEntries(\n section: WorkflowManifest[keyof WorkflowManifest]\n): boolean {\n if (!section) return false;\n return Object.values(section).some(\n (entries) => Object.keys(entries).length > 0\n );\n}\n\nfunction isGeneratedBuildArtifactPath(filePath: string): boolean {\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n return (\n normalizedPath.includes('/.output/') ||\n normalizedPath.includes('/.next/') ||\n normalizedPath.includes('/.nuxt/') ||\n normalizedPath.includes('/.svelte-kit/') ||\n normalizedPath.includes('/.vercel/')\n );\n}\n\n// parent -> children relationship (a file can import multiple files)\nexport const importParents = new Map<string, Set<string>>();\n\n// check if a parent has a child in its import chain\n// e.g. if a dependency needs to be bundled because it has\n// a 'use workflow/'use step' directive in it\nexport function parentHasChild(parent: string, childToFind: string): boolean {\n const visited = new Set<string>();\n const queue: string[] = [parent];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const children = importParents.get(current);\n if (!children) {\n continue;\n }\n\n for (const child of children) {\n if (child === childToFind) {\n return true;\n }\n queue.push(child);\n }\n }\n\n return false;\n}\n\nexport function createDiscoverEntriesPlugin(\n state: {\n discoveredSteps: Set<string>;\n discoveredWorkflows: Set<string>;\n discoveredSerdeFiles: Set<string>;\n },\n projectRoot?: string\n): Plugin {\n return {\n name: 'discover-entries-esbuild-plugin',\n setup(build) {\n // Track parent→child import relationships for ALL imports (not just\n // those with file extensions) so that `parentHasChild()` can correctly\n // identify transitive parents of serde/step files even when the\n // dependency chain passes through bare specifier imports like\n // `@workflow/core/runtime` or `workflow/runtime`.\n build.onResolve({ filter: /.*/ }, async (args) => {\n try {\n const resolved = await enhancedResolve(args.resolveDir, args.path);\n\n if (resolved) {\n // Normalize path separators for cross-platform compatibility\n const normalizedImporter = args.importer.replace(/\\\\/g, '/');\n const normalizedResolved = resolved.replace(/\\\\/g, '/');\n // A file can import multiple files, so we store a Set of children\n let children = importParents.get(normalizedImporter);\n if (!children) {\n children = new Set<string>();\n importParents.set(normalizedImporter, children);\n }\n children.add(normalizedResolved);\n }\n } catch (_) {}\n return null;\n });\n\n // Handle TypeScript and JavaScript files\n build.onLoad({ filter: jsTsRegex }, async (args) => {\n try {\n if (isGeneratedBuildArtifactPath(args.path)) {\n return {\n contents: '',\n loader: 'js',\n };\n }\n\n // Skip generated workflow route files to avoid re-processing them\n if (isGeneratedWorkflowFile(args.path)) {\n const source = await readFile(args.path, 'utf8');\n return {\n contents: source,\n loader: args.path.endsWith('.jsx') ? 'jsx' : 'js',\n };\n }\n\n // Determine the loader based on the output\n let loader: 'js' | 'jsx' = 'js';\n const isTypeScript =\n args.path.endsWith('.ts') ||\n args.path.endsWith('.tsx') ||\n args.path.endsWith('.mts') ||\n args.path.endsWith('.cts');\n if (!isTypeScript && args.path.endsWith('.jsx')) {\n loader = 'jsx';\n }\n const source = await readFile(args.path, 'utf8');\n\n // Normalize path separators to forward slashes for cross-platform compatibility\n // This is critical for Windows where paths contain backslashes\n const normalizedPath = args.path.replace(/\\\\/g, '/');\n\n const resolvedProjectRoot =\n projectRoot || build.initialOptions.absWorkingDir || process.cwd();\n\n // Two-phase discovery:\n // 1. Fast regexp pre-scan filters out the vast majority of files.\n // 2. For the small number that match, run the SWC plugin in 'detect'\n // mode to get an AST-level manifest. Detect mode walks the AST to\n // find directives and serde patterns but does NOT transform any\n // code, eliminating false positives where directive-like strings\n // appear inside template literals, regular strings, or comments.\n //\n // All files are transformed by SWC (TS→JS, decorators, etc.) since\n // esbuild does not support all TypeScript syntax (e.g. legacy\n // decorators, emitDecoratorMetadata). For regexp-matched files the\n // 'detect' call handles both the syntax transform and the manifest\n // in a single pass; for all other files a mode:false call is used.\n const patterns = detectWorkflowPatterns(source);\n\n let transformedCode: string;\n\n if (patterns.hasDirective || patterns.hasSerde) {\n const { code, workflowManifest } = await applySwcTransform(\n normalizedPath,\n source,\n 'detect',\n normalizedPath,\n resolvedProjectRoot\n );\n transformedCode = code;\n\n if (hasManifestEntries(workflowManifest.workflows)) {\n state.discoveredWorkflows.add(normalizedPath);\n }\n if (hasManifestEntries(workflowManifest.steps)) {\n state.discoveredSteps.add(normalizedPath);\n }\n\n if (hasManifestEntries(workflowManifest.classes)) {\n state.discoveredSerdeFiles.add(normalizedPath);\n }\n } else {\n const { code } = await applySwcTransform(\n normalizedPath,\n source,\n false,\n normalizedPath,\n resolvedProjectRoot\n );\n transformedCode = code;\n }\n\n return {\n contents: transformedCode,\n loader,\n };\n } catch (_) {\n // ignore trace errors during discover phase\n return {\n contents: '',\n loader: 'js',\n };\n }\n });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"discover-entries-esbuild-plugin.js","sourceRoot":"","sources":["../src/discover-entries-esbuild-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport enhancedResolveOriginal from 'enhanced-resolve';\nimport type { Plugin } from 'esbuild';\nimport type { WorkflowManifest } from './apply-swc-transform.js';\nimport { applySwcTransform } from './apply-swc-transform.js';\nimport {\n detectWorkflowPatterns,\n isGeneratedWorkflowFile,\n} from './transform-utils.js';\n\nconst enhancedResolve = promisify(\n enhancedResolveOriginal.create({\n extensions: [\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.json',\n '.node',\n ],\n fullySpecified: false,\n conditionNames: ['node', 'import', 'require'],\n })\n);\n\nexport const jsTsRegex = /\\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;\n\n/** Returns true if a manifest section has at least one entry. */\nfunction hasManifestEntries(\n section: WorkflowManifest[keyof WorkflowManifest]\n): boolean {\n if (!section) return false;\n return Object.values(section).some(\n (entries) => Object.keys(entries).length > 0\n );\n}\n\nfunction isGeneratedBuildArtifactPath(filePath: string): boolean {\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n return (\n normalizedPath.includes('/.output/') ||\n normalizedPath.includes('/.next/') ||\n normalizedPath.includes('/.nuxt/') ||\n normalizedPath.includes('/.svelte-kit/') ||\n normalizedPath.includes('/.vercel/')\n );\n}\n\n// parent -> children relationship (a file can import multiple files)\nexport const importParents = new Map<string, Set<string>>();\n\n// check if a parent has a child in its import chain\n// e.g. if a dependency needs to be bundled because it has\n// a 'use workflow/'use step' directive in it\nexport function parentHasChild(parent: string, childToFind: string): boolean {\n const visited = new Set<string>();\n const queue: string[] = [parent];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const children = importParents.get(current);\n if (!children) {\n continue;\n }\n\n for (const child of children) {\n if (child === childToFind) {\n return true;\n }\n queue.push(child);\n }\n }\n\n return false;\n}\n\nexport function createDiscoverEntriesPlugin(\n state: {\n discoveredSteps: Set<string>;\n discoveredWorkflows: Set<string>;\n discoveredSerdeFiles: Set<string>;\n },\n projectRoot?: string\n): Plugin {\n return {\n name: 'discover-entries-esbuild-plugin',\n setup(build) {\n // Track parent→child import relationships for ALL imports (not just\n // those with file extensions) so that `parentHasChild()` can correctly\n // identify transitive parents of serde/step files even when the\n // dependency chain passes through bare specifier imports like\n // `@workflow/core/runtime` or `workflow/runtime`.\n build.onResolve({ filter: /.*/ }, async (args) => {\n try {\n const resolved = await enhancedResolve(args.resolveDir, args.path);\n\n if (resolved) {\n // Normalize path separators for cross-platform compatibility\n const normalizedImporter = args.importer.replace(/\\\\/g, '/');\n const normalizedResolved = resolved.replace(/\\\\/g, '/');\n // A file can import multiple files, so we store a Set of children\n let children = importParents.get(normalizedImporter);\n if (!children) {\n children = new Set<string>();\n importParents.set(normalizedImporter, children);\n }\n children.add(normalizedResolved);\n }\n } catch (_) {}\n return null;\n });\n\n // Handle TypeScript and JavaScript files\n build.onLoad({ filter: jsTsRegex }, async (args) => {\n try {\n if (isGeneratedBuildArtifactPath(args.path)) {\n return {\n contents: '',\n loader: 'js',\n };\n }\n\n // Skip generated workflow route files to avoid re-processing them\n if (isGeneratedWorkflowFile(args.path)) {\n const source = await readFile(args.path, 'utf8');\n return {\n contents: source,\n loader: args.path.endsWith('.jsx') ? 'jsx' : 'js',\n };\n }\n\n // Determine the loader based on the output\n let loader: 'js' | 'jsx' = 'js';\n const isTypeScript =\n args.path.endsWith('.ts') ||\n args.path.endsWith('.tsx') ||\n args.path.endsWith('.mts') ||\n args.path.endsWith('.cts');\n if (!isTypeScript && args.path.endsWith('.jsx')) {\n loader = 'jsx';\n }\n const source = await readFile(args.path, 'utf8');\n\n // Normalize path separators to forward slashes for cross-platform compatibility\n // This is critical for Windows where paths contain backslashes\n const normalizedPath = args.path.replace(/\\\\/g, '/');\n\n const resolvedProjectRoot =\n projectRoot || build.initialOptions.absWorkingDir || process.cwd();\n\n // Two-phase discovery:\n // 1. Fast regexp pre-scan filters out the vast majority of files.\n // 2. For the small number that match, run the SWC plugin in 'detect'\n // mode to get an AST-level manifest. Detect mode walks the AST to\n // find directives and serde patterns but does NOT transform any\n // code, eliminating false positives where directive-like strings\n // appear inside template literals, regular strings, or comments.\n //\n // All files are transformed by SWC (TS→JS, decorators, etc.) since\n // esbuild does not support all TypeScript syntax (e.g. legacy\n // decorators, emitDecoratorMetadata). For regexp-matched files the\n // 'detect' call handles both the syntax transform and the manifest\n // in a single pass; for all other files a mode:false call is used.\n const patterns = detectWorkflowPatterns(source);\n\n let transformedCode: string;\n\n if (patterns.hasDirective || patterns.hasSerde) {\n const { code, workflowManifest } = await applySwcTransform(\n normalizedPath,\n source,\n 'detect',\n normalizedPath,\n resolvedProjectRoot\n );\n transformedCode = code;\n\n if (hasManifestEntries(workflowManifest.workflows)) {\n state.discoveredWorkflows.add(normalizedPath);\n }\n if (hasManifestEntries(workflowManifest.steps)) {\n state.discoveredSteps.add(normalizedPath);\n }\n\n if (hasManifestEntries(workflowManifest.classes)) {\n state.discoveredSerdeFiles.add(normalizedPath);\n }\n } else {\n const { code } = await applySwcTransform(\n normalizedPath,\n source,\n false,\n normalizedPath,\n resolvedProjectRoot\n );\n transformedCode = code;\n }\n\n return {\n contents: transformedCode,\n loader,\n };\n } catch (_) {\n // ignore trace errors during discover phase\n return {\n contents: '',\n loader: 'js',\n };\n }\n });\n },\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=external-package-warning.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-package-warning.test.d.ts","sourceRoot":"","sources":["../src/external-package-warning.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,219 @@
1
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync, } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
+ import { BaseBuilder } from './base-builder.js';
6
+ /**
7
+ * Minimal subclass to expose the protected `discoverEntries()` for testing.
8
+ */
9
+ class TestBuilder extends BaseBuilder {
10
+ async build() {
11
+ // no-op
12
+ }
13
+ // Expose for tests
14
+ discoverEntriesPublic(inputs, outdir) {
15
+ return this.discoverEntries(inputs, outdir);
16
+ }
17
+ }
18
+ // Resolve symlinks in tmpdir to avoid macOS /var -> /private/var issues
19
+ const realTmpdir = realpathSync(tmpdir());
20
+ function writeFile(path, contents) {
21
+ mkdirSync(dirname(path), { recursive: true });
22
+ writeFileSync(path, contents, 'utf-8');
23
+ }
24
+ function createBuilder(workingDir, externalPackages) {
25
+ const config = {
26
+ buildTarget: 'standalone',
27
+ workingDir,
28
+ dirs: ['.'],
29
+ externalPackages,
30
+ stepsBundlePath: join(workingDir, 'steps.js'),
31
+ workflowsBundlePath: join(workingDir, 'workflows.js'),
32
+ webhookBundlePath: join(workingDir, 'webhook.js'),
33
+ };
34
+ return new TestBuilder(config);
35
+ }
36
+ describe('warnAboutExternalWorkflowPackages', () => {
37
+ let testRoot;
38
+ let warnSpy;
39
+ beforeEach(() => {
40
+ testRoot = mkdtempSync(join(realTmpdir, 'workflow-external-pkg-warning-'));
41
+ warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
42
+ });
43
+ afterEach(() => {
44
+ warnSpy.mockRestore();
45
+ rmSync(testRoot, { recursive: true, force: true });
46
+ });
47
+ it('warns when an external package depends on @workflow/serde', async () => {
48
+ // Create a mock project with a node_modules package
49
+ const projectDir = join(testRoot, 'project');
50
+ // Create a minimal entry file for the project
51
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
52
+ // Create the external package with @workflow/serde dependency
53
+ writeFile(join(projectDir, 'node_modules', 'my-serde-pkg', 'package.json'), JSON.stringify({
54
+ name: 'my-serde-pkg',
55
+ version: '1.0.0',
56
+ main: 'index.js',
57
+ dependencies: {
58
+ '@workflow/serde': '^1.0.0',
59
+ },
60
+ }));
61
+ writeFile(join(projectDir, 'node_modules', 'my-serde-pkg', 'index.js'), 'export class Foo {}');
62
+ const builder = createBuilder(projectDir, ['my-serde-pkg']);
63
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
64
+ expect(warnSpy).toHaveBeenCalled();
65
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
66
+ expect(warnMessage).toContain('my-serde-pkg');
67
+ expect(warnMessage).toContain('serverExternalPackages');
68
+ expect(warnMessage).toContain('serialization classes');
69
+ });
70
+ it('warns when an external package source contains serde symbols', async () => {
71
+ const projectDir = join(testRoot, 'project');
72
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
73
+ // Package without @workflow/serde dep but with Symbol.for patterns in source
74
+ writeFile(join(projectDir, 'node_modules', 'my-symbol-pkg', 'package.json'), JSON.stringify({
75
+ name: 'my-symbol-pkg',
76
+ version: '1.0.0',
77
+ main: 'index.js',
78
+ }));
79
+ writeFile(join(projectDir, 'node_modules', 'my-symbol-pkg', 'index.js'), `export class Bar {
80
+ static [Symbol.for('workflow-serialize')](instance) { return {}; }
81
+ static [Symbol.for('workflow-deserialize')](data) { return new Bar(); }
82
+ }`);
83
+ const builder = createBuilder(projectDir, ['my-symbol-pkg']);
84
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
85
+ expect(warnSpy).toHaveBeenCalled();
86
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
87
+ expect(warnMessage).toContain('my-symbol-pkg');
88
+ expect(warnMessage).toContain('serialization classes');
89
+ });
90
+ it('warns when an external package contains "use step" directives', async () => {
91
+ const projectDir = join(testRoot, 'project');
92
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
93
+ writeFile(join(projectDir, 'node_modules', 'my-step-pkg', 'package.json'), JSON.stringify({
94
+ name: 'my-step-pkg',
95
+ version: '1.0.0',
96
+ main: 'index.js',
97
+ }));
98
+ writeFile(join(projectDir, 'node_modules', 'my-step-pkg', 'index.js'), `export async function doWork() {
99
+ "use step";
100
+ return 42;
101
+ }`);
102
+ const builder = createBuilder(projectDir, ['my-step-pkg']);
103
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
104
+ expect(warnSpy).toHaveBeenCalled();
105
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
106
+ expect(warnMessage).toContain('my-step-pkg');
107
+ expect(warnMessage).toContain('"use step" functions');
108
+ });
109
+ it('warns when an external package contains "use workflow" directives', async () => {
110
+ const projectDir = join(testRoot, 'project');
111
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
112
+ writeFile(join(projectDir, 'node_modules', 'my-workflow-pkg', 'package.json'), JSON.stringify({
113
+ name: 'my-workflow-pkg',
114
+ version: '1.0.0',
115
+ main: 'index.js',
116
+ }));
117
+ writeFile(join(projectDir, 'node_modules', 'my-workflow-pkg', 'index.js'), `export async function runJob() {
118
+ "use workflow";
119
+ return "done";
120
+ }`);
121
+ const builder = createBuilder(projectDir, ['my-workflow-pkg']);
122
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
123
+ expect(warnSpy).toHaveBeenCalled();
124
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
125
+ expect(warnMessage).toContain('my-workflow-pkg');
126
+ expect(warnMessage).toContain('"use workflow" functions');
127
+ });
128
+ it('does not warn for packages without workflow patterns', async () => {
129
+ const projectDir = join(testRoot, 'project');
130
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
131
+ writeFile(join(projectDir, 'node_modules', 'plain-pkg', 'package.json'), JSON.stringify({
132
+ name: 'plain-pkg',
133
+ version: '1.0.0',
134
+ main: 'index.js',
135
+ }));
136
+ writeFile(join(projectDir, 'node_modules', 'plain-pkg', 'index.js'), 'export const hello = "world";');
137
+ const builder = createBuilder(projectDir, ['plain-pkg']);
138
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
139
+ expect(warnSpy).not.toHaveBeenCalled();
140
+ });
141
+ it('does not warn for pseudo-packages (server-only, client-only)', async () => {
142
+ const projectDir = join(testRoot, 'project');
143
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
144
+ const builder = createBuilder(projectDir, ['server-only', 'client-only']);
145
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
146
+ expect(warnSpy).not.toHaveBeenCalled();
147
+ });
148
+ it('does not warn when externalPackages is empty', async () => {
149
+ const projectDir = join(testRoot, 'project');
150
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
151
+ const builder = createBuilder(projectDir, []);
152
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
153
+ expect(warnSpy).not.toHaveBeenCalled();
154
+ });
155
+ it('warns only once per package across multiple discoverEntries calls', async () => {
156
+ const projectDir = join(testRoot, 'project');
157
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
158
+ writeFile(join(projectDir, 'other.ts'), 'export const y = 2;');
159
+ writeFile(join(projectDir, 'node_modules', 'my-serde-pkg', 'package.json'), JSON.stringify({
160
+ name: 'my-serde-pkg',
161
+ version: '1.0.0',
162
+ main: 'index.js',
163
+ dependencies: { '@workflow/serde': '^1.0.0' },
164
+ }));
165
+ writeFile(join(projectDir, 'node_modules', 'my-serde-pkg', 'index.js'), 'export class Foo {}');
166
+ const builder = createBuilder(projectDir, ['my-serde-pkg']);
167
+ // Call discoverEntries twice with different inputs
168
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
169
+ await builder.discoverEntriesPublic([join(projectDir, 'other.ts')], join(projectDir, 'out2'));
170
+ // Should only warn once
171
+ const warnCalls = warnSpy.mock.calls.filter((call) => call[0].includes('my-serde-pkg'));
172
+ expect(warnCalls).toHaveLength(1);
173
+ });
174
+ it('lists multiple detected issues in the warning message', async () => {
175
+ const projectDir = join(testRoot, 'project');
176
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
177
+ writeFile(join(projectDir, 'node_modules', 'multi-pkg', 'package.json'), JSON.stringify({
178
+ name: 'multi-pkg',
179
+ version: '1.0.0',
180
+ main: 'index.js',
181
+ dependencies: { '@workflow/serde': '^1.0.0' },
182
+ }));
183
+ writeFile(join(projectDir, 'node_modules', 'multi-pkg', 'index.js'), `export async function doWork() {
184
+ "use step";
185
+ return 42;
186
+ }
187
+ export class Foo {
188
+ static [Symbol.for('workflow-serialize')](instance) { return {}; }
189
+ static [Symbol.for('workflow-deserialize')](data) { return new Foo(); }
190
+ }`);
191
+ const builder = createBuilder(projectDir, ['multi-pkg']);
192
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
193
+ expect(warnSpy).toHaveBeenCalled();
194
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
195
+ expect(warnMessage).toContain('"use step" functions');
196
+ expect(warnMessage).toContain('serialization classes');
197
+ });
198
+ it('warns via entry-file detection when package.json has no serde dep', async () => {
199
+ const projectDir = join(testRoot, 'project');
200
+ writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');
201
+ // Package without @workflow/serde in deps, but entry has "use step"
202
+ writeFile(join(projectDir, 'node_modules', 'no-serde-dep-pkg', 'package.json'), JSON.stringify({
203
+ name: 'no-serde-dep-pkg',
204
+ version: '1.0.0',
205
+ main: 'index.js',
206
+ }));
207
+ writeFile(join(projectDir, 'node_modules', 'no-serde-dep-pkg', 'index.js'), `export async function doWork() {
208
+ "use step";
209
+ return 42;
210
+ }`);
211
+ const builder = createBuilder(projectDir, ['no-serde-dep-pkg']);
212
+ await builder.discoverEntriesPublic([join(projectDir, 'index.ts')], join(projectDir, 'out'));
213
+ expect(warnSpy).toHaveBeenCalled();
214
+ const warnMessage = warnSpy.mock.calls[0]?.[0];
215
+ expect(warnMessage).toContain('no-serde-dep-pkg');
216
+ expect(warnMessage).toContain('"use step" functions');
217
+ });
218
+ });
219
+ //# sourceMappingURL=external-package-warning.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-package-warning.test.js","sourceRoot":"","sources":["../src/external-package-warning.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n mkdirSync,\n mkdtempSync,\n realpathSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport { BaseBuilder, type DiscoveredEntries } from './base-builder.js';\nimport type { StandaloneConfig } from './types.js';\n\n/**\n * Minimal subclass to expose the protected `discoverEntries()` for testing.\n */\nclass TestBuilder extends BaseBuilder {\n async build(): Promise<void> {\n // no-op\n }\n\n // Expose for tests\n public discoverEntriesPublic(\n inputs: string[],\n outdir: string\n ): Promise<DiscoveredEntries> {\n return this.discoverEntries(inputs, outdir);\n }\n}\n\n// Resolve symlinks in tmpdir to avoid macOS /var -> /private/var issues\nconst realTmpdir = realpathSync(tmpdir());\n\nfunction writeFile(path: string, contents: string): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, contents, 'utf-8');\n}\n\nfunction createBuilder(\n workingDir: string,\n externalPackages: string[]\n): TestBuilder {\n const config: StandaloneConfig = {\n buildTarget: 'standalone',\n workingDir,\n dirs: ['.'],\n externalPackages,\n stepsBundlePath: join(workingDir, 'steps.js'),\n workflowsBundlePath: join(workingDir, 'workflows.js'),\n webhookBundlePath: join(workingDir, 'webhook.js'),\n };\n return new TestBuilder(config);\n}\n\ndescribe('warnAboutExternalWorkflowPackages', () => {\n let testRoot: string;\n let warnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n testRoot = mkdtempSync(join(realTmpdir, 'workflow-external-pkg-warning-'));\n warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});\n });\n\n afterEach(() => {\n warnSpy.mockRestore();\n rmSync(testRoot, { recursive: true, force: true });\n });\n\n it('warns when an external package depends on @workflow/serde', async () => {\n // Create a mock project with a node_modules package\n const projectDir = join(testRoot, 'project');\n\n // Create a minimal entry file for the project\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n // Create the external package with @workflow/serde dependency\n writeFile(\n join(projectDir, 'node_modules', 'my-serde-pkg', 'package.json'),\n JSON.stringify({\n name: 'my-serde-pkg',\n version: '1.0.0',\n main: 'index.js',\n dependencies: {\n '@workflow/serde': '^1.0.0',\n },\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'my-serde-pkg', 'index.js'),\n 'export class Foo {}'\n );\n\n const builder = createBuilder(projectDir, ['my-serde-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('my-serde-pkg');\n expect(warnMessage).toContain('serverExternalPackages');\n expect(warnMessage).toContain('serialization classes');\n });\n\n it('warns when an external package source contains serde symbols', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n // Package without @workflow/serde dep but with Symbol.for patterns in source\n writeFile(\n join(projectDir, 'node_modules', 'my-symbol-pkg', 'package.json'),\n JSON.stringify({\n name: 'my-symbol-pkg',\n version: '1.0.0',\n main: 'index.js',\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'my-symbol-pkg', 'index.js'),\n `export class Bar {\n static [Symbol.for('workflow-serialize')](instance) { return {}; }\n static [Symbol.for('workflow-deserialize')](data) { return new Bar(); }\n}`\n );\n\n const builder = createBuilder(projectDir, ['my-symbol-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('my-symbol-pkg');\n expect(warnMessage).toContain('serialization classes');\n });\n\n it('warns when an external package contains \"use step\" directives', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n writeFile(\n join(projectDir, 'node_modules', 'my-step-pkg', 'package.json'),\n JSON.stringify({\n name: 'my-step-pkg',\n version: '1.0.0',\n main: 'index.js',\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'my-step-pkg', 'index.js'),\n `export async function doWork() {\n \"use step\";\n return 42;\n}`\n );\n\n const builder = createBuilder(projectDir, ['my-step-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('my-step-pkg');\n expect(warnMessage).toContain('\"use step\" functions');\n });\n\n it('warns when an external package contains \"use workflow\" directives', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n writeFile(\n join(projectDir, 'node_modules', 'my-workflow-pkg', 'package.json'),\n JSON.stringify({\n name: 'my-workflow-pkg',\n version: '1.0.0',\n main: 'index.js',\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'my-workflow-pkg', 'index.js'),\n `export async function runJob() {\n \"use workflow\";\n return \"done\";\n}`\n );\n\n const builder = createBuilder(projectDir, ['my-workflow-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('my-workflow-pkg');\n expect(warnMessage).toContain('\"use workflow\" functions');\n });\n\n it('does not warn for packages without workflow patterns', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n writeFile(\n join(projectDir, 'node_modules', 'plain-pkg', 'package.json'),\n JSON.stringify({\n name: 'plain-pkg',\n version: '1.0.0',\n main: 'index.js',\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'plain-pkg', 'index.js'),\n 'export const hello = \"world\";'\n );\n\n const builder = createBuilder(projectDir, ['plain-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).not.toHaveBeenCalled();\n });\n\n it('does not warn for pseudo-packages (server-only, client-only)', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n const builder = createBuilder(projectDir, ['server-only', 'client-only']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).not.toHaveBeenCalled();\n });\n\n it('does not warn when externalPackages is empty', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n const builder = createBuilder(projectDir, []);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).not.toHaveBeenCalled();\n });\n\n it('warns only once per package across multiple discoverEntries calls', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n writeFile(join(projectDir, 'other.ts'), 'export const y = 2;');\n\n writeFile(\n join(projectDir, 'node_modules', 'my-serde-pkg', 'package.json'),\n JSON.stringify({\n name: 'my-serde-pkg',\n version: '1.0.0',\n main: 'index.js',\n dependencies: { '@workflow/serde': '^1.0.0' },\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'my-serde-pkg', 'index.js'),\n 'export class Foo {}'\n );\n\n const builder = createBuilder(projectDir, ['my-serde-pkg']);\n\n // Call discoverEntries twice with different inputs\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n await builder.discoverEntriesPublic(\n [join(projectDir, 'other.ts')],\n join(projectDir, 'out2')\n );\n\n // Should only warn once\n const warnCalls = warnSpy.mock.calls.filter((call: unknown[]) =>\n (call[0] as string).includes('my-serde-pkg')\n );\n expect(warnCalls).toHaveLength(1);\n });\n\n it('lists multiple detected issues in the warning message', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n writeFile(\n join(projectDir, 'node_modules', 'multi-pkg', 'package.json'),\n JSON.stringify({\n name: 'multi-pkg',\n version: '1.0.0',\n main: 'index.js',\n dependencies: { '@workflow/serde': '^1.0.0' },\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'multi-pkg', 'index.js'),\n `export async function doWork() {\n \"use step\";\n return 42;\n}\nexport class Foo {\n static [Symbol.for('workflow-serialize')](instance) { return {}; }\n static [Symbol.for('workflow-deserialize')](data) { return new Foo(); }\n}`\n );\n\n const builder = createBuilder(projectDir, ['multi-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('\"use step\" functions');\n expect(warnMessage).toContain('serialization classes');\n });\n\n it('warns via entry-file detection when package.json has no serde dep', async () => {\n const projectDir = join(testRoot, 'project');\n\n writeFile(join(projectDir, 'index.ts'), 'export const x = 1;');\n\n // Package without @workflow/serde in deps, but entry has \"use step\"\n writeFile(\n join(projectDir, 'node_modules', 'no-serde-dep-pkg', 'package.json'),\n JSON.stringify({\n name: 'no-serde-dep-pkg',\n version: '1.0.0',\n main: 'index.js',\n })\n );\n writeFile(\n join(projectDir, 'node_modules', 'no-serde-dep-pkg', 'index.js'),\n `export async function doWork() {\n \"use step\";\n return 42;\n}`\n );\n\n const builder = createBuilder(projectDir, ['no-serde-dep-pkg']);\n await builder.discoverEntriesPublic(\n [join(projectDir, 'index.ts')],\n join(projectDir, 'out')\n );\n\n expect(warnSpy).toHaveBeenCalled();\n const warnMessage = warnSpy.mock.calls[0]?.[0] as string;\n expect(warnMessage).toContain('no-serde-dep-pkg');\n expect(warnMessage).toContain('\"use step\" functions');\n });\n});\n"]}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { applySwcTransform } from './apply-swc-transform.js';
3
3
  export { BaseBuilder } from './base-builder.js';
4
4
  export { createBuildQueue } from './build-queue.js';
5
5
  export { createBaseBuilderConfig, type DecoratorOptions, type DecoratorOptionsWithConfigPath, getDecoratorOptionsForDirectory, getDecoratorOptionsForDirectoryWithConfigPath, } from './config-helpers.js';
6
- export { STEP_QUEUE_TRIGGER, WORKFLOW_QUEUE_TRIGGER } from './constants.js';
6
+ export { WORKFLOW_QUEUE_TRIGGER } from './constants.js';
7
7
  export { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';
8
8
  export { clearModuleSpecifierCache, getImportPath, type ImportPathResult, type ModuleSpecifierResult, resolveModuleSpecifier, } from './module-specifier.js';
9
9
  export { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,8BAA8B,EACnC,+BAA+B,EAC/B,6CAA6C,GAC9C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,eAAe,GAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,uBAAuB,EACvB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,8BAA8B,EACnC,+BAA+B,EAC/B,6CAA6C,GAC9C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,eAAe,GAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,uBAAuB,EACvB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ export { applySwcTransform } from './apply-swc-transform.js';
2
2
  export { BaseBuilder } from './base-builder.js';
3
3
  export { createBuildQueue } from './build-queue.js';
4
4
  export { createBaseBuilderConfig, getDecoratorOptionsForDirectory, getDecoratorOptionsForDirectoryWithConfigPath, } from './config-helpers.js';
5
- export { STEP_QUEUE_TRIGGER, WORKFLOW_QUEUE_TRIGGER } from './constants.js';
5
+ export { WORKFLOW_QUEUE_TRIGGER } from './constants.js';
6
6
  export { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';
7
7
  export { clearModuleSpecifierCache, getImportPath, resolveModuleSpecifier, } from './module-specifier.js';
8
8
  export { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,uBAAuB,EAGvB,+BAA+B,EAC/B,6CAA6C,GAC9C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,yBAAyB,EACzB,aAAa,EAGb,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,eAAe,GAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GAGpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAElB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAU9B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export type { WorkflowManifest } from './apply-swc-transform.js';\nexport { applySwcTransform } from './apply-swc-transform.js';\nexport { BaseBuilder } from './base-builder.js';\nexport { createBuildQueue } from './build-queue.js';\nexport {\n createBaseBuilderConfig,\n type DecoratorOptions,\n type DecoratorOptionsWithConfigPath,\n getDecoratorOptionsForDirectory,\n getDecoratorOptionsForDirectoryWithConfigPath,\n} from './config-helpers.js';\nexport { STEP_QUEUE_TRIGGER, WORKFLOW_QUEUE_TRIGGER } from './constants.js';\nexport { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';\nexport {\n clearModuleSpecifierCache,\n getImportPath,\n type ImportPathResult,\n type ModuleSpecifierResult,\n resolveModuleSpecifier,\n} from './module-specifier.js';\nexport { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';\nexport {\n createPseudoPackagePlugin,\n PSEUDO_PACKAGES,\n} from './pseudo-package-esbuild-plugin.js';\nexport { NORMALIZE_REQUEST_CODE } from './request-converter.js';\nexport {\n analyzeSerdeCompliance,\n extractClassEntries,\n type SerdeCheckResult,\n type SerdeClassCheckResult,\n} from './serde-checker.js';\nexport { StandaloneBuilder } from './standalone.js';\nexport { createSwcPlugin } from './swc-esbuild-plugin.js';\nexport {\n detectWorkflowPatterns,\n generatedWorkflowPathPattern,\n isGeneratedWorkflowFile,\n shouldTransformFile,\n turbopackContentPattern,\n useStepPattern,\n useWorkflowPattern,\n type WorkflowPatternMatch,\n workflowSerdeImportPattern,\n workflowSerdeSymbolPattern,\n} from './transform-utils.js';\nexport type {\n AstroConfig,\n BuildTarget,\n NextConfig,\n StandaloneConfig,\n SvelteKitConfig,\n VercelBuildOutputConfig,\n WorkflowConfig,\n} from './types.js';\nexport { isValidBuildTarget, validBuildTargets } from './types.js';\nexport { VercelBuildOutputAPIBuilder } from './vercel-build-output-api.js';\nexport { resolveWorkflowAliasRelativePath } from './workflow-alias.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,uBAAuB,EAGvB,+BAA+B,EAC/B,6CAA6C,GAC9C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,yBAAyB,EACzB,aAAa,EAGb,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,eAAe,GAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GAGpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAElB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAU9B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export type { WorkflowManifest } from './apply-swc-transform.js';\nexport { applySwcTransform } from './apply-swc-transform.js';\nexport { BaseBuilder } from './base-builder.js';\nexport { createBuildQueue } from './build-queue.js';\nexport {\n createBaseBuilderConfig,\n type DecoratorOptions,\n type DecoratorOptionsWithConfigPath,\n getDecoratorOptionsForDirectory,\n getDecoratorOptionsForDirectoryWithConfigPath,\n} from './config-helpers.js';\nexport { WORKFLOW_QUEUE_TRIGGER } from './constants.js';\nexport { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';\nexport {\n clearModuleSpecifierCache,\n getImportPath,\n type ImportPathResult,\n type ModuleSpecifierResult,\n resolveModuleSpecifier,\n} from './module-specifier.js';\nexport { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';\nexport {\n createPseudoPackagePlugin,\n PSEUDO_PACKAGES,\n} from './pseudo-package-esbuild-plugin.js';\nexport { NORMALIZE_REQUEST_CODE } from './request-converter.js';\nexport {\n analyzeSerdeCompliance,\n extractClassEntries,\n type SerdeCheckResult,\n type SerdeClassCheckResult,\n} from './serde-checker.js';\nexport { StandaloneBuilder } from './standalone.js';\nexport { createSwcPlugin } from './swc-esbuild-plugin.js';\nexport {\n detectWorkflowPatterns,\n generatedWorkflowPathPattern,\n isGeneratedWorkflowFile,\n shouldTransformFile,\n turbopackContentPattern,\n useStepPattern,\n useWorkflowPattern,\n type WorkflowPatternMatch,\n workflowSerdeImportPattern,\n workflowSerdeSymbolPattern,\n} from './transform-utils.js';\nexport type {\n AstroConfig,\n BuildTarget,\n NextConfig,\n StandaloneConfig,\n SvelteKitConfig,\n VercelBuildOutputConfig,\n WorkflowConfig,\n} from './types.js';\nexport { isValidBuildTarget, validBuildTargets } from './types.js';\nexport { VercelBuildOutputAPIBuilder } from './vercel-build-output-api.js';\nexport { resolveWorkflowAliasRelativePath } from './workflow-alias.js';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"module-specifier.d.ts","sourceRoot":"","sources":["../src/module-specifier.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAgQD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,qBAAqB,CA6BvB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AA0HD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,gBAAgB,CA6DlB"}
1
+ {"version":3,"file":"module-specifier.d.ts","sourceRoot":"","sources":["../src/module-specifier.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAoTD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,qBAAqB,CA+BvB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AA0HD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,gBAAgB,CA6DlB"}
@@ -67,24 +67,60 @@ function findPackageJson(filePath) {
67
67
  * @param pkg - Package info from findPackageJson
68
68
  * @returns The subpath (e.g., "/internal/builtins") or empty string for root export
69
69
  */
70
- function resolveExportSubpath(filePath, pkg) {
70
+ function toPackageRelativePath(filePath, pkg) {
71
+ const normalizedFilePath = filePath.replace(/\\/g, '/');
72
+ const normalizedPkgDir = pkg.dir.replace(/\\/g, '/');
73
+ if (!normalizedFilePath.startsWith(normalizedPkgDir + '/')) {
74
+ return null;
75
+ }
76
+ return normalizedFilePath.substring(normalizedPkgDir.length + 1);
77
+ }
78
+ function getSourceFallbackExportTargets(relativePath) {
79
+ const fallbackTargets = new Set();
80
+ const extensionFallbacks = {
81
+ '.ts': ['.js'],
82
+ '.tsx': ['.js'],
83
+ '.mts': ['.mjs'],
84
+ '.cts': ['.cjs'],
85
+ '.jsx': ['.js'],
86
+ };
87
+ const extensionMatch = relativePath.match(/(\.[^./\\]+)$/);
88
+ const extension = extensionMatch?.[1]?.toLowerCase();
89
+ if (!extension) {
90
+ return [];
91
+ }
92
+ const pathWithoutExtension = relativePath.slice(0, -extension.length);
93
+ const extensionTargets = extensionFallbacks[extension] ?? [];
94
+ for (const fallbackExtension of extensionTargets) {
95
+ fallbackTargets.add(`${pathWithoutExtension}${fallbackExtension}`);
96
+ }
97
+ if (relativePath.startsWith('src/')) {
98
+ const distPathWithoutPrefix = relativePath.slice('src/'.length);
99
+ for (const fallbackExtension of extensionTargets) {
100
+ fallbackTargets.add(`dist/${distPathWithoutPrefix.slice(0, -extension.length)}${fallbackExtension}`);
101
+ }
102
+ }
103
+ return Array.from(fallbackTargets);
104
+ }
105
+ function resolveExportSubpath(filePath, pkg, options) {
71
106
  if (!pkg.exports || typeof pkg.exports !== 'object') {
72
107
  return '';
73
108
  }
74
- // Get the relative path from package root to the file
75
- const normalizedFilePath = filePath.replace(/\\/g, '/');
76
- const normalizedPkgDir = pkg.dir.replace(/\\/g, '/');
77
- const relativePath = normalizedFilePath.startsWith(normalizedPkgDir + '/')
78
- ? './' + normalizedFilePath.substring(normalizedPkgDir.length + 1)
79
- : null;
109
+ const relativePath = toPackageRelativePath(filePath, pkg);
80
110
  if (!relativePath) {
81
111
  return '';
82
112
  }
113
+ const comparableTargets = new Set([`./${relativePath}`]);
114
+ if (options?.allowSourceFallback) {
115
+ for (const fallbackTarget of getSourceFallbackExportTargets(relativePath)) {
116
+ comparableTargets.add(`./${fallbackTarget}`);
117
+ }
118
+ }
83
119
  // Search through exports to find a matching subpath
84
120
  for (const [subpath, target] of Object.entries(pkg.exports)) {
85
121
  const resolvedTarget = resolveExportTarget(target);
86
122
  if (resolvedTarget &&
87
- normalizeExportPath(resolvedTarget) === relativePath) {
123
+ comparableTargets.has(normalizeExportPath(resolvedTarget))) {
88
124
  // Found a match - return the subpath without the leading "."
89
125
  // e.g., "./internal/builtins" -> "/internal/builtins"
90
126
  return subpath === '.' ? '' : subpath.substring(1);
@@ -255,7 +291,9 @@ export function resolveModuleSpecifier(filePath, projectRoot) {
255
291
  return { moduleSpecifier: undefined };
256
292
  }
257
293
  // Resolve the export subpath (e.g., "/internal/builtins" for "workflow/internal/builtins")
258
- const subpath = resolveExportSubpath(filePath, pkg);
294
+ const subpath = resolveExportSubpath(filePath, pkg, {
295
+ allowSourceFallback: true,
296
+ });
259
297
  // Return the module specifier as "name/subpath@version" or "name@version"
260
298
  const specifier = subpath
261
299
  ? `${pkg.name}${subpath}@${pkg.version}`