@teleporthq/teleport-plugin-next-workflows 0.43.37 → 0.43.38

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.
@@ -29,6 +29,7 @@ import {
29
29
  collectUsedRealtimeActionTypes,
30
30
  } from './graph-utils'
31
31
  import { nodeRegistry } from './nodes'
32
+ import { resolveHandlerEntryName } from './nodes/types'
32
33
  import {
33
34
  generateClientRuntimeCode,
34
35
  generateServerRuntimeCode,
@@ -933,7 +934,7 @@ export class NextWorkflowProjectPlugin implements ProjectPlugin {
933
934
  const entries = exportNames
934
935
  .map((t, index) => {
935
936
  const source = handlers[index].trim()
936
- const entryFn = this.resolveHandlerEntryName(source, t)
937
+ const entryFn = resolveHandlerEntryName(source, t)
937
938
  return ` '${t}': (function () {\n${source}\nreturn ${entryFn};\n})()`
938
939
  })
939
940
  .join(',\n')
@@ -946,38 +947,6 @@ ${entries}
946
947
  `
947
948
  }
948
949
 
949
- // Resolves the name a handler's entry function is ACTUALLY declared with in
950
- // `source`, rather than assuming it always equals the
951
- // `nodeType.replace(/-/g, '_')` convention name (see the comment above
952
- // `generateNodeHandlerFile`'s `entries` for why that assumption can break
953
- // under minification).
954
- //
955
- // Handlers composed from string-literal templates (not `fn.toString()`) are
956
- // immune to that class of breakage — a minifier never rewrites the contents
957
- // of a string literal — so the convention name is still correct for those;
958
- // this only needs to look further when it's genuinely absent from `source`.
959
- private resolveHandlerEntryName(source: string, nodeType: string): string {
960
- const conventionName = nodeType.replace(/-/g, '_')
961
- const conventionNameUsed = new RegExp(`(?:^|[^\\w$])${conventionName}\\s*\\(`).test(source)
962
- if (conventionNameUsed) {
963
- return conventionName
964
- }
965
-
966
- // `source` came from `handlerToString(fn)` on a real, possibly-minified
967
- // function — its ENTIRE text is that one function's declaration, so
968
- // whatever name follows the leading `function`/`async function` keyword
969
- // is the name it was actually assigned at runtime.
970
- const leadingDeclaration = source.match(/^(?:async\s+)?function\s*([A-Za-z0-9_$]+)\s*\(/)
971
- if (leadingDeclaration) {
972
- return leadingDeclaration[1]
973
- }
974
-
975
- throw new Error(
976
- `generateNodeHandlerFile: could not resolve the entry function for workflow node type "${nodeType}" — ` +
977
- `expected a "${conventionName}" declaration or a single toString()'d function, found neither.`
978
- )
979
- }
980
-
981
950
  private getDefaultRouteUrl(uidl: ProjectUIDL, strategy: ProjectStrategy): string | null {
982
951
  const routeDef = uidl.root?.stateDefinitions?.route
983
952
  if (!routeDef?.values || !routeDef.defaultValue) {
@@ -1578,8 +1547,31 @@ module.exports = __customNodeRegistry;
1578
1547
  }
1579
1548
  })
1580
1549
 
1550
+ // See resolveHandlerEntryName: handlers built from `handlerToString(fn)`
1551
+ // on a real function (e.g. general-if-statement) can have `fn` renamed by
1552
+ // a consumer's own minifier (nothing in the bundle calls it by name, only
1553
+ // this runtime `.toString()` read does) — so the reference below must
1554
+ // match whatever `handlers[index]` actually declares, not the
1555
+ // `t.replace(/-/g, '_')` convention name.
1556
+ //
1557
+ // Each entry is ALSO isolated in its own IIFE, rather than declaring every
1558
+ // handler as a bare sibling statement inside `useGlobalWorkflows()`. Two
1559
+ // DIFFERENT node types are minified independently (each in its own
1560
+ // source file), so their real declared names can coincidentally collide —
1561
+ // e.g. state-update-local-state and payment-cancel-plan can both
1562
+ // legitimately mangle down to the same short name. Declared as siblings
1563
+ // in one shared function body, the second declaration would silently
1564
+ // shadow the first, so BOTH map entries end up pointing at the SAME
1565
+ // (wrong-for-one-of-them) function — a silent wrong-handler-executes bug,
1566
+ // not even a crash. An IIFE per entry gives every handler its own scope,
1567
+ // exactly like generateNodeHandlerFile already does, so a same-named
1568
+ // collision between two unrelated handlers can never shadow each other.
1581
1569
  const handlerEntries = emittedHandlerTypes
1582
- .map((t) => ` '${t}': ${t.replace(/-/g, '_')}`)
1570
+ .map((t, index) => {
1571
+ const source = handlers[index].trim()
1572
+ const entryFn = resolveHandlerEntryName(source, t)
1573
+ return ` '${t}': (function () {\n${source}\nreturn ${entryFn};\n})()`
1574
+ })
1583
1575
  .join(',\n')
1584
1576
 
1585
1577
  // NOTE: this module is pulled into the GLOBAL client bundle (every page,
@@ -1597,8 +1589,6 @@ import workflowRuntime from './runtime';
1597
1589
  const executeWorkflowWithSegments = workflowRuntime.executeWorkflowWithSegments;
1598
1590
 
1599
1591
  export function useGlobalWorkflows() {
1600
- ${handlers.join('\n')}
1601
-
1602
1592
  const clientNodeHandlers = {
1603
1593
  ${handlerEntries}
1604
1594
  };