@pikku/inspector 0.12.74 → 0.12.81
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 +347 -0
- package/dist/add/add-analytics.d.ts +9 -0
- package/dist/add/add-analytics.js +178 -0
- package/dist/add/add-auth.js +0 -54
- package/dist/add/add-feature-flag.d.ts +2 -0
- package/dist/add/add-feature-flag.js +162 -0
- package/dist/add/add-wire-addon.js +1 -0
- package/dist/add/add-wire-remote-addon.js +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/inspector.js +4 -0
- package/dist/surface/collect-surface.d.ts +58 -0
- package/dist/surface/collect-surface.js +613 -0
- package/dist/types.d.ts +20 -11
- package/dist/utils/filter-inspector-state.js +23 -13
- package/dist/utils/post-process.js +15 -0
- package/dist/utils/read-module-specifiers.d.ts +8 -0
- package/dist/utils/read-module-specifiers.js +23 -0
- package/dist/utils/read-tsconfig-out-dir.d.ts +5 -0
- package/dist/utils/read-tsconfig-out-dir.js +12 -0
- package/dist/utils/resolve-deploy-target.d.ts +7 -0
- package/dist/utils/resolve-deploy-target.js +15 -7
- package/dist/utils/serialize-inspector-state.d.ts +5 -0
- package/dist/utils/serialize-inspector-state.js +8 -0
- package/dist/visit.js +4 -0
- package/package.json +16 -6
- package/run-tests.sh +21 -6
- package/src/add/add-addon-bans.ts +0 -85
- package/src/add/add-agent-scorer.test.ts +0 -197
- package/src/add/add-agent-scorer.ts +0 -83
- package/src/add/add-agent.test.ts +0 -87
- package/src/add/add-agent.ts +0 -638
- package/src/add/add-approval-description.ts +0 -76
- package/src/add/add-auth.test.ts +0 -791
- package/src/add/add-auth.ts +0 -424
- package/src/add/add-channel.ts +0 -778
- package/src/add/add-cli-renderers.test.ts +0 -74
- package/src/add/add-cli.ts +0 -1006
- package/src/add/add-credential.ts +0 -186
- package/src/add/add-feature.test.ts +0 -306
- package/src/add/add-feature.ts +0 -253
- package/src/add/add-file-extends-core-type.ts +0 -66
- package/src/add/add-file-with-config.ts +0 -45
- package/src/add/add-file-with-factory.test.ts +0 -134
- package/src/add/add-file-with-factory.ts +0 -288
- package/src/add/add-functions.test.ts +0 -743
- package/src/add/add-functions.ts +0 -1548
- package/src/add/add-gateway.ts +0 -143
- package/src/add/add-http-route-ref.test.ts +0 -149
- package/src/add/add-http-route.ts +0 -530
- package/src/add/add-http-routes.ts +0 -471
- package/src/add/add-keyed-wiring.ts +0 -180
- package/src/add/add-mcp-prompt.ts +0 -157
- package/src/add/add-mcp-resource.ts +0 -175
- package/src/add/add-middleware.test.ts +0 -196
- package/src/add/add-middleware.ts +0 -879
- package/src/add/add-permission-auth.test.ts +0 -59
- package/src/add/add-permission.ts +0 -311
- package/src/add/add-personas.test.ts +0 -406
- package/src/add/add-personas.ts +0 -287
- package/src/add/add-queue-worker.ts +0 -117
- package/src/add/add-rpc-invocations.test.ts +0 -287
- package/src/add/add-rpc-invocations.ts +0 -221
- package/src/add/add-scenario-step.test.ts +0 -509
- package/src/add/add-schedule.ts +0 -120
- package/src/add/add-scope.test.ts +0 -419
- package/src/add/add-scope.ts +0 -221
- package/src/add/add-secret.ts +0 -10
- package/src/add/add-subject-scenario-steps.test.ts +0 -161
- package/src/add/add-system-role.test.ts +0 -297
- package/src/add/add-system-role.ts +0 -162
- package/src/add/add-trigger.ts +0 -165
- package/src/add/add-variable.ts +0 -10
- package/src/add/add-wire-addon.test.ts +0 -185
- package/src/add/add-wire-addon.ts +0 -146
- package/src/add/add-wire-remote-addon.ts +0 -80
- package/src/add/add-workflow-edge-cases.test.ts +0 -201
- package/src/add/add-workflow-fanout.test.ts +0 -166
- package/src/add/add-workflow-graph-foreach.test.ts +0 -174
- package/src/add/add-workflow-graph-input.test.ts +0 -94
- package/src/add/add-workflow-graph-notes.test.ts +0 -74
- package/src/add/add-workflow-graph.ts +0 -644
- package/src/add/add-workflow-on-error.test.ts +0 -118
- package/src/add/add-workflow-return-switch.test.ts +0 -121
- package/src/add/add-workflow-silent-drops.test.ts +0 -261
- package/src/add/add-workflow-sleep-expression.test.ts +0 -96
- package/src/add/add-workflow.test.ts +0 -155
- package/src/add/add-workflow.ts +0 -482
- package/src/add/addon-bans.test.ts +0 -121
- package/src/add/addon-contracts.test.ts +0 -221
- package/src/add/allow-escape-hatches.test.ts +0 -144
- package/src/add/audit-meta.test.ts +0 -75
- package/src/add/classified-sink-check.test.ts +0 -347
- package/src/add/config-value-metadata.test.ts +0 -263
- package/src/add/dynamic-import-check.test.ts +0 -119
- package/src/add/expect-eventually-scenario-only.test.ts +0 -108
- package/src/add/function-body-span.test.ts +0 -96
- package/src/add/inline-wiring-function.test.ts +0 -104
- package/src/add/pii-check.test.ts +0 -258
- package/src/add/rpc-type-cast.test.ts +0 -123
- package/src/add/scenario-instrumentation.test.ts +0 -89
- package/src/add/scenario-instrumentation.ts +0 -42
- package/src/add/scenario-marker.test.ts +0 -89
- package/src/add/scenario-not-extractable.test.ts +0 -159
- package/src/add/scenario-services.test.ts +0 -103
- package/src/add/scenario-skip.test.ts +0 -83
- package/src/add/validate-workflow-graph-addons.test.ts +0 -102
- package/src/add/wire-name-literal.test.ts +0 -117
- package/src/error-codes-emitted.test.ts +0 -76
- package/src/error-codes.ts +0 -145
- package/src/index.ts +0 -66
- package/src/inspector.ts +0 -575
- package/src/schema-generator.ts +0 -1
- package/src/source-file-cache.ts +0 -73
- package/src/tsconfig-paths.test.ts +0 -90
- package/src/types-map.ts +0 -141
- package/src/types.ts +0 -775
- package/src/utils/annotate-http-route-auth.test.ts +0 -161
- package/src/utils/annotate-http-route-auth.ts +0 -53
- package/src/utils/check-classified-sinks.ts +0 -215
- package/src/utils/check-pii-output.ts +0 -120
- package/src/utils/compute-diagnostics.test.ts +0 -106
- package/src/utils/compute-required-schemas.ts +0 -48
- package/src/utils/contract-hashes.test.ts +0 -553
- package/src/utils/contract-hashes.ts +0 -387
- package/src/utils/custom-types-generator.test.ts +0 -124
- package/src/utils/custom-types-generator.ts +0 -150
- package/src/utils/detect-schema-vendor.test.ts +0 -123
- package/src/utils/detect-schema-vendor.ts +0 -120
- package/src/utils/does-type-extend-core-type.ts +0 -53
- package/src/utils/ensure-function-metadata.ts +0 -385
- package/src/utils/extract-function-name.ts +0 -612
- package/src/utils/extract-function-node.ts +0 -70
- package/src/utils/extract-node-value.test.ts +0 -117
- package/src/utils/extract-node-value.ts +0 -172
- package/src/utils/extract-secret-usage.test.ts +0 -81
- package/src/utils/extract-secret-usage.ts +0 -73
- package/src/utils/extract-services.ts +0 -70
- package/src/utils/extract-surface-usage.test.ts +0 -147
- package/src/utils/extract-surface-usage.ts +0 -121
- package/src/utils/filter-inspector-state.test.ts +0 -2207
- package/src/utils/filter-inspector-state.ts +0 -1302
- package/src/utils/filter-utils.test.ts +0 -843
- package/src/utils/filter-utils.ts +0 -161
- package/src/utils/find-root-dir.ts +0 -68
- package/src/utils/find-zod-transform.test.ts +0 -70
- package/src/utils/find-zod-transform.ts +0 -103
- package/src/utils/get-exported-variable-name.ts +0 -48
- package/src/utils/get-files-and-methods.ts +0 -157
- package/src/utils/get-property-value.test.ts +0 -141
- package/src/utils/get-property-value.ts +0 -331
- package/src/utils/hash.ts +0 -26
- package/src/utils/literal-properties.ts +0 -97
- package/src/utils/load-addon-functions-meta.test.ts +0 -157
- package/src/utils/load-addon-functions-meta.ts +0 -508
- package/src/utils/load-addon-scopes.test.ts +0 -138
- package/src/utils/middleware.test.ts +0 -204
- package/src/utils/middleware.ts +0 -303
- package/src/utils/nested-project-filter.test.ts +0 -53
- package/src/utils/nested-project-filter.ts +0 -28
- package/src/utils/permissions-shorthand.test.ts +0 -79
- package/src/utils/permissions.test.ts +0 -125
- package/src/utils/permissions.ts +0 -129
- package/src/utils/post-process.test.ts +0 -1094
- package/src/utils/post-process.ts +0 -1604
- package/src/utils/resolve-addon-package.ts +0 -106
- package/src/utils/resolve-core-type.test.ts +0 -142
- package/src/utils/resolve-core-type.ts +0 -35
- package/src/utils/resolve-deploy-target.test.ts +0 -135
- package/src/utils/resolve-deploy-target.ts +0 -65
- package/src/utils/resolve-function-meta.ts +0 -25
- package/src/utils/resolve-function-types.ts +0 -42
- package/src/utils/resolve-identifier.ts +0 -46
- package/src/utils/resolve-ref-contract.ts +0 -71
- package/src/utils/resolve-versions.test.ts +0 -499
- package/src/utils/resolve-versions.ts +0 -228
- package/src/utils/schema-cache.test.ts +0 -124
- package/src/utils/schema-generator.test.ts +0 -272
- package/src/utils/schema-generator.ts +0 -780
- package/src/utils/secret-alias-services.test.ts +0 -146
- package/src/utils/secret-alias-services.ts +0 -58
- package/src/utils/serialize-inspector-state.ts +0 -742
- package/src/utils/serialize-mcp-json.ts +0 -150
- package/src/utils/serialize-middleware-groups-meta.ts +0 -36
- package/src/utils/serialize-openapi-json.ts +0 -277
- package/src/utils/serialize-permissions-groups-meta.ts +0 -7
- package/src/utils/single-declaration.ts +0 -57
- package/src/utils/type-utils.ts +0 -145
- package/src/utils/validate-auth-sessionless.ts +0 -30
- package/src/utils/validate-exposed-functions-gated.test.ts +0 -230
- package/src/utils/validate-exposed-functions-gated.ts +0 -103
- package/src/utils/validate-tags-resolve-to-middleware.test.ts +0 -108
- package/src/utils/validate-tags-resolve-to-middleware.ts +0 -48
- package/src/utils/workflow/derive-workflow-plan.test.ts +0 -178
- package/src/utils/workflow/derive-workflow-plan.ts +0 -117
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +0 -1465
- package/src/utils/workflow/dsl/deserialize-fanout-body.test.ts +0 -71
- package/src/utils/workflow/dsl/deserialize-fanout-fidelity.test.ts +0 -99
- package/src/utils/workflow/dsl/deserialize-graph-next.test.ts +0 -161
- package/src/utils/workflow/dsl/deserialize-roundtrip-bindings.test.ts +0 -121
- package/src/utils/workflow/dsl/deserialize-roundtrip-values.test.ts +0 -116
- package/src/utils/workflow/dsl/deserialize-roundtrip.test.ts +0 -145
- package/src/utils/workflow/dsl/extract-approval-policy.test.ts +0 -71
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +0 -2254
- package/src/utils/workflow/dsl/index.ts +0 -11
- package/src/utils/workflow/dsl/patterns.ts +0 -440
- package/src/utils/workflow/dsl/validation.ts +0 -203
- package/src/utils/workflow/graph/convert-dsl-to-graph-skip.test.ts +0 -35
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +0 -543
- package/src/utils/workflow/graph/fanout-node-identity.test.ts +0 -105
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +0 -310
- package/src/utils/workflow/graph/finalize-workflows.test.ts +0 -50
- package/src/utils/workflow/graph/finalize-workflows.ts +0 -130
- package/src/utils/workflow/graph/index.ts +0 -28
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +0 -240
- package/src/utils/workflow/graph/workflow-graph.types.ts +0 -281
- package/src/visit.ts +0 -181
- package/tsconfig.json +0 -19
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { strict as assert } from 'assert'
|
|
2
|
-
import { describe, test } from 'node:test'
|
|
3
|
-
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
4
|
-
import { tmpdir } from 'node:os'
|
|
5
|
-
import { join } from 'node:path'
|
|
6
|
-
import { inspect } from '../inspector.js'
|
|
7
|
-
import { ErrorCode } from '../error-codes.js'
|
|
8
|
-
import type { InspectorLogger } from '../types.js'
|
|
9
|
-
|
|
10
|
-
const makeLogger = (criticals: Array<{ code: ErrorCode; message: string }>) =>
|
|
11
|
-
({
|
|
12
|
-
debug: () => {},
|
|
13
|
-
info: () => {},
|
|
14
|
-
warn: () => {},
|
|
15
|
-
error: () => {},
|
|
16
|
-
diagnostic: ({ code, message }) => {
|
|
17
|
-
criticals.push({ code, message })
|
|
18
|
-
},
|
|
19
|
-
critical: (code: ErrorCode, message: string) => {
|
|
20
|
-
criticals.push({ code, message })
|
|
21
|
-
},
|
|
22
|
-
hasCriticalErrors: () => criticals.length > 0,
|
|
23
|
-
}) satisfies InspectorLogger
|
|
24
|
-
|
|
25
|
-
describe('addPermission — pikkuAuth', () => {
|
|
26
|
-
test('does not record a wires meta for the session parameter', async () => {
|
|
27
|
-
const rootDir = await mkdtemp(join(tmpdir(), 'pikku-auth-wires-'))
|
|
28
|
-
const file = join(rootDir, 'auth.ts')
|
|
29
|
-
|
|
30
|
-
await writeFile(
|
|
31
|
-
file,
|
|
32
|
-
[
|
|
33
|
-
'const pikkuAuth = (x: any) => x',
|
|
34
|
-
'export const isAuthenticated = pikkuAuth(async ({ logger }, session) => {',
|
|
35
|
-
' logger.info({ type: "auth-check" })',
|
|
36
|
-
' return !!session',
|
|
37
|
-
'})',
|
|
38
|
-
].join('\n')
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
const criticals: Array<{ code: ErrorCode; message: string }> = []
|
|
42
|
-
try {
|
|
43
|
-
const state = await inspect(makeLogger(criticals), [file], { rootDir })
|
|
44
|
-
const def = state.permissions.definitions['isAuthenticated']
|
|
45
|
-
assert.ok(def, 'isAuthenticated permission should be recorded')
|
|
46
|
-
// The pikkuAuth handler is (services, session) — session is NOT a wires
|
|
47
|
-
// bag and must not be flagged as a non-destructured wires parameter.
|
|
48
|
-
assert.equal(def.wires, undefined)
|
|
49
|
-
const wireDiag = (state.diagnostics ?? []).find(
|
|
50
|
-
(d) =>
|
|
51
|
-
d.code === ErrorCode.WIRES_NOT_DESTRUCTURED &&
|
|
52
|
-
d.message.includes('isAuthenticated')
|
|
53
|
-
)
|
|
54
|
-
assert.equal(wireDiag, undefined)
|
|
55
|
-
} finally {
|
|
56
|
-
await rm(rootDir, { recursive: true, force: true })
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
})
|
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
import * as ts from 'typescript'
|
|
2
|
-
import type { FunctionWiresMeta } from '@pikku/core/function'
|
|
3
|
-
import type { AddWiring } from '../types.js'
|
|
4
|
-
import { extractFunctionName } from '../utils/extract-function-name.js'
|
|
5
|
-
import {
|
|
6
|
-
extractServicesFromFunction,
|
|
7
|
-
extractUsedWires,
|
|
8
|
-
} from '../utils/extract-services.js'
|
|
9
|
-
import { getPropertyValue } from '../utils/get-property-value.js'
|
|
10
|
-
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
|
|
11
|
-
|
|
12
|
-
function isInsidePermissionContainer(node: ts.Node): boolean {
|
|
13
|
-
let current = node.parent
|
|
14
|
-
while (current) {
|
|
15
|
-
if (
|
|
16
|
-
ts.isCallExpression(current) &&
|
|
17
|
-
ts.isIdentifier(current.expression) &&
|
|
18
|
-
current.expression.text === 'pikkuPermissionFactory'
|
|
19
|
-
) {
|
|
20
|
-
return true
|
|
21
|
-
}
|
|
22
|
-
current = current.parent
|
|
23
|
-
}
|
|
24
|
-
return false
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Inspect pikkuPermission, pikkuAuth, and pikkuPermissionFactory definitions.
|
|
29
|
-
*/
|
|
30
|
-
export const addPermission: AddWiring = (logger, node, checker, state) => {
|
|
31
|
-
if (!ts.isCallExpression(node)) return
|
|
32
|
-
|
|
33
|
-
const { expression, arguments: args } = node
|
|
34
|
-
|
|
35
|
-
// only handle specific function calls
|
|
36
|
-
if (!ts.isIdentifier(expression)) {
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Handle pikkuPermission(...) - individual permission function definition
|
|
41
|
-
if (expression.text === 'pikkuPermission') {
|
|
42
|
-
// Skip if nested inside pikkuPermissionFactory — the factory handler extracts services itself
|
|
43
|
-
if (isInsidePermissionContainer(node)) return
|
|
44
|
-
|
|
45
|
-
const arg = args[0]
|
|
46
|
-
if (!arg) return
|
|
47
|
-
|
|
48
|
-
let actualHandler: ts.ArrowFunction | ts.FunctionExpression
|
|
49
|
-
let name: string | undefined
|
|
50
|
-
let description: string | undefined
|
|
51
|
-
|
|
52
|
-
if (ts.isObjectLiteralExpression(arg)) {
|
|
53
|
-
const nameValue = getPropertyValue(arg, 'name')
|
|
54
|
-
const descValue = getPropertyValue(arg, 'description')
|
|
55
|
-
name = typeof nameValue === 'string' ? nameValue : undefined
|
|
56
|
-
description = typeof descValue === 'string' ? descValue : undefined
|
|
57
|
-
|
|
58
|
-
const fnProp = getPropertyAssignmentInitializer(
|
|
59
|
-
arg,
|
|
60
|
-
'func',
|
|
61
|
-
true,
|
|
62
|
-
checker
|
|
63
|
-
)
|
|
64
|
-
if (
|
|
65
|
-
!fnProp ||
|
|
66
|
-
(!ts.isArrowFunction(fnProp) && !ts.isFunctionExpression(fnProp))
|
|
67
|
-
) {
|
|
68
|
-
logger.error(
|
|
69
|
-
`• pikkuPermission object missing required 'func' property.`
|
|
70
|
-
)
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
actualHandler = fnProp
|
|
74
|
-
} else if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
75
|
-
actualHandler = arg
|
|
76
|
-
} else {
|
|
77
|
-
logger.error(`• Handler for pikkuPermission is not a function.`)
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const services = extractServicesFromFunction(actualHandler)
|
|
82
|
-
const wires = extractUsedWires(actualHandler, 2)
|
|
83
|
-
let { pikkuFuncId, exportedName } = extractFunctionName(
|
|
84
|
-
node,
|
|
85
|
-
checker,
|
|
86
|
-
state.rootDir
|
|
87
|
-
)
|
|
88
|
-
if (pikkuFuncId.startsWith('__temp_')) {
|
|
89
|
-
if (
|
|
90
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
91
|
-
ts.isIdentifier(node.parent.name)
|
|
92
|
-
) {
|
|
93
|
-
pikkuFuncId = node.parent.name.text
|
|
94
|
-
} else if (
|
|
95
|
-
ts.isPropertyAssignment(node.parent) &&
|
|
96
|
-
ts.isIdentifier(node.parent.name)
|
|
97
|
-
) {
|
|
98
|
-
pikkuFuncId = node.parent.name.text
|
|
99
|
-
} else {
|
|
100
|
-
logger.error(
|
|
101
|
-
`• pikkuPermission() must be assigned to a variable or object property. ` +
|
|
102
|
-
`Extract it to a const: const myPermission = pikkuPermission(...)`
|
|
103
|
-
)
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const dataParam = actualHandler.parameters[1]
|
|
108
|
-
const dataParamName =
|
|
109
|
-
dataParam && ts.isIdentifier(dataParam.name) ? dataParam.name.text : null
|
|
110
|
-
const requiresData = !(dataParamName && dataParamName.startsWith('_'))
|
|
111
|
-
|
|
112
|
-
state.permissions.definitions[pikkuFuncId] = {
|
|
113
|
-
services,
|
|
114
|
-
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
115
|
-
sourceFile: node.getSourceFile().fileName,
|
|
116
|
-
position: node.getStart(),
|
|
117
|
-
exportedName,
|
|
118
|
-
name,
|
|
119
|
-
description,
|
|
120
|
-
...(requiresData ? {} : { requiresData: false }),
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
logger.debug(
|
|
124
|
-
`• Found permission with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}${!requiresData ? ' (auth-only)' : ''}`
|
|
125
|
-
)
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (expression.text === 'pikkuAuth') {
|
|
130
|
-
if (isInsidePermissionContainer(node)) return
|
|
131
|
-
|
|
132
|
-
const arg = args[0]
|
|
133
|
-
if (!arg) return
|
|
134
|
-
|
|
135
|
-
let actualHandler: ts.ArrowFunction | ts.FunctionExpression
|
|
136
|
-
let name: string | undefined
|
|
137
|
-
let description: string | undefined
|
|
138
|
-
|
|
139
|
-
if (ts.isObjectLiteralExpression(arg)) {
|
|
140
|
-
const nameValue = getPropertyValue(arg, 'name')
|
|
141
|
-
const descValue = getPropertyValue(arg, 'description')
|
|
142
|
-
name = typeof nameValue === 'string' ? nameValue : undefined
|
|
143
|
-
description = typeof descValue === 'string' ? descValue : undefined
|
|
144
|
-
|
|
145
|
-
const fnProp = getPropertyAssignmentInitializer(
|
|
146
|
-
arg,
|
|
147
|
-
'func',
|
|
148
|
-
true,
|
|
149
|
-
checker
|
|
150
|
-
)
|
|
151
|
-
if (
|
|
152
|
-
!fnProp ||
|
|
153
|
-
(!ts.isArrowFunction(fnProp) && !ts.isFunctionExpression(fnProp))
|
|
154
|
-
) {
|
|
155
|
-
logger.error(`• pikkuAuth object missing required 'func' property.`)
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
actualHandler = fnProp
|
|
159
|
-
} else if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
160
|
-
actualHandler = arg
|
|
161
|
-
} else {
|
|
162
|
-
logger.error(`• Handler for pikkuAuth is not a function.`)
|
|
163
|
-
return
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const services = extractServicesFromFunction(actualHandler)
|
|
167
|
-
// pikkuAuth's handler is (services, session) — its second parameter is the
|
|
168
|
-
// resolved user session, NOT a wires bag, so it must not be analyzed (or
|
|
169
|
-
// flagged) as a non-destructured wires parameter. pikkuAuth exposes no
|
|
170
|
-
// user-facing wires parameter.
|
|
171
|
-
const wires: FunctionWiresMeta = { optimized: true, wires: [] }
|
|
172
|
-
let { pikkuFuncId, exportedName } = extractFunctionName(
|
|
173
|
-
node,
|
|
174
|
-
checker,
|
|
175
|
-
state.rootDir
|
|
176
|
-
)
|
|
177
|
-
if (pikkuFuncId.startsWith('__temp_')) {
|
|
178
|
-
if (
|
|
179
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
180
|
-
ts.isIdentifier(node.parent.name)
|
|
181
|
-
) {
|
|
182
|
-
pikkuFuncId = node.parent.name.text
|
|
183
|
-
} else if (
|
|
184
|
-
ts.isPropertyAssignment(node.parent) &&
|
|
185
|
-
ts.isIdentifier(node.parent.name)
|
|
186
|
-
) {
|
|
187
|
-
pikkuFuncId = node.parent.name.text
|
|
188
|
-
} else {
|
|
189
|
-
logger.error(
|
|
190
|
-
`• pikkuAuth() must be assigned to a variable or object property. ` +
|
|
191
|
-
`Extract it to a const: const myAuth = pikkuAuth(...)`
|
|
192
|
-
)
|
|
193
|
-
return
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
state.permissions.definitions[pikkuFuncId] = {
|
|
197
|
-
services,
|
|
198
|
-
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
199
|
-
sourceFile: node.getSourceFile().fileName,
|
|
200
|
-
position: node.getStart(),
|
|
201
|
-
exportedName,
|
|
202
|
-
name,
|
|
203
|
-
description,
|
|
204
|
-
requiresData: false,
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
logger.debug(
|
|
208
|
-
`• Found auth permission with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`
|
|
209
|
-
)
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Handle pikkuPermissionFactory(...) - permission factory function
|
|
214
|
-
if (expression.text === 'pikkuPermissionFactory') {
|
|
215
|
-
const factoryNode = args[0]
|
|
216
|
-
if (!factoryNode) return
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
!ts.isArrowFunction(factoryNode) &&
|
|
220
|
-
!ts.isFunctionExpression(factoryNode)
|
|
221
|
-
) {
|
|
222
|
-
logger.error(`• Handler for pikkuPermissionFactory is not a function.`)
|
|
223
|
-
return
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Extract services by looking inside the factory function body
|
|
227
|
-
// The factory should return pikkuPermission(...), so we need to find that call
|
|
228
|
-
// If no wrapper is found, extract from the factory's returned function directly
|
|
229
|
-
let services = { optimized: false, services: [] as string[] }
|
|
230
|
-
let wires: ReturnType<typeof extractUsedWires> = {
|
|
231
|
-
optimized: true,
|
|
232
|
-
wires: [],
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const findPikkuPermissionCall = (
|
|
236
|
-
node: ts.Node
|
|
237
|
-
): ts.CallExpression | undefined => {
|
|
238
|
-
if (ts.isCallExpression(node)) {
|
|
239
|
-
const expr = node.expression
|
|
240
|
-
if (ts.isIdentifier(expr) && expr.text === 'pikkuPermission') {
|
|
241
|
-
return node
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return ts.forEachChild(node, findPikkuPermissionCall)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const pikkuPermissionCall = findPikkuPermissionCall(factoryNode)
|
|
248
|
-
if (pikkuPermissionCall && pikkuPermissionCall.arguments[0]) {
|
|
249
|
-
const permissionHandler = pikkuPermissionCall.arguments[0]
|
|
250
|
-
if (
|
|
251
|
-
ts.isArrowFunction(permissionHandler) ||
|
|
252
|
-
ts.isFunctionExpression(permissionHandler)
|
|
253
|
-
) {
|
|
254
|
-
services = extractServicesFromFunction(permissionHandler)
|
|
255
|
-
wires = extractUsedWires(permissionHandler, 2)
|
|
256
|
-
}
|
|
257
|
-
} else {
|
|
258
|
-
if (
|
|
259
|
-
ts.isArrowFunction(factoryNode) ||
|
|
260
|
-
ts.isFunctionExpression(factoryNode)
|
|
261
|
-
) {
|
|
262
|
-
const factoryBody = factoryNode.body
|
|
263
|
-
if (
|
|
264
|
-
ts.isArrowFunction(factoryBody) ||
|
|
265
|
-
ts.isFunctionExpression(factoryBody)
|
|
266
|
-
) {
|
|
267
|
-
services = extractServicesFromFunction(factoryBody)
|
|
268
|
-
wires = extractUsedWires(factoryBody, 2)
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
let { pikkuFuncId, exportedName } = extractFunctionName(
|
|
274
|
-
node,
|
|
275
|
-
checker,
|
|
276
|
-
state.rootDir
|
|
277
|
-
)
|
|
278
|
-
if (pikkuFuncId.startsWith('__temp_')) {
|
|
279
|
-
if (
|
|
280
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
281
|
-
ts.isIdentifier(node.parent.name)
|
|
282
|
-
) {
|
|
283
|
-
pikkuFuncId = node.parent.name.text
|
|
284
|
-
} else if (
|
|
285
|
-
ts.isPropertyAssignment(node.parent) &&
|
|
286
|
-
ts.isIdentifier(node.parent.name)
|
|
287
|
-
) {
|
|
288
|
-
pikkuFuncId = node.parent.name.text
|
|
289
|
-
} else {
|
|
290
|
-
logger.error(
|
|
291
|
-
`• pikkuPermissionFactory() must be assigned to a variable or object property. ` +
|
|
292
|
-
`Extract it to a const: const myPermission = pikkuPermissionFactory(...)`
|
|
293
|
-
)
|
|
294
|
-
return
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
state.permissions.definitions[pikkuFuncId] = {
|
|
298
|
-
services,
|
|
299
|
-
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
300
|
-
sourceFile: node.getSourceFile().fileName,
|
|
301
|
-
position: node.getStart(),
|
|
302
|
-
exportedName,
|
|
303
|
-
factory: true,
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
logger.debug(
|
|
307
|
-
`• Found permission factory with services: ${services.services.join(', ')}`
|
|
308
|
-
)
|
|
309
|
-
return
|
|
310
|
-
}
|
|
311
|
-
}
|