@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,28 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'fs'
|
|
2
|
-
import { dirname, join } from 'path'
|
|
3
|
-
|
|
4
|
-
export const createNestedProjectFilter = (rootDir: string) => {
|
|
5
|
-
const cache = new Map<string, boolean>()
|
|
6
|
-
return (fileName: string): boolean => {
|
|
7
|
-
const pending: string[] = []
|
|
8
|
-
let dir = dirname(fileName)
|
|
9
|
-
let nested = false
|
|
10
|
-
while (dir.startsWith(rootDir) && dir !== rootDir) {
|
|
11
|
-
const cached = cache.get(dir)
|
|
12
|
-
if (cached !== undefined) {
|
|
13
|
-
nested = cached
|
|
14
|
-
break
|
|
15
|
-
}
|
|
16
|
-
pending.push(dir)
|
|
17
|
-
if (existsSync(join(dir, 'pikku.config.json'))) {
|
|
18
|
-
nested = true
|
|
19
|
-
break
|
|
20
|
-
}
|
|
21
|
-
const parent = dirname(dir)
|
|
22
|
-
if (parent === dir) break
|
|
23
|
-
dir = parent
|
|
24
|
-
}
|
|
25
|
-
for (const d of pending) cache.set(d, nested)
|
|
26
|
-
return nested
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import * as ts from 'typescript'
|
|
4
|
-
import { extractPermissionPikkuNames } from './permissions.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A checker stub. With no symbols to resolve, every reference falls back to a
|
|
8
|
-
* deterministic `__temp_` id — which is fine, because the question here is
|
|
9
|
-
* whether a declared permission is *seen*, not what it resolves to. A dropped
|
|
10
|
-
* property yields nothing at all, and that is the bug being pinned.
|
|
11
|
-
*/
|
|
12
|
-
const checker = {
|
|
13
|
-
getSymbolAtLocation: () => undefined,
|
|
14
|
-
getAliasedSymbol: () => undefined,
|
|
15
|
-
getShorthandAssignmentValueSymbol: () => undefined,
|
|
16
|
-
} as unknown as ts.TypeChecker
|
|
17
|
-
|
|
18
|
-
/** Parses `permissions: <expr>` and counts the references the inspector records. */
|
|
19
|
-
const countFor = (permissionsExpression: string): number => {
|
|
20
|
-
const file = ts.createSourceFile(
|
|
21
|
-
'fn.ts',
|
|
22
|
-
`const config = { permissions: ${permissionsExpression} }`,
|
|
23
|
-
ts.ScriptTarget.Latest,
|
|
24
|
-
true
|
|
25
|
-
)
|
|
26
|
-
let node: ts.Expression | undefined
|
|
27
|
-
const visit = (n: ts.Node) => {
|
|
28
|
-
if (
|
|
29
|
-
ts.isPropertyAssignment(n) &&
|
|
30
|
-
ts.isIdentifier(n.name) &&
|
|
31
|
-
n.name.text === 'permissions'
|
|
32
|
-
) {
|
|
33
|
-
node = n.initializer
|
|
34
|
-
}
|
|
35
|
-
ts.forEachChild(n, visit)
|
|
36
|
-
}
|
|
37
|
-
visit(file)
|
|
38
|
-
assert.ok(node, 'failed to find the permissions node')
|
|
39
|
-
return extractPermissionPikkuNames(node, checker, '/root').length
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
describe('extractPermissionPikkuNames', () => {
|
|
43
|
-
test('records a permission declared with object shorthand', () => {
|
|
44
|
-
// `permissions: { canAdminOrg }` is enforced identically to the longhand
|
|
45
|
-
// form at runtime — verifyPermissions has a non-array branch — but was
|
|
46
|
-
// dropped here, so meta reported a guarded function as carrying no
|
|
47
|
-
// permissions at all. An audit reading meta saw an open door where one
|
|
48
|
-
// was shut.
|
|
49
|
-
assert.equal(countFor('{ canAdminOrg }'), 1)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test('records the longhand form', () => {
|
|
53
|
-
assert.equal(countFor('{ org: canAdminOrg }'), 1)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('records shorthand and longhand together', () => {
|
|
57
|
-
assert.equal(countFor('{ canAdminOrg, billing: canBill }'), 2)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('records several shorthands', () => {
|
|
61
|
-
assert.equal(countFor('{ canAdminOrg, canBill }'), 2)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
test('records the array form', () => {
|
|
65
|
-
assert.equal(countFor('[canAdminOrg, canBill]'), 2)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
test('records a group whose value is an array', () => {
|
|
69
|
-
assert.equal(countFor('{ org: [canAdminOrg, canBill] }'), 2)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test('records a call expression, shorthand-adjacent', () => {
|
|
73
|
-
assert.equal(countFor('{ quota: hasEmailQuota(100) }'), 1)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
test('records nothing for an empty object', () => {
|
|
77
|
-
assert.equal(countFor('{}'), 0)
|
|
78
|
-
})
|
|
79
|
-
})
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert'
|
|
3
|
-
import { resolvePermissions } from './permissions.js'
|
|
4
|
-
import type { InspectorState } from '../types.js'
|
|
5
|
-
|
|
6
|
-
describe('resolvePermissions', () => {
|
|
7
|
-
test('should return undefined when the object declares no permissions', () => {
|
|
8
|
-
const state: InspectorState = createMockState()
|
|
9
|
-
const mockObj = createMockObjectLiteral()
|
|
10
|
-
|
|
11
|
-
const result = resolvePermissions(state, mockObj, undefined, {} as any)
|
|
12
|
-
|
|
13
|
-
assert.strictEqual(result, undefined)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test('tags no longer resolve to permissions', () => {
|
|
17
|
-
// Permissions are function-scoped only; tags are organizational and never
|
|
18
|
-
// contribute permission metadata.
|
|
19
|
-
const state: InspectorState = createMockState()
|
|
20
|
-
const mockObj = createMockObjectLiteral()
|
|
21
|
-
|
|
22
|
-
const result = resolvePermissions(
|
|
23
|
-
state,
|
|
24
|
-
mockObj,
|
|
25
|
-
['mcp', 'admin'],
|
|
26
|
-
{} as any
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
assert.strictEqual(result, undefined)
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
// Helper to create a mock TypeScript object literal expression
|
|
34
|
-
function createMockObjectLiteral(): any {
|
|
35
|
-
return {
|
|
36
|
-
properties: [],
|
|
37
|
-
kind: 206, // ObjectLiteralExpression
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Helper function to create a mock InspectorState
|
|
42
|
-
function createMockState(): InspectorState {
|
|
43
|
-
return {
|
|
44
|
-
singletonServicesTypeImportMap: new Map(),
|
|
45
|
-
wireServicesTypeImportMap: new Map(),
|
|
46
|
-
userSessionTypeImportMap: new Map(),
|
|
47
|
-
configTypeImportMap: new Map(),
|
|
48
|
-
singletonServicesFactories: new Map(),
|
|
49
|
-
wireServicesFactories: new Map(),
|
|
50
|
-
wireServicesMeta: new Map(),
|
|
51
|
-
configFactories: new Map(),
|
|
52
|
-
filesAndMethods: {},
|
|
53
|
-
filesAndMethodsErrors: new Map(),
|
|
54
|
-
typesLookup: new Map(),
|
|
55
|
-
http: {
|
|
56
|
-
metaInputTypes: new Map(),
|
|
57
|
-
meta: {
|
|
58
|
-
get: {},
|
|
59
|
-
post: {},
|
|
60
|
-
put: {},
|
|
61
|
-
delete: {},
|
|
62
|
-
head: {},
|
|
63
|
-
patch: {},
|
|
64
|
-
options: {},
|
|
65
|
-
},
|
|
66
|
-
files: new Set(),
|
|
67
|
-
routeMiddleware: new Map(),
|
|
68
|
-
},
|
|
69
|
-
functions: {
|
|
70
|
-
typesMap: {} as any,
|
|
71
|
-
meta: {},
|
|
72
|
-
files: new Map(),
|
|
73
|
-
},
|
|
74
|
-
channels: {
|
|
75
|
-
meta: {},
|
|
76
|
-
files: new Set(),
|
|
77
|
-
},
|
|
78
|
-
scheduledTasks: {
|
|
79
|
-
meta: {},
|
|
80
|
-
files: new Set(),
|
|
81
|
-
},
|
|
82
|
-
queueWorkers: {
|
|
83
|
-
meta: {},
|
|
84
|
-
files: new Set(),
|
|
85
|
-
},
|
|
86
|
-
workflows: {
|
|
87
|
-
meta: {},
|
|
88
|
-
files: new Map(),
|
|
89
|
-
graphMeta: {},
|
|
90
|
-
graphFiles: new Map(),
|
|
91
|
-
invokedWorkflows: new Set(),
|
|
92
|
-
},
|
|
93
|
-
rpc: {
|
|
94
|
-
internalMeta: {},
|
|
95
|
-
internalFiles: new Map(),
|
|
96
|
-
exposedMeta: {},
|
|
97
|
-
exposedFiles: new Map(),
|
|
98
|
-
invokedFunctions: new Set(),
|
|
99
|
-
},
|
|
100
|
-
mcpEndpoints: {
|
|
101
|
-
resourcesMeta: {},
|
|
102
|
-
toolsMeta: {},
|
|
103
|
-
promptsMeta: {},
|
|
104
|
-
files: new Set(),
|
|
105
|
-
},
|
|
106
|
-
cli: {
|
|
107
|
-
meta: {},
|
|
108
|
-
files: new Set(),
|
|
109
|
-
},
|
|
110
|
-
middleware: {
|
|
111
|
-
definitions: {},
|
|
112
|
-
instances: {},
|
|
113
|
-
tagMiddleware: new Map(),
|
|
114
|
-
},
|
|
115
|
-
channelMiddleware: {
|
|
116
|
-
definitions: {},
|
|
117
|
-
instances: {},
|
|
118
|
-
tagMiddleware: new Map(),
|
|
119
|
-
},
|
|
120
|
-
permissions: {
|
|
121
|
-
definitions: {},
|
|
122
|
-
instances: {},
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
}
|
package/src/utils/permissions.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import * as ts from 'typescript'
|
|
2
|
-
import type { PermissionMetadata } from '@pikku/core/function'
|
|
3
|
-
import { extractFunctionName } from './extract-function-name.js'
|
|
4
|
-
import type { InspectorState } from '../types.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Extract permission pikkuFuncIds from an expression (array or object literal)
|
|
8
|
-
* Resolves each identifier to its pikkuFuncId using extractFunctionName
|
|
9
|
-
* Also handles call expressions (like rolePermission({...}))
|
|
10
|
-
*
|
|
11
|
-
* Supports both formats:
|
|
12
|
-
* - Array: [permission1, permission2]
|
|
13
|
-
* - Record: { groupName: permission1, anotherGroup: [permission2, permission3] }
|
|
14
|
-
*/
|
|
15
|
-
export function extractPermissionPikkuNames(
|
|
16
|
-
node: ts.Expression,
|
|
17
|
-
checker: ts.TypeChecker,
|
|
18
|
-
rootDir: string
|
|
19
|
-
): string[] {
|
|
20
|
-
const names: string[] = []
|
|
21
|
-
|
|
22
|
-
// Helper to extract from a single element
|
|
23
|
-
const extractFromElement = (element: ts.Expression) => {
|
|
24
|
-
if (ts.isIdentifier(element)) {
|
|
25
|
-
const { pikkuFuncId } = extractFunctionName(element, checker, rootDir)
|
|
26
|
-
names.push(pikkuFuncId)
|
|
27
|
-
} else if (ts.isCallExpression(element)) {
|
|
28
|
-
// Handle call expressions like hasEmailQuota(100) or rolePermission({...})
|
|
29
|
-
// Extract the function being called (e.g., 'hasEmailQuota' from 'hasEmailQuota(100)')
|
|
30
|
-
const { pikkuFuncId } = extractFunctionName(
|
|
31
|
-
element.expression,
|
|
32
|
-
checker,
|
|
33
|
-
rootDir
|
|
34
|
-
)
|
|
35
|
-
names.push(pikkuFuncId)
|
|
36
|
-
} else if (ts.isArrayLiteralExpression(element)) {
|
|
37
|
-
// Nested array (for Record values that are arrays)
|
|
38
|
-
for (const nestedElement of element.elements) {
|
|
39
|
-
extractFromElement(nestedElement)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (ts.isArrayLiteralExpression(node)) {
|
|
45
|
-
// Array format: [permission1, permission2]
|
|
46
|
-
for (const element of node.elements) {
|
|
47
|
-
extractFromElement(element)
|
|
48
|
-
}
|
|
49
|
-
} else if (ts.isObjectLiteralExpression(node)) {
|
|
50
|
-
// Record format: { groupName: permission1, anotherGroup: [permission2] }
|
|
51
|
-
for (const prop of node.properties) {
|
|
52
|
-
if (ts.isPropertyAssignment(prop)) {
|
|
53
|
-
extractFromElement(prop.initializer)
|
|
54
|
-
} else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
55
|
-
// `permissions: { canAdminOrg }`. The runtime resolves this exactly
|
|
56
|
-
// like the longhand form — `verifyPermissions` has a non-array branch —
|
|
57
|
-
// so dropping it here reported a guarded function as having no
|
|
58
|
-
// permissions at all, which is the most dangerous direction to be wrong
|
|
59
|
-
// in: an audit reading meta sees an open door where one is shut.
|
|
60
|
-
extractFromElement(prop.name)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return names
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get permissions array from an object literal expression property
|
|
70
|
-
* Returns the initializer node for the 'permissions' property if it exists
|
|
71
|
-
*/
|
|
72
|
-
export function getPermissionsNode(
|
|
73
|
-
obj: ts.ObjectLiteralExpression
|
|
74
|
-
): ts.Expression | undefined {
|
|
75
|
-
const permissionsProp = obj.properties.find(
|
|
76
|
-
(p) =>
|
|
77
|
-
ts.isPropertyAssignment(p) &&
|
|
78
|
-
ts.isIdentifier(p.name) &&
|
|
79
|
-
p.name.text === 'permissions'
|
|
80
|
-
) as ts.PropertyAssignment | undefined
|
|
81
|
-
|
|
82
|
-
return permissionsProp?.initializer
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Resolve the explicit permission references declared on a function (or agent).
|
|
87
|
-
* Permissions are function-scoped only: a `permissions: { group: [fn] }` object
|
|
88
|
-
* is flattened to `{ type: 'wire', name }` references used at filter time.
|
|
89
|
-
* Returns undefined if none are declared, otherwise an array with ≥1 item.
|
|
90
|
-
*/
|
|
91
|
-
function resolveExplicitPermissions(
|
|
92
|
-
state: InspectorState,
|
|
93
|
-
explicitPermissionsNode: ts.Expression | undefined,
|
|
94
|
-
checker: ts.TypeChecker
|
|
95
|
-
): PermissionMetadata[] | undefined {
|
|
96
|
-
if (!explicitPermissionsNode) {
|
|
97
|
-
return undefined
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const resolved: PermissionMetadata[] = []
|
|
101
|
-
const permissionNames = extractPermissionPikkuNames(
|
|
102
|
-
explicitPermissionsNode,
|
|
103
|
-
checker,
|
|
104
|
-
state.rootDir
|
|
105
|
-
)
|
|
106
|
-
for (const name of permissionNames) {
|
|
107
|
-
const def = state.permissions.definitions[name]
|
|
108
|
-
resolved.push({
|
|
109
|
-
type: 'wire',
|
|
110
|
-
name,
|
|
111
|
-
inline: def?.exportedName === null,
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return resolved.length > 0 ? resolved : undefined
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Convenience wrapper: Extract permissions node from object and resolve
|
|
120
|
-
* Use this in add-* files for cleaner code
|
|
121
|
-
*/
|
|
122
|
-
export function resolvePermissions(
|
|
123
|
-
state: InspectorState,
|
|
124
|
-
obj: ts.ObjectLiteralExpression,
|
|
125
|
-
_tags: string[] | undefined,
|
|
126
|
-
checker: ts.TypeChecker
|
|
127
|
-
): PermissionMetadata[] | undefined {
|
|
128
|
-
return resolveExplicitPermissions(state, getPermissionsNode(obj), checker)
|
|
129
|
-
}
|