@tailor-platform/sdk 1.44.0 → 1.44.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 1.44.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1096](https://github.com/tailor-platform/sdk/pull/1096) [`53dbbaf`](https://github.com/tailor-platform/sdk/commit/53dbbaf4a6de353f227c3ef57f39580b7e1d9379) Thanks [@k1LoW](https://github.com/k1LoW)! - Fix workflow bundle build failure caused by removing default exports from dependency files during cross-file workflow imports
8
+
9
+ ## 1.44.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1088](https://github.com/tailor-platform/sdk/pull/1088) [`6dc5318`](https://github.com/tailor-platform/sdk/commit/6dc53185418c117c65cebd92c8ee38ae406e8c9a) Thanks [@k1LoW](https://github.com/k1LoW)! - Fix workflow bundle build failure caused by dead default imports after cross-file trigger transformation
14
+
15
+ - [#1085](https://github.com/tailor-platform/sdk/pull/1085) [`0947e14`](https://github.com/tailor-platform/sdk/commit/0947e14daf39bf35b84f496984c32acb4c7bc24b) Thanks [@k1LoW](https://github.com/k1LoW)! - Add `concurrencyPolicy` option to `createWorkflow` for limiting concurrent workflow executions
16
+
3
17
  ## 1.44.0
4
18
 
5
19
  ### Minor Changes
@@ -1,5 +1,5 @@
1
1
 
2
- import { u as initOAuth2Client } from "./client-DQl5NPG9.mjs";
2
+ import { u as initOAuth2Client } from "./client-DcuQRqSd.mjs";
3
3
  import { n as isSdkBranded } from "./brand-Ll48SMXe.mjs";
4
4
  import { a as parseBoolean, n as logger, r as styles } from "./logger-DTNAMYGy.mjs";
5
5
  import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-C3KSpsYj.mjs";
@@ -1781,6 +1781,121 @@ function extractAuthInvokerInfo(configArg, sourceText) {
1781
1781
  }
1782
1782
  }
1783
1783
  /**
1784
+ * Check if an AST binding pattern (parameter, catch clause, etc.) contains an Identifier with the given name.
1785
+ * @param node - AST node to inspect
1786
+ * @param name - Identifier name to look for
1787
+ * @returns True if the binding pattern contains the name
1788
+ */
1789
+ function containsBindingName(node, name) {
1790
+ if (!node || typeof node !== "object") return false;
1791
+ if (node.type === "Identifier" && node.name === name) return true;
1792
+ for (const key of Object.keys(node)) {
1793
+ const child = node[key];
1794
+ if (Array.isArray(child)) {
1795
+ if (child.some((c) => containsBindingName(c, name))) return true;
1796
+ } else if (child && typeof child === "object") {
1797
+ if (containsBindingName(child, name)) return true;
1798
+ }
1799
+ }
1800
+ return false;
1801
+ }
1802
+ /**
1803
+ * Build a map of reference counts for multiple identifiers in a single AST pass.
1804
+ * Scope-aware: references inside functions or catch clauses that shadow the name
1805
+ * via parameters are excluded, so only references to the original import binding
1806
+ * are counted.
1807
+ * Excludes import declarations and property names in non-computed member expressions.
1808
+ * @param program - The parsed AST program
1809
+ * @param names - Set of identifier names to count
1810
+ * @returns Map from identifier name to reference count
1811
+ */
1812
+ function buildReferenceCountMap(program, names) {
1813
+ if (names.size === 0) return /* @__PURE__ */ new Map();
1814
+ const counts = /* @__PURE__ */ new Map();
1815
+ const shadowDepth = /* @__PURE__ */ new Map();
1816
+ for (const name of names) {
1817
+ counts.set(name, 0);
1818
+ shadowDepth.set(name, 0);
1819
+ }
1820
+ function walk(node, parentNode, parentKey) {
1821
+ if (!node || typeof node !== "object") return;
1822
+ const nodeType = node.type;
1823
+ if (nodeType === "ImportDeclaration") return;
1824
+ const shadowedHere = [];
1825
+ if (nodeType === "FunctionDeclaration" || nodeType === "FunctionExpression" || nodeType === "ArrowFunctionExpression") {
1826
+ const params = node.params;
1827
+ if (params) {
1828
+ for (const name of names) if (params.some((p) => containsBindingName(p, name))) {
1829
+ shadowDepth.set(name, (shadowDepth.get(name) ?? 0) + 1);
1830
+ shadowedHere.push(name);
1831
+ }
1832
+ }
1833
+ }
1834
+ if (nodeType === "CatchClause") {
1835
+ const param = node.param;
1836
+ if (param) {
1837
+ for (const name of names) if (containsBindingName(param, name)) {
1838
+ shadowDepth.set(name, (shadowDepth.get(name) ?? 0) + 1);
1839
+ shadowedHere.push(name);
1840
+ }
1841
+ }
1842
+ }
1843
+ if (nodeType === "Identifier") {
1844
+ const identName = node.name;
1845
+ if (identName && names.has(identName) && (shadowDepth.get(identName) ?? 0) === 0) {
1846
+ const isMemberProperty = parentNode && parentNode.type === "MemberExpression" && parentKey === "property" && !parentNode.computed;
1847
+ const isObjectPropertyKey = parentNode && parentNode.type === "Property" && parentKey === "key" && !parentNode.shorthand && !parentNode.computed;
1848
+ if (!isMemberProperty && !isObjectPropertyKey) counts.set(identName, (counts.get(identName) ?? 0) + 1);
1849
+ }
1850
+ }
1851
+ for (const key of Object.keys(node)) {
1852
+ const child = node[key];
1853
+ if (Array.isArray(child)) child.forEach((c) => walk(c, node, key));
1854
+ else if (child && typeof child === "object") walk(child, node, key);
1855
+ }
1856
+ for (const name of shadowedHere) shadowDepth.set(name, (shadowDepth.get(name) ?? 0) - 1);
1857
+ }
1858
+ walk(program);
1859
+ return counts;
1860
+ }
1861
+ /**
1862
+ * Find the text range to remove for a dead default import.
1863
+ *
1864
+ * - Default-only import (`import wf from "..."`): returns the full declaration range.
1865
+ * - Mixed import (`import wf, { helper } from "..."`): returns the range covering
1866
+ * the default specifier and trailing comma/whitespace so the result becomes
1867
+ * `import { helper } from "..."`.
1868
+ * @param program - The parsed AST program
1869
+ * @param localName - The local name of the default import
1870
+ * @param source - The source code text (used to locate the `{` in mixed imports)
1871
+ * @returns Range to remove, or null if the import was not found
1872
+ */
1873
+ function findDefaultImportRemovalRange(program, localName, source) {
1874
+ for (const statement of program.body) {
1875
+ if (statement.type !== "ImportDeclaration") continue;
1876
+ const importDecl = statement;
1877
+ const specifiers = importDecl.specifiers || [];
1878
+ for (const spec of specifiers) {
1879
+ if (spec.type !== "ImportDefaultSpecifier") continue;
1880
+ const defaultSpec = spec;
1881
+ if (defaultSpec.local?.name !== localName) continue;
1882
+ if (specifiers.length === 1) return {
1883
+ start: importDecl.start,
1884
+ end: importDecl.end,
1885
+ isFullDeclaration: true
1886
+ };
1887
+ const braceIndex = source.indexOf("{", defaultSpec.end);
1888
+ if (braceIndex !== -1) return {
1889
+ start: defaultSpec.start,
1890
+ end: braceIndex,
1891
+ isFullDeclaration: false
1892
+ };
1893
+ return null;
1894
+ }
1895
+ }
1896
+ return null;
1897
+ }
1898
+ /**
1784
1899
  * Detect .trigger() calls for known workflows and jobs
1785
1900
  * Only detects calls where the identifier is in workflowNames or jobNames
1786
1901
  * @param program - The parsed AST program
@@ -1866,6 +1981,7 @@ function detectExtendedTriggerCalls(program, sourceText, workflowNames, jobNames
1866
1981
  function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflowFileMap, currentFilePath, authNamespace) {
1867
1982
  const { program } = parseSync("input.ts", source);
1868
1983
  const localWorkflowNameMap = new Map(workflowNameMap);
1984
+ const workflowDefaultImportNames = /* @__PURE__ */ new Set();
1869
1985
  if (workflowFileMap && currentFilePath) {
1870
1986
  const defaultImports = detectDefaultImports(program);
1871
1987
  const currentDir = currentFilePath.replace(/[/\\][^/\\]+$/, "");
@@ -1873,12 +1989,16 @@ function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflow
1873
1989
  if (!importSource.startsWith(".")) continue;
1874
1990
  const resolvedPath = resolvePath(currentDir, importSource);
1875
1991
  const workflowName = workflowFileMap.get(resolvedPath);
1876
- if (workflowName) localWorkflowNameMap.set(localName, workflowName);
1992
+ if (workflowName) {
1993
+ localWorkflowNameMap.set(localName, workflowName);
1994
+ workflowDefaultImportNames.add(localName);
1995
+ }
1877
1996
  }
1878
1997
  }
1879
1998
  const triggerCalls = detectExtendedTriggerCalls(program, source, new Set(localWorkflowNameMap.keys()), new Set(jobNameMap.keys()));
1880
1999
  const replacements = [];
1881
2000
  let needsNormalizerHelper = false;
2001
+ const transformedCallsPerIdentifier = /* @__PURE__ */ new Map();
1882
2002
  for (const call of triggerCalls) if (call.kind === "workflow" && call.authInvoker) {
1883
2003
  const workflowName = localWorkflowNameMap.get(call.identifierName);
1884
2004
  if (workflowName) {
@@ -1894,6 +2014,7 @@ function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflow
1894
2014
  end: call.callRange.end,
1895
2015
  text: transformedCall
1896
2016
  });
2017
+ transformedCallsPerIdentifier.set(call.identifierName, (transformedCallsPerIdentifier.get(call.identifierName) ?? 0) + 1);
1897
2018
  }
1898
2019
  } else if (call.kind === "job") {
1899
2020
  const jobName = jobNameMap.get(call.identifierName);
@@ -1905,6 +2026,20 @@ function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflow
1905
2026
  end: range.end,
1906
2027
  text: transformedCall
1907
2028
  });
2029
+ transformedCallsPerIdentifier.set(call.identifierName, (transformedCallsPerIdentifier.get(call.identifierName) ?? 0) + 1);
2030
+ }
2031
+ }
2032
+ const refCounts = buildReferenceCountMap(program, workflowDefaultImportNames);
2033
+ for (const localName of workflowDefaultImportNames) {
2034
+ const transformedCount = transformedCallsPerIdentifier.get(localName) ?? 0;
2035
+ const refCount = refCounts.get(localName) ?? 0;
2036
+ if (refCount === 0 || transformedCount >= refCount) {
2037
+ const removal = findDefaultImportRemovalRange(program, localName, source);
2038
+ if (removal) replacements.push({
2039
+ start: removal.start,
2040
+ end: removal.isFullDeclaration ? findStatementEnd(source, removal.end) : removal.end,
2041
+ text: ""
2042
+ });
1908
2043
  }
1909
2044
  }
1910
2045
  const transformed = applyReplacements(source, replacements);
@@ -4225,6 +4360,7 @@ function findWorkflowDefaultExport(program) {
4225
4360
  function transformWorkflowSource(source, targetJobName, targetJobExportName, otherJobExportNames, allJobsMap) {
4226
4361
  const { program } = parseSync("input.ts", source);
4227
4362
  const detectedJobs = findAllJobs(program, source);
4363
+ if (!detectedJobs.some((j) => j.name === targetJobName)) return source;
4228
4364
  const jobNameMap = allJobsMap ?? buildJobNameMap(detectedJobs);
4229
4365
  const allDeclarations = findVariableDeclarationsByName(program);
4230
4366
  const triggerCalls = detectTriggerCalls(program, source);
@@ -4301,6 +4437,15 @@ function transformWorkflowSource(source, targetJobName, targetJobExportName, oth
4301
4437
 
4302
4438
  //#endregion
4303
4439
  //#region src/cli/services/workflow/bundler.ts
4440
+ function safeRealpath(p) {
4441
+ const resolved = path.resolve(p);
4442
+ try {
4443
+ return fs$1.realpathSync(resolved);
4444
+ } catch (e) {
4445
+ logger.debug(`realpathSync failed for ${resolved}: ${e instanceof Error ? e.message : e}`);
4446
+ return resolved;
4447
+ }
4448
+ }
4304
4449
  /**
4305
4450
  * Bundle workflow jobs
4306
4451
  *
@@ -4456,14 +4601,17 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
4456
4601
  const otherJobExportNames = allJobs.filter((j) => j.name !== job.name).map((j) => j.exportName);
4457
4602
  const allJobsMap = /* @__PURE__ */ new Map();
4458
4603
  for (const j of allJobs) allJobsMap.set(j.exportName, j.name);
4604
+ const resolvedSourceFile = safeRealpath(job.sourceFile);
4459
4605
  const plugins = [{
4460
4606
  name: "workflow-transform",
4461
4607
  transform: {
4462
4608
  filter: { id: { include: [/\.ts$/, /\.js$/] } },
4463
4609
  handler(code, id) {
4464
4610
  if (!code.includes("createWorkflowJob") && !code.includes("createWorkflow") && !code.includes(".trigger(")) return null;
4465
- let transformed = transformWorkflowSource(code, job.name, job.exportName, otherJobExportNames, allJobsMap);
4611
+ let transformed = code;
4612
+ if (safeRealpath(id) === resolvedSourceFile) transformed = transformWorkflowSource(code, job.name, job.exportName, otherJobExportNames, allJobsMap);
4466
4613
  if (triggerContext && transformed.includes(".trigger(")) transformed = transformFunctionTriggers(transformed, triggerContext.workflowNameMap, triggerContext.jobNameMap, triggerContext.workflowFileMap, id, triggerContext.authNamespace);
4614
+ if (transformed === code) return null;
4467
4615
  return { code: transformed };
4468
4616
  }
4469
4617
  }
@@ -4527,10 +4675,12 @@ const RetryPolicySchema = z.object({
4527
4675
  message: "initialBackoff must be greater than 0",
4528
4676
  path: ["initialBackoff"]
4529
4677
  });
4678
+ const ConcurrencyPolicySchema = z.object({ maxConcurrentExecutions: z.number().int().min(1).max(1e3).describe("Maximum number of concurrent executions (1-1000)") });
4530
4679
  const WorkflowSchema = z.object({
4531
4680
  name: z.string().describe("Workflow name"),
4532
4681
  mainJob: WorkflowJobSchema.describe("Main job that starts the workflow"),
4533
- retryPolicy: RetryPolicySchema.optional().describe("Retry policy for the workflow")
4682
+ retryPolicy: RetryPolicySchema.optional().describe("Retry policy for the workflow"),
4683
+ concurrencyPolicy: ConcurrencyPolicySchema.optional().describe("Concurrency policy for the workflow")
4534
4684
  });
4535
4685
 
4536
4686
  //#endregion
@@ -5167,4 +5317,4 @@ async function loadApplication(params) {
5167
5317
 
5168
5318
  //#endregion
5169
5319
  export { loadWorkspaceId as C, writePlatformConfig as D, saveUserTokens as E, loadAccessToken as S, resolveTokens as T, getDistDir as _, WorkflowJobSchema as a, deleteUserTokens as b, ExecutorSchema as c, buildResolverOperationHookExpr as d, OAuth2ClientSchema as f, createBundleCache as g, loadFilesWithIgnores as h, resolveInlineSourcemap as i, INVOKER_EXPR as l, stringifyFunction as m, generatePluginFilesIfNeeded as n, ResolverSchema as o, TailorDBTypeSchema as p, loadApplication as r, createExecutorService as s, defineApplication as t, buildExecutorArgsExpr as u, hashFile as v, readPlatformConfig as w, fetchLatestToken as x, loadConfig as y };
5170
- //# sourceMappingURL=application-DkVNbIuh.mjs.map
5320
+ //# sourceMappingURL=application-7wtQzifE.mjs.map