@pikku/inspector 0.12.16 → 0.12.18

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.
@@ -11,6 +11,61 @@ export function sanitizeTypeName(name: string): string {
11
11
  return name.replace(/[^a-zA-Z0-9_$]/g, '_')
12
12
  }
13
13
 
14
+ const CLASSIFICATION_WRAPPERS = new Set(['Private', 'Pii', 'Secret'])
15
+
16
+ function findMatchingAngleBracket(type: string, startIndex: number): number {
17
+ let depth = 0
18
+ for (let i = startIndex; i < type.length; i += 1) {
19
+ const char = type[i]
20
+ if (char === '<') {
21
+ depth += 1
22
+ continue
23
+ }
24
+ if (char === '>' && (i === 0 || type[i - 1] !== '=')) {
25
+ depth -= 1
26
+ if (depth === 0) {
27
+ return i
28
+ }
29
+ }
30
+ }
31
+ return -1
32
+ }
33
+
34
+ function stripClassificationWrappers(type: string): string {
35
+ let output = ''
36
+ let index = 0
37
+
38
+ while (index < type.length) {
39
+ const char = type[index]
40
+ if (!/[A-Za-z_$]/.test(char)) {
41
+ output += char
42
+ index += 1
43
+ continue
44
+ }
45
+
46
+ let end = index + 1
47
+ while (end < type.length && /[A-Za-z0-9_$]/.test(type[end])) {
48
+ end += 1
49
+ }
50
+
51
+ const identifier = type.slice(index, end)
52
+ if (CLASSIFICATION_WRAPPERS.has(identifier) && type[end] === '<') {
53
+ const closingIndex = findMatchingAngleBracket(type, end)
54
+ if (closingIndex !== -1) {
55
+ const inner = type.slice(end + 1, closingIndex)
56
+ output += stripClassificationWrappers(inner)
57
+ index = closingIndex + 1
58
+ continue
59
+ }
60
+ }
61
+
62
+ output += identifier
63
+ index = end
64
+ }
65
+
66
+ return output
67
+ }
68
+
14
69
  export function generateCustomTypes(
15
70
  typesMap: TypesMap,
16
71
  requiredTypes: Set<string>
@@ -25,12 +80,16 @@ export function generateCustomTypes(
25
80
  .map(([originalName, { type, references }]) => {
26
81
  const name = sanitizeTypeName(originalName)
27
82
  references.forEach((refName) => {
28
- if (refName !== '__object' && !refName.startsWith('__object_')) {
83
+ if (
84
+ refName !== '__object' &&
85
+ !refName.startsWith('__object_') &&
86
+ !CLASSIFICATION_WRAPPERS.has(refName)
87
+ ) {
29
88
  requiredTypes.add(refName)
30
89
  }
31
90
  })
32
91
 
33
- const typeString = type
92
+ const typeString = stripClassificationWrappers(type)
34
93
  const typeNameRegex = /\b[A-Z][a-zA-Z0-9]*\b/g
35
94
  const potentialTypes = typeString.match(typeNameRegex) || []
36
95
 
@@ -59,12 +118,13 @@ export function generateCustomTypes(
59
118
  }
60
119
  })
61
120
 
62
- if (name === type) return null
63
- return `export type ${name} = ${type}`
121
+ if (name === typeString) return null
122
+ return `export type ${name} = ${typeString}`
64
123
  })
65
124
 
66
125
  const importsByPath = new Map<string, Set<string>>()
67
126
  for (const typeName of requiredTypes) {
127
+ if (CLASSIFICATION_WRAPPERS.has(typeName)) continue
68
128
  try {
69
129
  const typeMeta = typesMap.getTypeMeta(typeName)
70
130
  if (typeMeta.path) {
@@ -1061,21 +1061,28 @@ export function filterInspectorState(
1061
1061
  filteredState.requiredSchemas = prunedSchemas
1062
1062
  }
1063
1063
 
1064
- // If any surviving function is a non-inline workflow step, the unit needs
1065
- // workflowService + queueService even though the function doesn't use them.
1066
- // Check the ORIGINAL graph meta (before filtering pruned it).
1064
+ // Step dispatch is decided purely per-function: a workflow step runs via the
1065
+ // queue only when its function opts out of inline execution (inline: false).
1066
+ // Such a unit needs workflowService + queueService injected even though the
1067
+ // function itself doesn't reference them. Check the ORIGINAL graph meta
1068
+ // (before filtering pruned it).
1067
1069
  const survivingFuncIds = new Set(Object.keys(filteredState.functions.meta))
1070
+ const resolveFuncId = (rpcName: string): string =>
1071
+ filteredState.rpc.internalMeta[rpcName] ??
1072
+ filteredState.rpc.exposedMeta[rpcName] ??
1073
+ rpcName
1068
1074
  // Use the snapshot taken before filtering
1069
1075
  for (const graph of Object.values(originalGraphMeta)) {
1070
1076
  if (!graph.nodes) continue
1071
1077
  for (const node of Object.values(graph.nodes)) {
1072
1078
  if (!('rpcName' in node) || !node.rpcName) continue
1073
1079
  const rpcName = node.rpcName as string
1074
- if (!survivingFuncIds.has(rpcName)) continue
1075
- const isInline =
1076
- (node as { options?: { async?: boolean } }).options?.async !== true &&
1077
- graph.inline === true
1078
- if (!isInline) {
1080
+ const funcId = resolveFuncId(rpcName)
1081
+ if (!survivingFuncIds.has(funcId) && !survivingFuncIds.has(rpcName))
1082
+ continue
1083
+ const funcMeta = (filteredState.functions.meta[funcId] ??
1084
+ filteredState.functions.meta[rpcName]) as { inline?: boolean }
1085
+ if (funcMeta?.inline === false) {
1079
1086
  filteredState.serviceAggregation.requiredServices.add('workflowService')
1080
1087
  filteredState.serviceAggregation.requiredServices.add('queueService')
1081
1088
  }
@@ -297,7 +297,9 @@ async function batchImportWithRegister(
297
297
  logger.debug(`tsx register() batch import failed: ${(e as Error).message}`)
298
298
  return null
299
299
  } finally {
300
- await unregister?.()
300
+ void Promise.resolve(unregister?.()).catch((e) => {
301
+ logger.debug(`tsx unregister() failed: ${(e as Error).message}`)
302
+ })
301
303
  }
302
304
  }
303
305
 
@@ -308,7 +310,7 @@ async function importWithRegister(
308
310
  try {
309
311
  return await import(sourceFile)
310
312
  } finally {
311
- await unregister()
313
+ void Promise.resolve(unregister()).catch(() => {})
312
314
  }
313
315
  }
314
316
 
@@ -6,7 +6,6 @@ import type {
6
6
  BranchStepMeta,
7
7
  ParallelGroupStepMeta,
8
8
  FanoutStepMeta,
9
- ReturnStepMeta,
10
9
  CancelStepMeta,
11
10
  SetStepMeta,
12
11
  SwitchStepMeta,
@@ -1340,11 +1339,38 @@ function extractOutputBinding(
1340
1339
  function extractReturn(
1341
1340
  statement: ts.ReturnStatement,
1342
1341
  context: ExtractionContext
1343
- ): ReturnStepMeta | null {
1342
+ ): WorkflowStepMeta | null {
1344
1343
  if (!statement.expression) {
1345
1344
  return null
1346
1345
  }
1347
1346
 
1347
+ if (
1348
+ ts.isAwaitExpression(statement.expression) &&
1349
+ ts.isCallExpression(statement.expression.expression)
1350
+ ) {
1351
+ const call = statement.expression.expression
1352
+ if (isWorkflowDoCall(call, context.checker)) {
1353
+ return isInlineDoCall(call)
1354
+ ? extractInlineStep(call, context)
1355
+ : extractRpcStep(call, context)
1356
+ }
1357
+ if (isWorkflowSleepCall(call, context.checker)) {
1358
+ return extractSleepStep(call, context)
1359
+ }
1360
+ }
1361
+
1362
+ if (ts.isCallExpression(statement.expression)) {
1363
+ const call = statement.expression
1364
+ if (isWorkflowDoCall(call, context.checker)) {
1365
+ return isInlineDoCall(call)
1366
+ ? extractInlineStep(call, context)
1367
+ : extractRpcStep(call, context)
1368
+ }
1369
+ if (isWorkflowSleepCall(call, context.checker)) {
1370
+ return extractSleepStep(call, context)
1371
+ }
1372
+ }
1373
+
1348
1374
  if (!ts.isObjectLiteralExpression(statement.expression)) {
1349
1375
  return null
1350
1376
  }
@@ -400,7 +400,6 @@ export function convertDslToGraph(
400
400
  source,
401
401
  description: meta.description,
402
402
  tags: meta.tags,
403
- inline: meta.inline,
404
403
  context: meta.context,
405
404
  nodes: nodesRecord,
406
405
  entryNodeIds,