@pikku/inspector 0.12.21 → 0.12.22
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 +20 -0
- package/dist/add/add-functions.js +16 -8
- package/dist/add/add-workflow.js +16 -2
- package/dist/error-codes.d.ts +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/inspector.js +5 -1
- package/dist/types.d.ts +10 -1
- package/dist/utils/extract-node-value.js +19 -2
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +15 -0
- package/package.json +2 -2
- package/src/add/add-auth.test.ts +3 -0
- package/src/add/add-cli-renderers.test.ts +1 -0
- package/src/add/add-functions.test.ts +13 -0
- package/src/add/add-functions.ts +14 -10
- package/src/add/add-workflow-fanout.test.ts +106 -0
- package/src/add/add-workflow.test.ts +3 -0
- package/src/add/add-workflow.ts +16 -2
- package/src/add/pii-check.test.ts +4 -0
- package/src/add/wire-name-literal.test.ts +3 -0
- package/src/error-codes.ts +14 -0
- package/src/index.ts +1 -0
- package/src/inspector.ts +8 -1
- package/src/types.ts +10 -1
- package/src/utils/extract-node-value.test.ts +49 -1
- package/src/utils/extract-node-value.ts +19 -2
- package/src/utils/filter-inspector-state.test.ts +1 -0
- package/src/utils/filter-utils.test.ts +1 -0
- package/src/utils/resolve-versions.test.ts +1 -0
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +16 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { test, describe } from 'node:test'
|
|
2
2
|
import { strict as assert } from 'node:assert'
|
|
3
3
|
import * as ts from 'typescript'
|
|
4
|
-
import { extractDescription } from './extract-node-value'
|
|
4
|
+
import { extractDescription, extractStringLiteral } from './extract-node-value'
|
|
5
5
|
|
|
6
6
|
const createChecker = (source: string) => {
|
|
7
7
|
const sourceFile = ts.createSourceFile(
|
|
@@ -67,3 +67,51 @@ describe('extractDescription', () => {
|
|
|
67
67
|
assert.equal(extractDescription(sourceFile, checker), null)
|
|
68
68
|
})
|
|
69
69
|
})
|
|
70
|
+
|
|
71
|
+
describe('extractStringLiteral — concatenation/template symmetry', () => {
|
|
72
|
+
const findInitializer = (node: ts.Node): ts.Expression | undefined => {
|
|
73
|
+
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
74
|
+
return node.initializer
|
|
75
|
+
}
|
|
76
|
+
let result: ts.Expression | undefined
|
|
77
|
+
ts.forEachChild(node, (child) => {
|
|
78
|
+
if (!result) result = findInitializer(child)
|
|
79
|
+
})
|
|
80
|
+
return result
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
test('a `+` operand that cannot be statically resolved becomes a ${...} placeholder', () => {
|
|
84
|
+
const { checker, sourceFile } = createChecker(
|
|
85
|
+
`const x = 'Enrich event ' + (event.id ?? event.name)`
|
|
86
|
+
)
|
|
87
|
+
const init = findInitializer(sourceFile)!
|
|
88
|
+
assert.equal(
|
|
89
|
+
extractStringLiteral(init, checker),
|
|
90
|
+
'Enrich event ${event.id ?? event.name}'
|
|
91
|
+
)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test('`+` concatenation and template literal produce the same display string', () => {
|
|
95
|
+
const concat = createChecker(
|
|
96
|
+
`const x = 'Enrich event ' + (event.id ?? event.name)`
|
|
97
|
+
)
|
|
98
|
+
const template = createChecker(
|
|
99
|
+
'const x = `Enrich event ${event.id ?? event.name}`'
|
|
100
|
+
)
|
|
101
|
+
const concatValue = extractStringLiteral(
|
|
102
|
+
findInitializer(concat.sourceFile)!,
|
|
103
|
+
concat.checker
|
|
104
|
+
)
|
|
105
|
+
const templateValue = extractStringLiteral(
|
|
106
|
+
findInitializer(template.sourceFile)!,
|
|
107
|
+
template.checker
|
|
108
|
+
)
|
|
109
|
+
assert.equal(concatValue, templateValue)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('still resolves fully-static concatenation exactly', () => {
|
|
113
|
+
const { checker, sourceFile } = createChecker(`const x = 'a' + 'b' + 'c'`)
|
|
114
|
+
const init = findInitializer(sourceFile)!
|
|
115
|
+
assert.equal(extractStringLiteral(init, checker), 'abc')
|
|
116
|
+
})
|
|
117
|
+
})
|
|
@@ -37,8 +37,8 @@ export function extractStringLiteral(
|
|
|
37
37
|
node.operatorToken.kind === ts.SyntaxKind.PlusToken
|
|
38
38
|
) {
|
|
39
39
|
return (
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
extractConcatOperand(node.left, checker) +
|
|
41
|
+
extractConcatOperand(node.right, checker)
|
|
42
42
|
)
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -59,6 +59,23 @@ export function extractStringLiteral(
|
|
|
59
59
|
throw new Error('Unable to extract string literal from node')
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Resolve one operand of a `+` string concatenation.
|
|
64
|
+
*
|
|
65
|
+
* An operand that can't be statically resolved (e.g. `a ?? b`) becomes a
|
|
66
|
+
* `${...}` placeholder rather than throwing — mirroring the TemplateExpression
|
|
67
|
+
* branch above, so `'x ' + expr` and `` `x ${expr}` `` produce the same string.
|
|
68
|
+
* This keeps an unresolvable display name from aborting the whole extraction.
|
|
69
|
+
*/
|
|
70
|
+
function extractConcatOperand(node: ts.Node, checker: ts.TypeChecker): string {
|
|
71
|
+
try {
|
|
72
|
+
return extractStringLiteral(node, checker)
|
|
73
|
+
} catch {
|
|
74
|
+
const inner = ts.isParenthesizedExpression(node) ? node.expression : node
|
|
75
|
+
return '${' + inner.getText() + '}'
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
62
79
|
/**
|
|
63
80
|
* Check if node is string-like (string literal or template expression)
|
|
64
81
|
*/
|
|
@@ -386,6 +386,22 @@ function extractVariableDeclaration(
|
|
|
386
386
|
return step
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
+
|
|
390
|
+
// Promise.all fanout/group captured into a variable
|
|
391
|
+
// (const results = await Promise.all(array.map(...)))
|
|
392
|
+
if (isParallelFanout(call) || isParallelGroup(call)) {
|
|
393
|
+
const step = isParallelFanout(call)
|
|
394
|
+
? extractParallelFanout(call, context)
|
|
395
|
+
: extractParallelGroup(call, context)
|
|
396
|
+
if (step) {
|
|
397
|
+
const type = context.checker.getTypeAtLocation(decl)
|
|
398
|
+
context.outputVars.set(varName, { type, node: decl })
|
|
399
|
+
if (isArrayType(type, context.checker)) {
|
|
400
|
+
context.arrayVars.add(varName)
|
|
401
|
+
}
|
|
402
|
+
return step
|
|
403
|
+
}
|
|
404
|
+
}
|
|
389
405
|
}
|
|
390
406
|
|
|
391
407
|
// Check for array.filter(...)
|