@teleporthq/teleport-plugin-next-workflows 0.43.63 → 0.43.65
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/__tests__/custom-node-page-route-rewrite.test.ts +109 -0
- package/__tests__/resolve-handler-entry-name.test.ts +25 -0
- package/__tests__/state-same-run-write-then-read.test.ts +225 -0
- package/dist/cjs/nodes/analytics/commerce-tracking.d.ts +38 -2
- package/dist/cjs/nodes/analytics/commerce-tracking.d.ts.map +1 -1
- package/dist/cjs/nodes/analytics/commerce-tracking.js +41 -26
- package/dist/cjs/nodes/analytics/commerce-tracking.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-add-item.js +3 -1
- package/dist/cjs/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/cjs/nodes/types.d.ts.map +1 -1
- package/dist/cjs/nodes/types.js +19 -0
- package/dist/cjs/nodes/types.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/workflow-component-plugin.js +23 -3
- package/dist/cjs/workflow-component-plugin.js.map +1 -1
- package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
- package/dist/cjs/workflow-project-plugin.js +39 -30
- package/dist/cjs/workflow-project-plugin.js.map +1 -1
- package/dist/esm/nodes/analytics/commerce-tracking.d.ts +38 -2
- package/dist/esm/nodes/analytics/commerce-tracking.d.ts.map +1 -1
- package/dist/esm/nodes/analytics/commerce-tracking.js +41 -26
- package/dist/esm/nodes/analytics/commerce-tracking.js.map +1 -1
- package/dist/esm/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-add-item.js +3 -1
- package/dist/esm/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/esm/nodes/types.d.ts.map +1 -1
- package/dist/esm/nodes/types.js +19 -0
- package/dist/esm/nodes/types.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/workflow-component-plugin.js +23 -3
- package/dist/esm/workflow-component-plugin.js.map +1 -1
- package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
- package/dist/esm/workflow-project-plugin.js +39 -30
- package/dist/esm/workflow-project-plugin.js.map +1 -1
- package/package.json +4 -4
- package/src/nodes/analytics/commerce-tracking.ts +37 -21
- package/src/nodes/cart/cart-add-item.ts +3 -1
- package/src/nodes/types.ts +23 -0
- package/src/workflow-component-plugin.ts +23 -3
- package/src/workflow-project-plugin.ts +37 -29
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { NextWorkflowProjectPlugin } from '../src/workflow-project-plugin'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `runBefore` rewrites every `navigation-go-to-page` node's `config.pageId`
|
|
5
|
+
* from a UIDL page id to the real Next.js route. It used to walk only
|
|
6
|
+
* `workflows.workflows`, so the same node inside a shared CUSTOM NODE reached
|
|
7
|
+
* the generated `custom-nodes.js` still holding the raw page id.
|
|
8
|
+
*
|
|
9
|
+
* The runtime then fell through to `targetPage.staticUrl`, which is the
|
|
10
|
+
* mapper's best guess: it is `/home` for the home page even though Next serves
|
|
11
|
+
* it at `/`, and it keeps pointing at a page that has since been deleted. Both
|
|
12
|
+
* end on a 404, and only when the navigation came from a custom node.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const goToPage = (id: string, pageId: string, targetPage?: Record<string, unknown>) => ({
|
|
16
|
+
id,
|
|
17
|
+
type: 'navigation-go-to-page',
|
|
18
|
+
config: { pageId, ...(targetPage ? { targetPage } : {}) },
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const structure = (uidl: unknown): any => ({
|
|
22
|
+
uidl,
|
|
23
|
+
strategy: { pages: { options: {} } },
|
|
24
|
+
files: new Map(),
|
|
25
|
+
dependencies: {},
|
|
26
|
+
devDependencies: {},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const projectUidl = (): any => ({
|
|
30
|
+
name: 'Store',
|
|
31
|
+
globals: { settings: { title: 'Store' }, env: {} },
|
|
32
|
+
root: {
|
|
33
|
+
name: 'Root',
|
|
34
|
+
stateDefinitions: {
|
|
35
|
+
route: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
defaultValue: 'Home',
|
|
38
|
+
values: [
|
|
39
|
+
{ value: 'Home', pageId: 'TQ_home' },
|
|
40
|
+
{ value: 'products-list', pageId: 'TQ_products', pageOptions: { navLink: '/menu' } },
|
|
41
|
+
{ value: '404 - Not Found', pageOptions: { fallback: true } },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
node: { type: 'element', content: { elementType: 'container', children: [] } },
|
|
46
|
+
},
|
|
47
|
+
components: {},
|
|
48
|
+
workflows: {
|
|
49
|
+
workflows: {
|
|
50
|
+
wf1: {
|
|
51
|
+
id: 'wf1',
|
|
52
|
+
name: 'Go home',
|
|
53
|
+
trigger: { type: 'event-element-clicked', scope: 'page', nodeId: 't1' },
|
|
54
|
+
nodes: [goToPage('n1', 'TQ_home', { pageId: 'TQ_home', staticUrl: '/home' })],
|
|
55
|
+
edges: [],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
customNodes: {
|
|
59
|
+
cn1: {
|
|
60
|
+
id: 'cn1',
|
|
61
|
+
name: 'Require login',
|
|
62
|
+
nodes: [
|
|
63
|
+
goToPage('n2', 'TQ_home', { pageId: 'TQ_home', staticUrl: '/home' }),
|
|
64
|
+
goToPage('n3', 'TQ_products', { pageId: 'TQ_products', staticUrl: '/products-list' }),
|
|
65
|
+
],
|
|
66
|
+
edges: [],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe('runBefore — navigation-go-to-page page ids inside custom nodes', () => {
|
|
73
|
+
it('rewrites custom-node page ids to the real route, like workflow nodes', async () => {
|
|
74
|
+
const uidl = projectUidl()
|
|
75
|
+
await new NextWorkflowProjectPlugin().runBefore(structure(uidl))
|
|
76
|
+
|
|
77
|
+
const customNodes = uidl.workflows.customNodes.cn1.nodes
|
|
78
|
+
// The home page's staticUrl is '/home', but Next serves it at '/'. Leaving
|
|
79
|
+
// the raw id made the runtime prefer staticUrl and 404.
|
|
80
|
+
expect(customNodes[0].config.pageId).toBe('/')
|
|
81
|
+
expect(customNodes[1].config.pageId).toBe('/menu')
|
|
82
|
+
// Unchanged behaviour for the workflow that already worked.
|
|
83
|
+
expect(uidl.workflows.workflows.wf1.nodes[0].config.pageId).toBe('/')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// The reported scenario: every page was deleted while e-commerce stayed on,
|
|
87
|
+
// so the route map is empty and the custom node still points at a page id
|
|
88
|
+
// that resolves to nothing. It gets the same default-route treatment a
|
|
89
|
+
// workflow node has always had, instead of shipping the raw id.
|
|
90
|
+
it('sends a custom-node reference to a deleted page to the default route', async () => {
|
|
91
|
+
const uidl = projectUidl()
|
|
92
|
+
uidl.root.stateDefinitions.route = {
|
|
93
|
+
type: 'string',
|
|
94
|
+
defaultValue: '404 - Not Found',
|
|
95
|
+
values: [{ value: '404 - Not Found', pageOptions: { fallback: true } }],
|
|
96
|
+
}
|
|
97
|
+
uidl.workflows.customNodes.cn1.nodes = [goToPage('n4', 'TQ_deleted')]
|
|
98
|
+
await new NextWorkflowProjectPlugin().runBefore(structure(uidl))
|
|
99
|
+
|
|
100
|
+
expect(uidl.workflows.customNodes.cn1.nodes[0].config.pageId).toBe('/')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('does not throw for a project that has custom nodes but no workflows', async () => {
|
|
104
|
+
const uidl = projectUidl()
|
|
105
|
+
delete uidl.workflows.workflows
|
|
106
|
+
await expect(new NextWorkflowProjectPlugin().runBefore(structure(uidl))).resolves.toBeDefined()
|
|
107
|
+
expect(uidl.workflows.customNodes.cn1.nodes[0].config.pageId).toBe('/')
|
|
108
|
+
})
|
|
109
|
+
})
|
|
@@ -80,6 +80,31 @@ async function zzz(config, context) { return one_param_helper(config); }
|
|
|
80
80
|
)
|
|
81
81
|
})
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The shipped break this guards: a helper read back through
|
|
85
|
+
* `helper.toString()` had that read as its ONLY reference, so a consumer's
|
|
86
|
+
* minifier inlined the declaration and dropped the name. The concatenated
|
|
87
|
+
* handler then carried `function(e){...}` in STATEMENT position, and
|
|
88
|
+
* `next build` of the generated project failed with SWC's "Expected ident"
|
|
89
|
+
* in utils/workflows/node-handlers-client.js — visible only in a minified
|
|
90
|
+
* build, so nothing reading the unminified source could catch it.
|
|
91
|
+
*/
|
|
92
|
+
it('rejects a helper that a minifier left anonymous in statement position', () => {
|
|
93
|
+
const source = `async function cart_add_item(config) { trackCommerceStep({ name: 'add_to_cart' }); }
|
|
94
|
+
function(e){try{const t=globalThis.tpTrackCommerce;"function"==typeof t&&t(e.name,e.detail)}catch(e){}}`
|
|
95
|
+
expect(() => resolveHandlerEntryName(source, 'cart-add-item')).toThrow(
|
|
96
|
+
/anonymous function where a statement is expected/
|
|
97
|
+
)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('accepts an anonymous function that is an expression, not a statement', () => {
|
|
101
|
+
// `wrapWithGuard`'s re-declaration guard and any inline callback keep the
|
|
102
|
+
// `function` keyword off the start of a line — those are valid and common.
|
|
103
|
+
const source = `var util = typeof util !== 'undefined' ? util : function (val) { return val; };
|
|
104
|
+
async function my_node_type(config, context) { return [config].map(function (c) { return c; }); }`
|
|
105
|
+
expect(resolveHandlerEntryName(source, 'my-node-type')).toBe('my_node_type')
|
|
106
|
+
})
|
|
107
|
+
|
|
83
108
|
// Full-registry regression: every node type's generateHandler()/
|
|
84
109
|
// generateServerHandler() output must resolve to a real, callable function
|
|
85
110
|
// both normally AND after its entry function's declared name is renamed
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// A workflow that WRITES a state key and then READS it back in the same run
|
|
2
|
+
// used to get the value from before the write.
|
|
3
|
+
//
|
|
4
|
+
// `state-update-local-state` calls the React setter, which only schedules a
|
|
5
|
+
// render, and `state-get-local-state` deliberately reads `stateValuesRef`
|
|
6
|
+
// (the "latest committed" values) rather than the trigger-time snapshot. The
|
|
7
|
+
// ref is rebuilt from state on render, so between the write and the next
|
|
8
|
+
// render it still held the old value.
|
|
9
|
+
//
|
|
10
|
+
// The chat's option chips are exactly this sequence — write the chip's text
|
|
11
|
+
// into the input state, then invoke the node that reads it back — so clicking
|
|
12
|
+
// a chip re-sent the previous message, and the assistant answered the question
|
|
13
|
+
// before the one the visitor had just chosen.
|
|
14
|
+
|
|
15
|
+
import { createNextWorkflowPlugin } from '../src/workflow-component-plugin'
|
|
16
|
+
|
|
17
|
+
const extractFunctionSource = (haystack: string, funcDecl: string): string => {
|
|
18
|
+
const startIdx = haystack.indexOf(funcDecl)
|
|
19
|
+
if (startIdx === -1) {
|
|
20
|
+
throw new Error('Helper not found: ' + funcDecl)
|
|
21
|
+
}
|
|
22
|
+
let depth = 0
|
|
23
|
+
let i = haystack.indexOf('{', startIdx)
|
|
24
|
+
if (i === -1) {
|
|
25
|
+
throw new Error('No opening brace after ' + funcDecl)
|
|
26
|
+
}
|
|
27
|
+
for (; i < haystack.length; i++) {
|
|
28
|
+
const ch = haystack.charAt(i)
|
|
29
|
+
if (ch === '{') {
|
|
30
|
+
depth++
|
|
31
|
+
} else if (ch === '}') {
|
|
32
|
+
depth--
|
|
33
|
+
if (depth === 0) {
|
|
34
|
+
return haystack.slice(startIdx, i + 1)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
throw new Error('Unbalanced braces for ' + funcDecl)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const buildStructure = (): any => {
|
|
42
|
+
const workflow = {
|
|
43
|
+
id: 'wf-1',
|
|
44
|
+
name: 'Test WF',
|
|
45
|
+
trigger: {
|
|
46
|
+
type: 'event-page-loaded',
|
|
47
|
+
nodeId: 'trigger-1',
|
|
48
|
+
scope: 'page',
|
|
49
|
+
config: { pageId: 'page-1' },
|
|
50
|
+
},
|
|
51
|
+
nodes: [
|
|
52
|
+
{
|
|
53
|
+
id: 'update-1',
|
|
54
|
+
type: 'state-update-local-state',
|
|
55
|
+
config: { property: 'chatInputValue', value: 'x' },
|
|
56
|
+
stepNumber: 1,
|
|
57
|
+
label: 'X',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
edges: [{ id: 'e', source: 'trigger-1', target: 'update-1' }],
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
uidl: {
|
|
64
|
+
name: 'Page',
|
|
65
|
+
outputOptions: { pageId: 'page-1', fileName: 'page-1' },
|
|
66
|
+
node: { type: 'element', content: { elementType: 'container', name: 'Container' } },
|
|
67
|
+
stateDefinitions: {
|
|
68
|
+
chatInputValue: { type: 'string', defaultValue: '' },
|
|
69
|
+
draft: { type: 'object', defaultValue: {} },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
chunks: [
|
|
73
|
+
{
|
|
74
|
+
type: 'chunk-type-ast',
|
|
75
|
+
name: 'jsx-component',
|
|
76
|
+
content: {
|
|
77
|
+
type: 'VariableDeclaration',
|
|
78
|
+
declarations: [
|
|
79
|
+
{
|
|
80
|
+
type: 'VariableDeclarator',
|
|
81
|
+
init: {
|
|
82
|
+
type: 'ArrowFunctionExpression',
|
|
83
|
+
body: {
|
|
84
|
+
type: 'BlockStatement',
|
|
85
|
+
body: [{ type: 'ReturnStatement', argument: null }],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
options: { workflows: { workflows: { 'wf-1': workflow }, customNodes: {} } },
|
|
94
|
+
dependencies: {},
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface Harness {
|
|
99
|
+
update: (config: Record<string, unknown>, context: unknown) => Promise<unknown>
|
|
100
|
+
batchUpdate: (config: Record<string, unknown>, context: unknown) => Promise<unknown>
|
|
101
|
+
read: (config: Record<string, unknown>, context: unknown) => Promise<{ value: unknown }>
|
|
102
|
+
/** What React has actually committed — only advances on "render". */
|
|
103
|
+
committed: Record<string, unknown>
|
|
104
|
+
render: () => void
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Instantiates the emitted `__createWorkflowHandlers` against a fake React:
|
|
109
|
+
* setters record into `pending`, and the ref is only rebuilt from `pending`
|
|
110
|
+
* when `render()` is called — the timing that made the bug possible.
|
|
111
|
+
*/
|
|
112
|
+
const buildHarness = async (): Promise<Harness> => {
|
|
113
|
+
const plugin = createNextWorkflowPlugin({ isPage: true })
|
|
114
|
+
const structure = buildStructure()
|
|
115
|
+
await plugin(structure as any)
|
|
116
|
+
const moduleChunk = (structure.chunks as any[]).find((c: any) => c.name === 'workflow-module')
|
|
117
|
+
if (!moduleChunk) {
|
|
118
|
+
throw new Error('workflow-module chunk not emitted by plugin')
|
|
119
|
+
}
|
|
120
|
+
const moduleCode = String(moduleChunk.content)
|
|
121
|
+
|
|
122
|
+
// The factory returns only its trigger wiring, so capture the handler map
|
|
123
|
+
// itself at the point it is built.
|
|
124
|
+
const HANDLERS_DECL = 'const __handlers = Object.assign({}, workflowClientHandlers);'
|
|
125
|
+
const factorySource = extractFunctionSource(moduleCode, 'function __createWorkflowHandlers')
|
|
126
|
+
if (!factorySource.includes(HANDLERS_DECL)) {
|
|
127
|
+
throw new Error('handler map declaration moved; update this test')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const source = [
|
|
131
|
+
extractFunctionSource(moduleCode, 'function __resolveName'),
|
|
132
|
+
extractFunctionSource(moduleCode, 'function __defaultValueForType'),
|
|
133
|
+
extractFunctionSource(moduleCode, 'function __coerceValue'),
|
|
134
|
+
factorySource.replace(HANDLERS_DECL, HANDLERS_DECL + '\n __captureHandlers(__handlers);'),
|
|
135
|
+
'return __createWorkflowHandlers;',
|
|
136
|
+
].join('\n')
|
|
137
|
+
|
|
138
|
+
const stateTypes = { chatInputValue: 'string', draft: 'object' }
|
|
139
|
+
const committed: Record<string, unknown> = { chatInputValue: '', draft: {} }
|
|
140
|
+
const pending: Record<string, unknown> = { ...committed }
|
|
141
|
+
const stateSetters: Record<string, (v: unknown) => void> = {
|
|
142
|
+
chatInputValue: (v) => {
|
|
143
|
+
pending.chatInputValue = v
|
|
144
|
+
},
|
|
145
|
+
draft: (v) => {
|
|
146
|
+
pending.draft = v
|
|
147
|
+
},
|
|
148
|
+
}
|
|
149
|
+
// Rebuilt from committed state on every render, exactly like the emitted
|
|
150
|
+
// `__wfStateRef.current = { ... }` assignment.
|
|
151
|
+
const stateValuesRef = { current: { ...committed } }
|
|
152
|
+
|
|
153
|
+
let handlers: Record<string, (config: any, context: any) => Promise<any>> = {}
|
|
154
|
+
// `__handlers` starts as a copy of the shared client handlers; the state
|
|
155
|
+
// handlers under test are assigned over it, so an empty map is enough.
|
|
156
|
+
const factory = new Function('stateTypes', 'workflowClientHandlers', '__captureHandlers', source)(
|
|
157
|
+
stateTypes,
|
|
158
|
+
{},
|
|
159
|
+
(map: Record<string, any>) => {
|
|
160
|
+
handlers = map
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
factory(stateSetters, stateTypes, stateValuesRef)
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
update: handlers['state-update-local-state'],
|
|
167
|
+
batchUpdate: handlers['state-batch-update'],
|
|
168
|
+
read: handlers['state-get-local-state'],
|
|
169
|
+
committed,
|
|
170
|
+
render: () => {
|
|
171
|
+
Object.assign(committed, pending)
|
|
172
|
+
stateValuesRef.current = { ...committed }
|
|
173
|
+
},
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
describe('state written and read back inside one workflow run', () => {
|
|
178
|
+
it('reads the value the run just wrote, before React has re-rendered', async () => {
|
|
179
|
+
const h = await buildHarness()
|
|
180
|
+
const context = { __stateValues: { chatInputValue: 'the previous message' } }
|
|
181
|
+
|
|
182
|
+
await h.update({ property: 'chatInputValue', value: 'the message just chosen' }, context)
|
|
183
|
+
const result = await h.read({ property: 'chatInputValue' }, context)
|
|
184
|
+
|
|
185
|
+
expect(result.value).toBe('the message just chosen')
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('still reads the written value after the render lands', async () => {
|
|
189
|
+
const h = await buildHarness()
|
|
190
|
+
const context = { __stateValues: { chatInputValue: '' } }
|
|
191
|
+
|
|
192
|
+
await h.update({ property: 'chatInputValue', value: 'chosen' }, context)
|
|
193
|
+
h.render()
|
|
194
|
+
const result = await h.read({ property: 'chatInputValue' }, context)
|
|
195
|
+
|
|
196
|
+
expect(result.value).toBe('chosen')
|
|
197
|
+
// The setter really ran; the ref write is an early mirror of it, not a
|
|
198
|
+
// substitute that would leave React holding something else.
|
|
199
|
+
expect(h.committed.chatInputValue).toBe('chosen')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('applies to a batch write too', async () => {
|
|
203
|
+
const h = await buildHarness()
|
|
204
|
+
const context = { __stateValues: {} }
|
|
205
|
+
|
|
206
|
+
await h.batchUpdate({ updates: [{ key: 'chatInputValue', value: 'batched' }] }, context)
|
|
207
|
+
const result = await h.read({ property: 'chatInputValue' }, context)
|
|
208
|
+
|
|
209
|
+
expect(result.value).toBe('batched')
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it('leaves a key the page does not own to the warning path', async () => {
|
|
213
|
+
const h = await buildHarness()
|
|
214
|
+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined)
|
|
215
|
+
const context = { __stateValues: {} }
|
|
216
|
+
|
|
217
|
+
await h.update({ property: 'notOnThisPage', value: 'nope' }, context)
|
|
218
|
+
const result = await h.read({ property: 'notOnThisPage' }, context)
|
|
219
|
+
|
|
220
|
+
// No setter means no state write, so the ref must not claim otherwise.
|
|
221
|
+
expect(result.value).toBeUndefined()
|
|
222
|
+
expect(warn).toHaveBeenCalled()
|
|
223
|
+
warn.mockRestore()
|
|
224
|
+
})
|
|
225
|
+
})
|
|
@@ -32,8 +32,44 @@
|
|
|
32
32
|
* definition travels with it. `assertHandlerHasNoModuleRefs` fails the build if
|
|
33
33
|
* a module reference ever creeps back in.
|
|
34
34
|
*/
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* ⛔ A STRING LITERAL, not `someFunction.toString()`. Not a style choice.
|
|
37
|
+
*
|
|
38
|
+
* The helper used to be a real TypeScript function read back through
|
|
39
|
+
* `.toString()`. Its ONLY reference was that read, so when a consumer bundles
|
|
40
|
+
* and minifies this package (teleport-gui's browser packer worker, webpack +
|
|
41
|
+
* Terser) the minifier inlined the single-use declaration into the call site
|
|
42
|
+
* and dropped the now-pointless name:
|
|
43
|
+
*
|
|
44
|
+
* COMMERCE_TRACKING_HELPER_SOURCE = function(e){ ... }.toString()
|
|
45
|
+
*
|
|
46
|
+
* The emitted text was therefore an ANONYMOUS function expression, and every
|
|
47
|
+
* consumer of this constant appends it as a STATEMENT after a handler. A
|
|
48
|
+
* statement-position `function(e){…}` is not parseable, so `next build` of the
|
|
49
|
+
* generated project died in `utils/workflows/node-handlers-client.js` with
|
|
50
|
+
* SWC's "Expected ident" — for any store with an add-to-cart or
|
|
51
|
+
* remove-from-cart workflow, and only in a minified build, so no local run and
|
|
52
|
+
* no source-reading test could see it.
|
|
53
|
+
*
|
|
54
|
+
* A string literal is immune: a minifier never rewrites the contents of one.
|
|
55
|
+
* It also keeps the emitted name EXACTLY `trackCommerceStep`, which is the name
|
|
56
|
+
* every caller's ambient `declare function` leaves in its serialized body, so
|
|
57
|
+
* no bundler-name aliasing is needed either.
|
|
58
|
+
*
|
|
59
|
+
* ⛔ EXACTLY ONE PARAMETER, for the same reason the arity mattered before:
|
|
60
|
+
* `resolveHandlerEntryName` identifies a minified handler's entry point by
|
|
61
|
+
* ARITY, preferring a 2-param declaration because every real entry is
|
|
62
|
+
* `(config, context)`. A 2-param helper concatenated after a 1-param entry
|
|
63
|
+
* would WIN, and the generated workflow would call the tracking helper where it
|
|
64
|
+
* meant to call add-to-cart. One object parameter keeps the helper out of that
|
|
65
|
+
* contest. `resolve-handler-entry-name.test.ts` checks every registered node
|
|
66
|
+
* type against exactly this, and is what caught it.
|
|
67
|
+
*
|
|
68
|
+
* Declared with `function` (not `var f = function`) so that concatenating it
|
|
69
|
+
* after a handler stays a plain, re-declarable statement in whatever scope the
|
|
70
|
+
* emitters splice it into.
|
|
71
|
+
*/
|
|
72
|
+
export declare const COMMERCE_TRACKING_HELPER_SOURCE = "function trackCommerceStep(step) {\n try {\n var tracker = globalThis.tpTrackCommerce;\n if (typeof tracker === 'function') {\n tracker(step.name, step.detail);\n }\n } catch (err) {\n /* analytics must never break a cart or a checkout */\n }\n}";
|
|
37
73
|
/**
|
|
38
74
|
* Fails the BUILD when a serialized handler still references a module namespace.
|
|
39
75
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commerce-tracking.d.ts","sourceRoot":"","sources":["../../../../src/nodes/analytics/commerce-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;
|
|
1
|
+
{"version":3,"file":"commerce-tracking.d.ts","sourceRoot":"","sources":["../../../../src/nodes/analytics/commerce-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,+BAA+B,8QAS1C,CAAA;AAQF;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWrF"}
|
|
@@ -36,37 +36,52 @@
|
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
exports.assertHandlerHasNoModuleRefs = exports.COMMERCE_TRACKING_HELPER_SOURCE = void 0;
|
|
38
38
|
/**
|
|
39
|
-
* ⛔
|
|
39
|
+
* ⛔ A STRING LITERAL, not `someFunction.toString()`. Not a style choice.
|
|
40
40
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* where it meant to call add-to-cart.
|
|
41
|
+
* The helper used to be a real TypeScript function read back through
|
|
42
|
+
* `.toString()`. Its ONLY reference was that read, so when a consumer bundles
|
|
43
|
+
* and minifies this package (teleport-gui's browser packer worker, webpack +
|
|
44
|
+
* Terser) the minifier inlined the single-use declaration into the call site
|
|
45
|
+
* and dropped the now-pointless name:
|
|
47
46
|
*
|
|
48
|
-
*
|
|
49
|
-
* positional fallback then correctly picks the entry, which is emitted first.
|
|
50
|
-
* `resolve-handler-entry-name.test.ts` checks every registered node type against
|
|
51
|
-
* exactly this, and is what caught it.
|
|
47
|
+
* COMMERCE_TRACKING_HELPER_SOURCE = function(e){ ... }.toString()
|
|
52
48
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
49
|
+
* The emitted text was therefore an ANONYMOUS function expression, and every
|
|
50
|
+
* consumer of this constant appends it as a STATEMENT after a handler. A
|
|
51
|
+
* statement-position `function(e){…}` is not parseable, so `next build` of the
|
|
52
|
+
* generated project died in `utils/workflows/node-handlers-client.js` with
|
|
53
|
+
* SWC's "Expected ident" — for any store with an add-to-cart or
|
|
54
|
+
* remove-from-cart workflow, and only in a minified build, so no local run and
|
|
55
|
+
* no source-reading test could see it.
|
|
56
|
+
*
|
|
57
|
+
* A string literal is immune: a minifier never rewrites the contents of one.
|
|
58
|
+
* It also keeps the emitted name EXACTLY `trackCommerceStep`, which is the name
|
|
59
|
+
* every caller's ambient `declare function` leaves in its serialized body, so
|
|
60
|
+
* no bundler-name aliasing is needed either.
|
|
61
|
+
*
|
|
62
|
+
* ⛔ EXACTLY ONE PARAMETER, for the same reason the arity mattered before:
|
|
63
|
+
* `resolveHandlerEntryName` identifies a minified handler's entry point by
|
|
64
|
+
* ARITY, preferring a 2-param declaration because every real entry is
|
|
65
|
+
* `(config, context)`. A 2-param helper concatenated after a 1-param entry
|
|
66
|
+
* would WIN, and the generated workflow would call the tracking helper where it
|
|
67
|
+
* meant to call add-to-cart. One object parameter keeps the helper out of that
|
|
68
|
+
* contest. `resolve-handler-entry-name.test.ts` checks every registered node
|
|
69
|
+
* type against exactly this, and is what caught it.
|
|
70
|
+
*
|
|
71
|
+
* Declared with `function` (not `var f = function`) so that concatenating it
|
|
72
|
+
* after a handler stays a plain, re-declarable statement in whatever scope the
|
|
73
|
+
* emitters splice it into.
|
|
55
74
|
*/
|
|
56
|
-
function trackCommerceStep(step) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
tracker(step.name, step.detail);
|
|
62
|
-
}
|
|
75
|
+
exports.COMMERCE_TRACKING_HELPER_SOURCE = `function trackCommerceStep(step) {
|
|
76
|
+
try {
|
|
77
|
+
var tracker = globalThis.tpTrackCommerce;
|
|
78
|
+
if (typeof tracker === 'function') {
|
|
79
|
+
tracker(step.name, step.detail);
|
|
63
80
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
/** ES5 source of the helper, for concatenating after a serialized handler. */
|
|
69
|
-
exports.COMMERCE_TRACKING_HELPER_SOURCE = trackCommerceStep.toString();
|
|
81
|
+
} catch (err) {
|
|
82
|
+
/* analytics must never break a cart or a checkout */
|
|
83
|
+
}
|
|
84
|
+
}`;
|
|
70
85
|
/**
|
|
71
86
|
* Matches the two shapes TypeScript's CJS emit produces for a cross-module
|
|
72
87
|
* call — `(0, ns_1.fn)(…)` and a bare `ns_1.fn(…)`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commerce-tracking.js","sourceRoot":"","sources":["../../../../src/nodes/analytics/commerce-tracking.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AAEH
|
|
1
|
+
{"version":3,"file":"commerce-tracking.js","sourceRoot":"","sources":["../../../../src/nodes/analytics/commerce-tracking.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACU,QAAA,+BAA+B,GAAG;;;;;;;;;EAS7C,CAAA;AAEF;;;GAGG;AACH,MAAM,gBAAgB,GAAG,6BAA6B,CAAA;AAEtD;;;;;;;GAOG;AACH,SAAgB,4BAA4B,CAAC,MAAc,EAAE,QAAgB;IAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;IAC5C,IAAI,KAAK,EAAE;QACT,MAAM,IAAI,KAAK,CACb,QAAQ,QAAQ,8CAA8C,KAAK,CAAC,CAAC,CAAC,KAAK;YACzE,6EAA6E;YAC7E,8EAA8E;YAC9E,iCAAiC,CACpC,CAAA;KACF;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAXD,oEAWC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart-add-item.d.ts","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AAmJhE,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"cart-add-item.d.ts","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AAmJhE,eAAO,MAAM,WAAW,EAAE,oBAazB,CAAA"}
|
|
@@ -138,7 +138,9 @@ exports.cartAddItem = {
|
|
|
138
138
|
executionEnv: 'client',
|
|
139
139
|
generateHandler() {
|
|
140
140
|
// The helper is concatenated rather than imported: the handler ships as a
|
|
141
|
-
// serialized function body with no module scope.
|
|
141
|
+
// serialized function body with no module scope. It is a string literal
|
|
142
|
+
// rather than a `.toString()` so a consumer's minifier cannot strip its
|
|
143
|
+
// declaration name. See `commerce-tracking.ts`.
|
|
142
144
|
return (0, commerce_tracking_1.assertHandlerHasNoModuleRefs)((0, types_1.handlerToString)(cart_add_item) + '\n' + commerce_tracking_1.COMMERCE_TRACKING_HELPER_SOURCE, 'cart-add-item');
|
|
143
145
|
},
|
|
144
146
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart-add-item.js","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cart-add-item.js","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/F,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAErD;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/F,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAErD;AAkCD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwEhF;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,eAAe,IAAI,MAAM,CAAA;IACzB,qBAAqB,CAAC,IAAI,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB"}
|
package/dist/cjs/nodes/types.js
CHANGED
|
@@ -5,6 +5,19 @@ function handlerToString(fn) {
|
|
|
5
5
|
return fn.toString();
|
|
6
6
|
}
|
|
7
7
|
exports.handlerToString = handlerToString;
|
|
8
|
+
// A `function` keyword opening a line with no name after it: an anonymous
|
|
9
|
+
// function EXPRESSION sitting where the emitters splice a STATEMENT, which
|
|
10
|
+
// makes the whole generated handler file unparseable ("Expected ident" from
|
|
11
|
+
// SWC when the generated project builds).
|
|
12
|
+
//
|
|
13
|
+
// A minifier produces exactly this when it inlines a single-use function into
|
|
14
|
+
// the `.toString()` that reads it — `export const SRC = helper.toString()`
|
|
15
|
+
// becomes `export const SRC = function(e){…}.toString()`, and the name is gone
|
|
16
|
+
// because nothing referenced it. It is invisible to every test that reads the
|
|
17
|
+
// unminified source, and only a consumer's production bundle (teleport-gui's
|
|
18
|
+
// packer worker) is minified, so it reaches a shopper's build untouched.
|
|
19
|
+
// `commerce-tracking.ts` explains the shape a helper must use instead.
|
|
20
|
+
const ANONYMOUS_FUNCTION_STATEMENT = /(?:^|\n)[ \t]*(?:async[ \t]+)?function[ \t]*\(/;
|
|
8
21
|
// Resolves the name a handler's entry function is ACTUALLY declared with in
|
|
9
22
|
// `source`, rather than assuming it always equals the
|
|
10
23
|
// `nodeType.replace(/-/g, '_')` convention name.
|
|
@@ -24,6 +37,12 @@ exports.handlerToString = handlerToString;
|
|
|
24
37
|
// of a string literal — so the convention name is still correct for those;
|
|
25
38
|
// this only needs to look further when it's genuinely absent from `source`.
|
|
26
39
|
function resolveHandlerEntryName(source, nodeType) {
|
|
40
|
+
if (ANONYMOUS_FUNCTION_STATEMENT.test(source)) {
|
|
41
|
+
throw new Error(`The "${nodeType}" handler contains an anonymous function where a statement is ` +
|
|
42
|
+
'expected, so the generated handler file would not parse. A minifier that inlined ' +
|
|
43
|
+
'a single-use function into the `.toString()` reading it produces this; build the ' +
|
|
44
|
+
'emitted source from a string literal instead (see commerce-tracking.ts).');
|
|
45
|
+
}
|
|
27
46
|
const conventionName = nodeType.replace(/-/g, '_');
|
|
28
47
|
const conventionNameUsed = new RegExp(`(?:^|[^\\w$])${conventionName}\\s*\\(`).test(source);
|
|
29
48
|
if (conventionNameUsed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"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"}
|