@pikku/inspector 0.12.0 → 0.12.2
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 +34 -0
- package/dist/add/add-ai-agent.d.ts +1 -1
- package/dist/add/add-ai-agent.js +1 -1
- package/dist/add/add-channel.js +14 -0
- package/dist/add/add-cli.d.ts +1 -1
- package/dist/add/add-cli.js +29 -8
- package/dist/add/add-file-extends-core-type.d.ts +1 -1
- package/dist/add/add-file-with-config.d.ts +1 -1
- package/dist/add/add-file-with-factory.d.ts +1 -1
- package/dist/add/add-file-with-factory.js +2 -2
- package/dist/add/add-functions.d.ts +1 -1
- package/dist/add/add-functions.js +6 -7
- package/dist/add/add-gateway.d.ts +2 -0
- package/dist/add/add-gateway.js +57 -0
- package/dist/add/add-http-route.d.ts +3 -2
- package/dist/add/add-http-route.js +5 -1
- package/dist/add/add-http-routes.d.ts +1 -1
- package/dist/add/add-http-routes.js +1 -0
- package/dist/add/add-keyed-wiring.d.ts +1 -1
- package/dist/add/add-mcp-prompt.d.ts +1 -1
- package/dist/add/add-mcp-resource.d.ts +1 -1
- package/dist/add/add-queue-worker.d.ts +1 -1
- package/dist/add/add-rpc-invocations.d.ts +3 -3
- package/dist/add/add-rpc-invocations.js +10 -10
- package/dist/add/add-schedule.d.ts +1 -1
- package/dist/add/add-secret.d.ts +1 -1
- package/dist/add/add-trigger.d.ts +1 -1
- package/dist/add/add-trigger.js +2 -2
- package/dist/add/add-wire-addon.d.ts +7 -0
- package/dist/add/add-wire-addon.js +70 -0
- package/dist/add/add-workflow.d.ts +1 -1
- package/dist/error-codes.d.ts +1 -0
- package/dist/error-codes.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +11 -4
- package/dist/types.d.ts +31 -20
- package/dist/utils/compute-required-schemas.js +1 -2
- package/dist/utils/contract-hashes.d.ts +20 -3
- package/dist/utils/contract-hashes.js +77 -10
- package/dist/utils/custom-types-generator.d.ts +1 -1
- package/dist/utils/detect-schema-vendor.d.ts +1 -1
- package/dist/utils/does-type-extend-core-type.d.ts +1 -1
- package/dist/utils/ensure-function-metadata.d.ts +1 -1
- package/dist/utils/extract-services.d.ts +1 -1
- package/dist/utils/filter-inspector-state.d.ts +1 -1
- package/dist/utils/filter-utils.d.ts +2 -2
- package/dist/utils/get-files-and-methods.d.ts +1 -1
- package/dist/utils/middleware.d.ts +2 -2
- package/dist/utils/permissions.d.ts +2 -2
- package/dist/utils/post-process.d.ts +4 -3
- package/dist/utils/post-process.js +24 -8
- package/dist/utils/resolve-addon-package.d.ts +16 -0
- package/dist/utils/{resolve-external-package.js → resolve-addon-package.js} +8 -8
- package/dist/utils/schema-generator.d.ts +2 -2
- package/dist/utils/serialize-inspector-state.d.ts +17 -3
- package/dist/utils/serialize-inspector-state.js +14 -2
- package/dist/utils/validate-auth-sessionless.d.ts +3 -0
- package/dist/utils/validate-auth-sessionless.js +14 -0
- package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
- package/dist/visit.d.ts +1 -1
- package/dist/visit.js +4 -0
- package/package.json +3 -3
- package/src/add/add-ai-agent.ts +2 -2
- package/src/add/add-channel.ts +17 -0
- package/src/add/add-cli.ts +53 -15
- package/src/add/add-file-extends-core-type.ts +1 -1
- package/src/add/add-file-with-config.ts +1 -1
- package/src/add/add-file-with-factory.ts +3 -3
- package/src/add/add-functions.ts +21 -19
- package/src/add/add-gateway.ts +95 -0
- package/src/add/add-http-route.ts +19 -2
- package/src/add/add-http-routes.ts +2 -1
- package/src/add/add-keyed-wiring.ts +1 -1
- package/src/add/add-mcp-prompt.ts +1 -1
- package/src/add/add-mcp-resource.ts +1 -1
- package/src/add/add-queue-worker.ts +1 -1
- package/src/add/add-rpc-invocations.ts +11 -11
- package/src/add/add-schedule.ts +1 -1
- package/src/add/add-secret.ts +1 -1
- package/src/add/add-trigger.ts +4 -4
- package/src/add/add-wire-addon.ts +80 -0
- package/src/add/add-workflow.ts +2 -2
- package/src/error-codes.ts +1 -0
- package/src/index.ts +1 -0
- package/src/inspector.ts +17 -5
- package/src/types.ts +38 -20
- package/src/utils/compute-required-schemas.ts +1 -2
- package/src/utils/contract-hashes.test.ts +30 -5
- package/src/utils/contract-hashes.ts +110 -14
- package/src/utils/custom-types-generator.ts +1 -1
- package/src/utils/detect-schema-vendor.ts +1 -1
- package/src/utils/does-type-extend-core-type.ts +1 -1
- package/src/utils/ensure-function-metadata.ts +1 -1
- package/src/utils/extract-services.ts +1 -1
- package/src/utils/filter-inspector-state.test.ts +3 -5
- package/src/utils/filter-inspector-state.ts +7 -2
- package/src/utils/filter-utils.test.ts +1 -1
- package/src/utils/filter-utils.ts +2 -2
- package/src/utils/get-files-and-methods.ts +1 -1
- package/src/utils/middleware.ts +2 -2
- package/src/utils/permissions.ts +2 -2
- package/src/utils/post-process.ts +34 -12
- package/src/utils/{resolve-external-package.ts → resolve-addon-package.ts} +17 -10
- package/src/utils/resolve-versions.test.ts +1 -1
- package/src/utils/schema-generator.ts +4 -4
- package/src/utils/serialize-inspector-state.ts +35 -5
- package/src/utils/validate-auth-sessionless.ts +29 -0
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +2 -2
- package/src/visit.ts +9 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/resolve-external-package.d.ts +0 -12
|
@@ -44,6 +44,10 @@ export function serializeInspectorState(state) {
|
|
|
44
44
|
files: Array.from(state.channels.files),
|
|
45
45
|
meta: state.channels.meta,
|
|
46
46
|
},
|
|
47
|
+
gateways: {
|
|
48
|
+
meta: state.gateways.meta,
|
|
49
|
+
files: Array.from(state.gateways.files),
|
|
50
|
+
},
|
|
47
51
|
triggers: {
|
|
48
52
|
meta: state.triggers.meta,
|
|
49
53
|
sourceMeta: state.triggers.sourceMeta,
|
|
@@ -70,7 +74,9 @@ export function serializeInspectorState(state) {
|
|
|
70
74
|
exposedMeta: state.rpc.exposedMeta,
|
|
71
75
|
exposedFiles: Array.from(state.rpc.exposedFiles.entries()),
|
|
72
76
|
invokedFunctions: Array.from(state.rpc.invokedFunctions),
|
|
73
|
-
|
|
77
|
+
usedAddons: Array.from(state.rpc.usedAddons),
|
|
78
|
+
wireAddonDeclarations: Array.from(state.rpc.wireAddonDeclarations.entries()),
|
|
79
|
+
wireAddonFiles: Array.from(state.rpc.wireAddonFiles),
|
|
74
80
|
},
|
|
75
81
|
mcpEndpoints: {
|
|
76
82
|
resourcesMeta: state.mcpEndpoints.resourcesMeta,
|
|
@@ -179,6 +185,10 @@ export function deserializeInspectorState(data) {
|
|
|
179
185
|
files: new Set(data.channels.files),
|
|
180
186
|
meta: data.channels.meta,
|
|
181
187
|
},
|
|
188
|
+
gateways: {
|
|
189
|
+
meta: data.gateways?.meta ?? {},
|
|
190
|
+
files: new Set(data.gateways?.files ?? []),
|
|
191
|
+
},
|
|
182
192
|
triggers: {
|
|
183
193
|
meta: data.triggers?.meta ?? {},
|
|
184
194
|
sourceMeta: data.triggers?.sourceMeta ?? {},
|
|
@@ -205,7 +215,9 @@ export function deserializeInspectorState(data) {
|
|
|
205
215
|
exposedMeta: data.rpc.exposedMeta,
|
|
206
216
|
exposedFiles: new Map(data.rpc.exposedFiles),
|
|
207
217
|
invokedFunctions: new Set(data.rpc.invokedFunctions),
|
|
208
|
-
|
|
218
|
+
usedAddons: new Set(data.rpc.usedAddons || []),
|
|
219
|
+
wireAddonDeclarations: new Map(data.rpc.wireAddonDeclarations || []),
|
|
220
|
+
wireAddonFiles: new Set(data.rpc.wireAddonFiles || []),
|
|
209
221
|
},
|
|
210
222
|
mcpEndpoints: {
|
|
211
223
|
resourcesMeta: data.mcpEndpoints.resourcesMeta,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import type { InspectorLogger, InspectorState } from '../types.js';
|
|
3
|
+
export declare function validateAuthSessionless(logger: InspectorLogger, obj: ts.ObjectLiteralExpression, state: InspectorState, funcName: string, wireDescription: string, inheritedAuth?: boolean): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getPropertyValue } from './get-property-value.js';
|
|
2
|
+
import { ErrorCode } from '../error-codes.js';
|
|
3
|
+
export function validateAuthSessionless(logger, obj, state, funcName, wireDescription, inheritedAuth) {
|
|
4
|
+
const fnMeta = state.functions.meta[funcName];
|
|
5
|
+
if (!fnMeta)
|
|
6
|
+
return true;
|
|
7
|
+
const routeAuth = getPropertyValue(obj, 'auth');
|
|
8
|
+
const resolvedAuth = routeAuth === true || routeAuth === false ? routeAuth : inheritedAuth;
|
|
9
|
+
if (resolvedAuth === false && fnMeta.sessionless === false) {
|
|
10
|
+
logger.critical(ErrorCode.AUTH_DISABLED_REQUIRES_SESSIONLESS, `${wireDescription} has auth disabled but function '${funcName}' uses pikkuFunc (requires session). Use pikkuSessionlessFunc instead.`);
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
package/dist/visit.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { InspectorState, InspectorLogger, InspectorOptions } from './types.js';
|
|
2
|
+
import type { InspectorState, InspectorLogger, InspectorOptions } from './types.js';
|
|
3
3
|
export declare const visitSetup: (logger: InspectorLogger, checker: ts.TypeChecker, node: ts.Node, state: InspectorState, options: InspectorOptions) => void;
|
|
4
4
|
export declare const visitRoutes: (logger: InspectorLogger, checker: ts.TypeChecker, node: ts.Node, state: InspectorState, options: InspectorOptions) => void;
|
package/dist/visit.js
CHANGED
|
@@ -11,7 +11,9 @@ import { addMCPResource } from './add/add-mcp-resource.js';
|
|
|
11
11
|
import { addMCPPrompt } from './add/add-mcp-prompt.js';
|
|
12
12
|
import { addFunctions } from './add/add-functions.js';
|
|
13
13
|
import { addChannel } from './add/add-channel.js';
|
|
14
|
+
import { addGateway } from './add/add-gateway.js';
|
|
14
15
|
import { addRPCInvocations } from './add/add-rpc-invocations.js';
|
|
16
|
+
import { addWireAddon } from './add/add-wire-addon.js';
|
|
15
17
|
import { addMiddleware } from './add/add-middleware.js';
|
|
16
18
|
import { addPermission } from './add/add-permission.js';
|
|
17
19
|
import { addCLI, addCLIRenderers } from './add/add-cli.js';
|
|
@@ -28,6 +30,7 @@ export const visitSetup = (logger, checker, node, state, options) => {
|
|
|
28
30
|
addFileWithFactory(node, checker, state.wireServicesFactories, 'CreateWireServices', state);
|
|
29
31
|
addFileWithFactory(node, checker, state.configFactories, 'CreateConfig');
|
|
30
32
|
addRPCInvocations(node, state, logger);
|
|
33
|
+
addWireAddon(node, state, logger);
|
|
31
34
|
addMiddleware(logger, node, checker, state, options);
|
|
32
35
|
addPermission(logger, node, checker, state, options);
|
|
33
36
|
addWorkflow(logger, node, checker, state, options);
|
|
@@ -44,6 +47,7 @@ export const visitRoutes = (logger, checker, node, state, options) => {
|
|
|
44
47
|
addTrigger(logger, node, checker, state, options);
|
|
45
48
|
addQueueWorker(logger, node, checker, state, options);
|
|
46
49
|
addChannel(logger, node, checker, state, options);
|
|
50
|
+
addGateway(logger, node, checker, state, options);
|
|
47
51
|
addCLI(logger, node, checker, state, options);
|
|
48
52
|
addCLIRenderers(logger, node, checker, state, options);
|
|
49
53
|
addMCPResource(logger, node, checker, state, options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/inspector",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"type": "module",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@openapi-contrib/json-schema-to-openapi-schema": "^4.3.1",
|
|
37
|
-
"@pikku/core": "^0.12.
|
|
37
|
+
"@pikku/core": "^0.12.2",
|
|
38
38
|
"path-to-regexp": "^8.3.0",
|
|
39
39
|
"ts-json-schema-generator": "^2.5.0",
|
|
40
40
|
"tsx": "^4.21.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"zod-to-ts": "^2.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/node": "^24.
|
|
46
|
+
"@types/node": "^24.11.0"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=18"
|
package/src/add/add-ai-agent.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getCommonWireMetaData,
|
|
5
5
|
} from '../utils/get-property-value.js'
|
|
6
6
|
import { extractWireNames } from '../utils/post-process.js'
|
|
7
|
-
import { AddWiring, InspectorLogger, SchemaRef } from '../types.js'
|
|
7
|
+
import type { AddWiring, InspectorLogger, SchemaRef } from '../types.js'
|
|
8
8
|
import {
|
|
9
9
|
extractFunctionName,
|
|
10
10
|
funcIdToTypeName,
|
|
@@ -63,7 +63,7 @@ function resolveToolReferences(
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
if (calleeName === '
|
|
66
|
+
if (calleeName === 'addon') {
|
|
67
67
|
const [firstArg] = element.arguments
|
|
68
68
|
if (firstArg && ts.isStringLiteral(firstArg)) {
|
|
69
69
|
resolved.push(firstArg.text)
|
package/src/add/add-channel.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from '../utils/middleware.js'
|
|
19
19
|
import { extractWireNames } from '../utils/post-process.js'
|
|
20
20
|
import { resolveIdentifier } from '../utils/resolve-identifier.js'
|
|
21
|
+
import { validateAuthSessionless } from '../utils/validate-auth-sessionless.js'
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Safely get the "initializer" expression of a property-like AST node:
|
|
@@ -526,6 +527,7 @@ export const addChannel: AddWiring = (
|
|
|
526
527
|
if (disabled) return
|
|
527
528
|
|
|
528
529
|
const query = getPropertyValue(obj, 'query') as string[] | []
|
|
530
|
+
const binary = getPropertyValue(obj, 'binary') as boolean | undefined
|
|
529
531
|
|
|
530
532
|
const connect = getPropertyAssignmentInitializer(
|
|
531
533
|
obj,
|
|
@@ -611,6 +613,20 @@ export const addChannel: AddWiring = (
|
|
|
611
613
|
state.serviceAggregation.usedMiddleware.add(name)
|
|
612
614
|
)
|
|
613
615
|
|
|
616
|
+
// --- validate auth/sessionless ---
|
|
617
|
+
const handlersToValidate = [
|
|
618
|
+
connectFuncId,
|
|
619
|
+
disconnectFuncId,
|
|
620
|
+
message?.pikkuFuncId,
|
|
621
|
+
].filter(Boolean) as string[]
|
|
622
|
+
for (const funcId of handlersToValidate) {
|
|
623
|
+
if (
|
|
624
|
+
!validateAuthSessionless(logger, obj, state, funcId, `Channel '${name}'`)
|
|
625
|
+
) {
|
|
626
|
+
return
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
614
630
|
state.channels.files.add(node.getSourceFile().fileName)
|
|
615
631
|
state.channels.meta[name] = {
|
|
616
632
|
name,
|
|
@@ -622,6 +638,7 @@ export const addChannel: AddWiring = (
|
|
|
622
638
|
disconnect: disconnectFuncId ? { pikkuFuncId: disconnectFuncId } : null,
|
|
623
639
|
message,
|
|
624
640
|
messageWirings,
|
|
641
|
+
binary: binary === undefined ? undefined : binary,
|
|
625
642
|
summary,
|
|
626
643
|
description,
|
|
627
644
|
errors,
|
package/src/add/add-cli.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import type { TypeChecker } from 'typescript'
|
|
2
|
+
import ts from 'typescript'
|
|
3
|
+
import type {
|
|
3
4
|
AddWiring,
|
|
4
5
|
InspectorLogger,
|
|
5
6
|
InspectorOptions,
|
|
6
7
|
InspectorState,
|
|
7
8
|
} from '../types.js'
|
|
8
|
-
import { CLIProgramMeta, CLICommandMeta } from '@pikku/core/cli'
|
|
9
|
-
import {
|
|
9
|
+
import type { CLIProgramMeta, CLICommandMeta } from '@pikku/core/cli'
|
|
10
|
+
import {
|
|
11
|
+
extractFunctionName,
|
|
12
|
+
makeContextBasedId,
|
|
13
|
+
} from '../utils/extract-function-name.js'
|
|
10
14
|
import { resolveMiddleware } from '../utils/middleware.js'
|
|
11
15
|
import { extractWireNames } from '../utils/post-process.js'
|
|
12
16
|
import { getPropertyValue } from '../utils/get-property-value.js'
|
|
13
17
|
import { resolveIdentifier } from '../utils/resolve-identifier.js'
|
|
18
|
+
import { validateAuthSessionless } from '../utils/validate-auth-sessionless.js'
|
|
14
19
|
|
|
15
20
|
// Track if we've warned about missing Config type to avoid duplicate warnings
|
|
16
21
|
const configTypeWarningShown = new Set<string>()
|
|
@@ -151,14 +156,18 @@ function processCLIConfig(
|
|
|
151
156
|
}
|
|
152
157
|
break
|
|
153
158
|
|
|
154
|
-
case 'render':
|
|
155
|
-
|
|
156
|
-
programMeta.defaultRenderName = extractFunctionName(
|
|
159
|
+
case 'render': {
|
|
160
|
+
let renderFuncId = extractFunctionName(
|
|
157
161
|
prop.initializer,
|
|
158
162
|
typeChecker,
|
|
159
163
|
inspectorState.rootDir
|
|
160
164
|
).pikkuFuncId
|
|
165
|
+
if (renderFuncId.startsWith('__temp_')) {
|
|
166
|
+
renderFuncId = makeContextBasedId('cli-render', programName)
|
|
167
|
+
}
|
|
168
|
+
programMeta.defaultRenderName = renderFuncId
|
|
161
169
|
break
|
|
170
|
+
}
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
|
|
@@ -271,12 +280,16 @@ function processCommand(
|
|
|
271
280
|
ts.isArrowFunction(node) ||
|
|
272
281
|
ts.isFunctionExpression(node)
|
|
273
282
|
) {
|
|
283
|
+
let pikkuFuncId = extractFunctionName(
|
|
284
|
+
node,
|
|
285
|
+
typeChecker,
|
|
286
|
+
inspectorState.rootDir
|
|
287
|
+
).pikkuFuncId
|
|
288
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
289
|
+
pikkuFuncId = makeContextBasedId('cli', programName, ...fullPath)
|
|
290
|
+
}
|
|
274
291
|
return {
|
|
275
|
-
pikkuFuncId
|
|
276
|
-
node,
|
|
277
|
-
typeChecker,
|
|
278
|
-
inspectorState.rootDir
|
|
279
|
-
).pikkuFuncId,
|
|
292
|
+
pikkuFuncId,
|
|
280
293
|
positionals: [],
|
|
281
294
|
options: {},
|
|
282
295
|
}
|
|
@@ -336,6 +349,9 @@ function processCommand(
|
|
|
336
349
|
typeChecker,
|
|
337
350
|
inspectorState.rootDir
|
|
338
351
|
).pikkuFuncId
|
|
352
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
353
|
+
pikkuFuncId = makeContextBasedId('cli', programName, ...fullPath)
|
|
354
|
+
}
|
|
339
355
|
meta.pikkuFuncId = pikkuFuncId
|
|
340
356
|
} else if (
|
|
341
357
|
propName === 'options' &&
|
|
@@ -391,13 +407,22 @@ function processCommand(
|
|
|
391
407
|
// Already handled in first pass
|
|
392
408
|
break
|
|
393
409
|
|
|
394
|
-
case 'render':
|
|
395
|
-
|
|
410
|
+
case 'render': {
|
|
411
|
+
let renderFuncId = extractFunctionName(
|
|
396
412
|
prop.initializer,
|
|
397
413
|
typeChecker,
|
|
398
414
|
inspectorState.rootDir
|
|
399
415
|
).pikkuFuncId
|
|
416
|
+
if (renderFuncId.startsWith('__temp_')) {
|
|
417
|
+
renderFuncId = makeContextBasedId(
|
|
418
|
+
'cli-render',
|
|
419
|
+
programName,
|
|
420
|
+
...fullPath
|
|
421
|
+
)
|
|
422
|
+
}
|
|
423
|
+
meta.renderName = renderFuncId
|
|
400
424
|
break
|
|
425
|
+
}
|
|
401
426
|
|
|
402
427
|
case 'options':
|
|
403
428
|
// Process with pikkuFuncId from first pass
|
|
@@ -453,12 +478,25 @@ function processCommand(
|
|
|
453
478
|
}
|
|
454
479
|
}
|
|
455
480
|
|
|
481
|
+
// --- validate auth/sessionless ---
|
|
482
|
+
if (
|
|
483
|
+
meta.pikkuFuncId &&
|
|
484
|
+
!validateAuthSessionless(
|
|
485
|
+
logger,
|
|
486
|
+
node,
|
|
487
|
+
inspectorState,
|
|
488
|
+
meta.pikkuFuncId,
|
|
489
|
+
`CLI command '${name}'`
|
|
490
|
+
)
|
|
491
|
+
) {
|
|
492
|
+
return null
|
|
493
|
+
}
|
|
494
|
+
|
|
456
495
|
// --- track used functions/middleware for service aggregation ---
|
|
457
496
|
inspectorState.serviceAggregation.usedFunctions.add(meta.pikkuFuncId)
|
|
458
497
|
extractWireNames(meta.middleware).forEach((name) =>
|
|
459
498
|
inspectorState.serviceAggregation.usedMiddleware.add(name)
|
|
460
499
|
)
|
|
461
|
-
// Note: subcommands are tracked recursively when they're processed
|
|
462
500
|
|
|
463
501
|
return meta
|
|
464
502
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { doesTypeExtendsCore } from '../utils/does-type-extend-core-type.js'
|
|
3
|
-
import { PathToNameAndType } from '../types.js'
|
|
3
|
+
import type { PathToNameAndType } from '../types.js'
|
|
4
4
|
|
|
5
5
|
export const addFileWithConfig = (
|
|
6
6
|
node: ts.Node,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import { PathToNameAndType, InspectorState } from '../types.js'
|
|
2
|
+
import type { PathToNameAndType, InspectorState } from '../types.js'
|
|
3
3
|
import { extractServicesFromFunction } from '../utils/extract-services.js'
|
|
4
4
|
|
|
5
5
|
// Mapping of wrapper function names to their corresponding types
|
|
6
6
|
const wrapperFunctionMap: Record<string, string> = {
|
|
7
7
|
pikkuConfig: 'CreateConfig',
|
|
8
|
-
|
|
8
|
+
pikkuAddonConfig: 'CreateConfig',
|
|
9
9
|
pikkuServices: 'CreateSingletonServices',
|
|
10
|
-
|
|
10
|
+
pikkuAddonServices: 'CreateSingletonServices',
|
|
11
11
|
pikkuWireServices: 'CreateWireServices',
|
|
12
12
|
}
|
|
13
13
|
|
package/src/add/add-functions.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import { AddWiring, SchemaRef } from '../types.js'
|
|
2
|
+
import type { AddWiring, SchemaRef } from '../types.js'
|
|
3
3
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
|
|
4
|
-
import { TypesMap } from '../types-map.js'
|
|
4
|
+
import type { TypesMap } from '../types-map.js'
|
|
5
5
|
import {
|
|
6
6
|
extractFunctionName,
|
|
7
7
|
funcIdToTypeName,
|
|
8
8
|
} from '../utils/extract-function-name.js'
|
|
9
9
|
import { extractFunctionNode } from '../utils/extract-function-node.js'
|
|
10
10
|
import { extractUsedWires } from '../utils/extract-services.js'
|
|
11
|
-
import { FunctionServicesMeta
|
|
11
|
+
import type { FunctionServicesMeta } from '@pikku/core'
|
|
12
|
+
import { formatVersionedId } from '@pikku/core'
|
|
12
13
|
import {
|
|
13
14
|
getPropertyValue,
|
|
14
15
|
getCommonWireMetaData,
|
|
@@ -216,9 +217,9 @@ const getNamesAndTypes = (
|
|
|
216
217
|
const aliasName = funcIdToTypeName(funcName) + direction
|
|
217
218
|
|
|
218
219
|
// record the alias in your TypesMap
|
|
219
|
-
const references = rawTypes
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
const references = rawTypes.flatMap((t) =>
|
|
221
|
+
resolveTypeImports(t, typesMap, true, checker)
|
|
222
|
+
)
|
|
222
223
|
|
|
223
224
|
typesMap.addCustomType(aliasName, aliasType, references)
|
|
224
225
|
|
|
@@ -229,19 +230,17 @@ const getNamesAndTypes = (
|
|
|
229
230
|
}
|
|
230
231
|
|
|
231
232
|
// 4) Single, valid name → inline it
|
|
232
|
-
const uniqueNames = rawNames
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
})
|
|
244
|
-
.flat()
|
|
233
|
+
const uniqueNames = rawNames.flatMap((name, i) => {
|
|
234
|
+
const t = rawTypes[i]
|
|
235
|
+
if (!t) {
|
|
236
|
+
throw new Error(`Expected type for name "${name}" in ${funcName}`)
|
|
237
|
+
}
|
|
238
|
+
if (isPrimitiveType(t)) {
|
|
239
|
+
return name
|
|
240
|
+
}
|
|
241
|
+
// non-primitive: import/alias it inline
|
|
242
|
+
return resolveTypeImports(t, typesMap, false, checker)
|
|
243
|
+
})
|
|
245
244
|
|
|
246
245
|
return {
|
|
247
246
|
names: uniqueNames,
|
|
@@ -339,6 +338,7 @@ export const addFunctions: AddWiring = (
|
|
|
339
338
|
let expose: boolean | undefined
|
|
340
339
|
let remote: boolean | undefined
|
|
341
340
|
let mcp: boolean | undefined
|
|
341
|
+
let readonly_: boolean | undefined
|
|
342
342
|
let requiresApproval: boolean | undefined
|
|
343
343
|
let version: number | undefined
|
|
344
344
|
let objectNode: ts.ObjectLiteralExpression | undefined
|
|
@@ -420,6 +420,7 @@ export const addFunctions: AddWiring = (
|
|
|
420
420
|
expose = getPropertyValue(firstArg, 'expose') as boolean | undefined
|
|
421
421
|
remote = getPropertyValue(firstArg, 'remote') as boolean | undefined
|
|
422
422
|
mcp = getPropertyValue(firstArg, 'mcp') as boolean | undefined
|
|
423
|
+
readonly_ = getPropertyValue(firstArg, 'readonly') as boolean | undefined
|
|
423
424
|
requiresApproval = getPropertyValue(firstArg, 'requiresApproval') as
|
|
424
425
|
| boolean
|
|
425
426
|
| undefined
|
|
@@ -757,6 +758,7 @@ export const addFunctions: AddWiring = (
|
|
|
757
758
|
expose: expose || undefined,
|
|
758
759
|
remote: remote || undefined,
|
|
759
760
|
mcp: mcpEnabled || undefined,
|
|
761
|
+
readonly: readonly_ || undefined,
|
|
760
762
|
requiresApproval: requiresApproval || undefined,
|
|
761
763
|
version,
|
|
762
764
|
title,
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as ts from 'typescript'
|
|
2
|
+
import {
|
|
3
|
+
getPropertyValue,
|
|
4
|
+
getCommonWireMetaData,
|
|
5
|
+
} from '../utils/get-property-value.js'
|
|
6
|
+
import type { AddWiring } from '../types.js'
|
|
7
|
+
import {
|
|
8
|
+
extractFunctionName,
|
|
9
|
+
makeContextBasedId,
|
|
10
|
+
} from '../utils/extract-function-name.js'
|
|
11
|
+
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
|
|
12
|
+
import { resolveMiddleware } from '../utils/middleware.js'
|
|
13
|
+
import { extractWireNames } from '../utils/post-process.js'
|
|
14
|
+
import type { GatewayTransportType } from '@pikku/core/gateway'
|
|
15
|
+
|
|
16
|
+
import { ErrorCode } from '../error-codes.js'
|
|
17
|
+
|
|
18
|
+
export const addGateway: AddWiring = (
|
|
19
|
+
logger,
|
|
20
|
+
node,
|
|
21
|
+
checker,
|
|
22
|
+
state,
|
|
23
|
+
_options
|
|
24
|
+
) => {
|
|
25
|
+
if (!ts.isCallExpression(node)) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const args = node.arguments
|
|
30
|
+
const firstArg = args[0]
|
|
31
|
+
const expression = node.expression
|
|
32
|
+
|
|
33
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'wireGateway') {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!firstArg || !ts.isObjectLiteralExpression(firstArg)) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const obj = firstArg
|
|
42
|
+
|
|
43
|
+
const nameValue = getPropertyValue(obj, 'name') as string | null
|
|
44
|
+
const typeValue = getPropertyValue(obj, 'type') as GatewayTransportType | null
|
|
45
|
+
const routeValue = getPropertyValue(obj, 'route') as string | undefined
|
|
46
|
+
const { disabled, tags, summary, description, errors } =
|
|
47
|
+
getCommonWireMetaData(obj, 'Gateway', nameValue, logger)
|
|
48
|
+
|
|
49
|
+
if (disabled) return
|
|
50
|
+
|
|
51
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
52
|
+
obj,
|
|
53
|
+
'func',
|
|
54
|
+
true,
|
|
55
|
+
checker
|
|
56
|
+
)
|
|
57
|
+
if (!funcInitializer) {
|
|
58
|
+
logger.critical(
|
|
59
|
+
ErrorCode.MISSING_FUNC,
|
|
60
|
+
`No valid 'func' property for gateway '${nameValue}'.`
|
|
61
|
+
)
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const extracted = extractFunctionName(funcInitializer, checker, state.rootDir)
|
|
66
|
+
let pikkuFuncId = extracted.pikkuFuncId
|
|
67
|
+
if (pikkuFuncId.startsWith('__temp_') && nameValue) {
|
|
68
|
+
pikkuFuncId = makeContextBasedId('gateway', nameValue)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!nameValue || !typeValue) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const middleware = resolveMiddleware(state, obj, tags, checker)
|
|
76
|
+
|
|
77
|
+
state.serviceAggregation.usedFunctions.add(pikkuFuncId)
|
|
78
|
+
extractWireNames(middleware).forEach((name) =>
|
|
79
|
+
state.serviceAggregation.usedMiddleware.add(name)
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
state.gateways.files.add(node.getSourceFile().fileName)
|
|
83
|
+
state.gateways.meta[nameValue] = {
|
|
84
|
+
pikkuFuncId,
|
|
85
|
+
name: nameValue,
|
|
86
|
+
type: typeValue,
|
|
87
|
+
route: routeValue,
|
|
88
|
+
gateway: true,
|
|
89
|
+
summary,
|
|
90
|
+
description,
|
|
91
|
+
errors,
|
|
92
|
+
tags,
|
|
93
|
+
middleware,
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getCommonWireMetaData,
|
|
5
5
|
} from '../utils/get-property-value.js'
|
|
6
6
|
import { pathToRegexp } from 'path-to-regexp'
|
|
7
|
-
import { HTTPMethod } from '@pikku/core/http'
|
|
7
|
+
import type { HTTPMethod } from '@pikku/core/http'
|
|
8
8
|
import {
|
|
9
9
|
extractFunctionName,
|
|
10
10
|
makeContextBasedId,
|
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
getPropertyAssignmentInitializer,
|
|
14
14
|
extractTypeKeys,
|
|
15
15
|
} from '../utils/type-utils.js'
|
|
16
|
-
import { AddWiring, InspectorState } from '../types.js'
|
|
16
|
+
import type { AddWiring, InspectorState } from '../types.js'
|
|
17
17
|
import { resolveHTTPMiddlewareFromObject } from '../utils/middleware.js'
|
|
18
18
|
import { resolveHTTPPermissionsFromObject } from '../utils/permissions.js'
|
|
19
19
|
import { extractWireNames } from '../utils/post-process.js'
|
|
20
20
|
import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
|
|
21
21
|
import { ErrorCode } from '../error-codes.js'
|
|
22
|
+
import { validateAuthSessionless } from '../utils/validate-auth-sessionless.js'
|
|
22
23
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
|
|
23
24
|
|
|
24
25
|
import type { InspectorLogger } from '../types.js'
|
|
@@ -34,6 +35,7 @@ export interface RegisterHTTPRouteParams {
|
|
|
34
35
|
sourceFile: ts.SourceFile
|
|
35
36
|
basePath?: string
|
|
36
37
|
inheritedTags?: string[]
|
|
38
|
+
inheritedAuth?: boolean
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
/**
|
|
@@ -140,6 +142,7 @@ export function registerHTTPRoute({
|
|
|
140
142
|
sourceFile,
|
|
141
143
|
basePath = '',
|
|
142
144
|
inheritedTags = [],
|
|
145
|
+
inheritedAuth,
|
|
143
146
|
}: RegisterHTTPRouteParams): void {
|
|
144
147
|
// Extract route path
|
|
145
148
|
const routePath = getPropertyValue(obj, 'route') as string | null
|
|
@@ -218,6 +221,20 @@ export function registerHTTPRoute({
|
|
|
218
221
|
)
|
|
219
222
|
return
|
|
220
223
|
}
|
|
224
|
+
|
|
225
|
+
if (
|
|
226
|
+
!validateAuthSessionless(
|
|
227
|
+
logger,
|
|
228
|
+
obj,
|
|
229
|
+
state,
|
|
230
|
+
funcName,
|
|
231
|
+
`Route '${fullRoute}'`,
|
|
232
|
+
inheritedAuth
|
|
233
|
+
)
|
|
234
|
+
) {
|
|
235
|
+
return
|
|
236
|
+
}
|
|
237
|
+
|
|
221
238
|
const input = fnMeta.inputs?.[0] || null
|
|
222
239
|
|
|
223
240
|
// Validate that route params and query params exist in function input type
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { getPropertyValue } from '../utils/get-property-value.js'
|
|
3
|
-
import { AddWiring, InspectorState, InspectorLogger } from '../types.js'
|
|
3
|
+
import type { AddWiring, InspectorState, InspectorLogger } from '../types.js'
|
|
4
4
|
import { registerHTTPRoute } from './add-http-route.js'
|
|
5
5
|
import { resolveIdentifier } from '../utils/resolve-identifier.js'
|
|
6
6
|
|
|
@@ -224,5 +224,6 @@ function processRoute(
|
|
|
224
224
|
sourceFile,
|
|
225
225
|
basePath: groupConfig.basePath,
|
|
226
226
|
inheritedTags: groupConfig.tags,
|
|
227
|
+
inheritedAuth: groupConfig.auth,
|
|
227
228
|
})
|
|
228
229
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { getPropertyValue } from '../utils/get-property-value.js'
|
|
3
|
-
import { AddWiring, InspectorState } from '../types.js'
|
|
3
|
+
import type { AddWiring, InspectorState } from '../types.js'
|
|
4
4
|
import { ErrorCode } from '../error-codes.js'
|
|
5
5
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
|
|
6
6
|
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from '../utils/get-property-value.js'
|
|
6
6
|
import { extractWireNames } from '../utils/post-process.js'
|
|
7
7
|
import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
|
|
8
|
-
import { AddWiring } from '../types.js'
|
|
8
|
+
import type { AddWiring } from '../types.js'
|
|
9
9
|
import {
|
|
10
10
|
extractFunctionName,
|
|
11
11
|
makeContextBasedId,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from '../utils/get-property-value.js'
|
|
6
6
|
import { extractWireNames } from '../utils/post-process.js'
|
|
7
7
|
import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
|
|
8
|
-
import { AddWiring } from '../types.js'
|
|
8
|
+
import type { AddWiring } from '../types.js'
|
|
9
9
|
import {
|
|
10
10
|
extractFunctionName,
|
|
11
11
|
makeContextBasedId,
|