@pikku/inspector 0.12.103 → 0.12.107
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/dist/add/add-auth.d.ts +1 -9
- package/dist/add/add-auth.js +64 -17
- package/dist/add/add-cli.js +25 -11
- package/dist/add/add-functions.js +35 -39
- package/dist/add/add-keyed-wiring.js +22 -2
- package/dist/add/add-middleware.js +17 -16
- package/dist/add/add-permission.d.ts +0 -3
- package/dist/add/add-permission.js +213 -22
- package/dist/add/add-scope.d.ts +1 -7
- package/dist/add/add-scope.js +1 -21
- package/dist/add/add-virtual-users.d.ts +13 -0
- package/dist/add/{add-personas.js → add-virtual-users.js} +33 -33
- package/dist/add/add-workflow.js +14 -10
- package/dist/add/check-indirect-registrations.d.ts +9 -0
- package/dist/add/check-indirect-registrations.js +114 -0
- package/dist/error-codes.d.ts +5 -3
- package/dist/error-codes.js +5 -3
- package/dist/finalize.d.ts +10 -0
- package/dist/finalize.js +102 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.js +6 -5
- package/dist/initial-state.d.ts +7 -0
- package/dist/initial-state.js +216 -0
- package/dist/inspector.d.ts +6 -4
- package/dist/inspector.js +28 -300
- package/dist/lite.d.ts +26 -0
- package/dist/lite.js +25 -0
- package/dist/source-file-cache.d.ts +11 -0
- package/dist/source-file-cache.js +34 -10
- package/dist/types-map.js +2 -1
- package/dist/types.d.ts +35 -3
- package/dist/utils/apply-declared-scopes.d.ts +8 -0
- package/dist/utils/apply-declared-scopes.js +21 -0
- package/dist/utils/canonical-type-string.d.ts +14 -0
- package/dist/utils/canonical-type-string.js +162 -0
- package/dist/utils/context-based-id.d.ts +7 -0
- package/dist/utils/context-based-id.js +9 -0
- package/dist/utils/custom-types-generator.d.ts +15 -1
- package/dist/utils/custom-types-generator.js +17 -5
- package/dist/utils/ensure-function-metadata.d.ts +0 -14
- package/dist/utils/ensure-function-metadata.js +4 -1
- package/dist/utils/extract-function-name.d.ts +1 -1
- package/dist/utils/extract-function-name.js +2 -4
- package/dist/utils/filter-inspector-state.js +31 -1
- package/dist/utils/get-property-value.d.ts +5 -0
- package/dist/utils/get-property-value.js +15 -1
- package/dist/utils/inspector-constants.d.ts +16 -0
- package/dist/utils/inspector-constants.js +16 -0
- package/dist/utils/load-addon-functions-meta.js +1 -0
- package/dist/utils/post-process.d.ts +35 -36
- package/dist/utils/post-process.js +218 -193
- package/dist/utils/resolve-callee-name.d.ts +27 -0
- package/dist/utils/resolve-callee-name.js +147 -0
- package/dist/utils/resolve-service-types.d.ts +8 -0
- package/dist/utils/resolve-service-types.js +21 -0
- package/dist/utils/schema-generator.js +29 -2
- package/dist/utils/serialize-inspector-state.d.ts +9 -3
- package/dist/utils/serialize-inspector-state.js +22 -7
- package/dist/utils/single-declaration.d.ts +3 -3
- package/dist/utils/single-declaration.js +3 -3
- package/dist/utils/validate-single-step-workflows.d.ts +3 -0
- package/dist/utils/validate-single-step-workflows.js +32 -0
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +3 -3
- package/dist/utils/workflow/dsl/patterns.d.ts +4 -11
- package/dist/utils/workflow/dsl/patterns.js +5 -11
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +6 -6
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +5 -5
- package/dist/visit.js +4 -2
- package/package.json +25 -9
- package/CHANGELOG.md +0 -4318
- package/OPTIMIZATION-PLAN.md +0 -201
- package/dist/add/add-personas.d.ts +0 -13
- package/run-tests.sh +0 -68
- package/src/utils/test-data/inspector-state.json +0 -1687
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { ErrorCode } from '../error-codes.js';
|
|
3
|
+
import { MIDDLEWARE_HELPERS, PERMISSION_HELPERS, calleeNames, isNamespaceReceiver, } from '../utils/resolve-callee-name.js';
|
|
4
|
+
const isGateHelper = (name) => MIDDLEWARE_HELPERS.has(name) || PERMISSION_HELPERS.has(name);
|
|
5
|
+
const localNamesCache = new WeakMap();
|
|
6
|
+
/** The names a file can reach a gate helper by: its own, and its import aliases. */
|
|
7
|
+
const localGateNames = (sourceFile) => {
|
|
8
|
+
const cached = localNamesCache.get(sourceFile);
|
|
9
|
+
if (cached)
|
|
10
|
+
return cached;
|
|
11
|
+
const names = new Set([...MIDDLEWARE_HELPERS, ...PERMISSION_HELPERS]);
|
|
12
|
+
for (const statement of sourceFile.statements) {
|
|
13
|
+
const bindings = ts.isImportDeclaration(statement)
|
|
14
|
+
? statement.importClause?.namedBindings
|
|
15
|
+
: undefined;
|
|
16
|
+
if (!bindings || !ts.isNamedImports(bindings))
|
|
17
|
+
continue;
|
|
18
|
+
for (const element of bindings.elements) {
|
|
19
|
+
if (isGateHelper((element.propertyName ?? element.name).text)) {
|
|
20
|
+
names.add(element.name.text);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
localNamesCache.set(sourceFile, names);
|
|
25
|
+
return names;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Whether a reference to a gate helper sits where the inspector already
|
|
29
|
+
* accounts for it: called directly, imported or re-exported, bound to another
|
|
30
|
+
* `const` name, named as a declaration, or used as a type.
|
|
31
|
+
*/
|
|
32
|
+
const isAccountedFor = (reference) => {
|
|
33
|
+
const parent = reference.parent;
|
|
34
|
+
if (ts.isCallExpression(parent) && parent.expression === reference) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (ts.isImportSpecifier(parent) ||
|
|
38
|
+
ts.isExportSpecifier(parent) ||
|
|
39
|
+
ts.isImportClause(parent) ||
|
|
40
|
+
ts.isNamespaceImport(parent) ||
|
|
41
|
+
ts.isExportAssignment(parent) ||
|
|
42
|
+
ts.isQualifiedName(parent) ||
|
|
43
|
+
ts.isTypeNode(parent) ||
|
|
44
|
+
ts.isExpressionWithTypeArguments(parent)) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (ts.isVariableDeclaration(parent) &&
|
|
48
|
+
parent.initializer === reference &&
|
|
49
|
+
ts.getCombinedNodeFlags(parent) & ts.NodeFlags.Const) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if ('name' in parent && parent.name === reference) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
for (let current = parent; current; current = current.parent) {
|
|
56
|
+
if ((ts.isVariableDeclaration(current) ||
|
|
57
|
+
ts.isFunctionDeclaration(current)) &&
|
|
58
|
+
current.name &&
|
|
59
|
+
ts.isIdentifier(current.name) &&
|
|
60
|
+
isGateHelper(current.name.text)) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* A middleware or permission helper the inspector can only see by its direct
|
|
68
|
+
* calls. Passed around as a value — into an array, through a ternary, as an
|
|
69
|
+
* argument — whatever it registers is invisible to codegen, and a gate that
|
|
70
|
+
* codegen never imports is a gate that never runs. Say so rather than
|
|
71
|
+
* generate an app that is silently open.
|
|
72
|
+
*/
|
|
73
|
+
export const checkIndirectRegistrations = (logger, node, checker) => {
|
|
74
|
+
if (!ts.isIdentifier(node))
|
|
75
|
+
return;
|
|
76
|
+
const sourceFile = node.getSourceFile();
|
|
77
|
+
if (sourceFile.isDeclarationFile)
|
|
78
|
+
return;
|
|
79
|
+
if (!localGateNames(sourceFile).has(node.text))
|
|
80
|
+
return;
|
|
81
|
+
let reference = node;
|
|
82
|
+
if (ts.isPropertyAccessExpression(node.parent)) {
|
|
83
|
+
if (node.parent.name !== node)
|
|
84
|
+
return;
|
|
85
|
+
if (!isNamespaceReceiver(node.parent.expression, checker))
|
|
86
|
+
return;
|
|
87
|
+
reference = node.parent;
|
|
88
|
+
}
|
|
89
|
+
if (isAccountedFor(reference))
|
|
90
|
+
return;
|
|
91
|
+
const helper = [...calleeNames(reference, checker)]
|
|
92
|
+
.reverse()
|
|
93
|
+
.find(isGateHelper);
|
|
94
|
+
if (!helper)
|
|
95
|
+
return;
|
|
96
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
97
|
+
if (symbol?.valueDeclaration && ts.isParameter(symbol.valueDeclaration)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const type = checker.getTypeAtLocation(reference);
|
|
101
|
+
if (type.getCallSignatures().length === 0 &&
|
|
102
|
+
!(type.flags & ts.TypeFlags.Any)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
106
|
+
logger.diagnostic({
|
|
107
|
+
severity: 'error',
|
|
108
|
+
code: ErrorCode.REGISTRATION_NOT_A_DIRECT_CALL,
|
|
109
|
+
message: `'${reference.getText()}' (${helper}) is used as a value at ${sourceFile.fileName}:${line + 1}. ` +
|
|
110
|
+
`The inspector records middleware and permissions only where ${helper} is called directly, ` +
|
|
111
|
+
`so whatever this registers is never imported by the generated code and does not run. ` +
|
|
112
|
+
`Call ${helper}(...) directly.`,
|
|
113
|
+
});
|
|
114
|
+
};
|
package/dist/error-codes.d.ts
CHANGED
|
@@ -20,16 +20,17 @@ export declare enum ErrorCode {
|
|
|
20
20
|
CLI_CLIENTSIDE_RENDERER_HAS_SERVICES = "PKU672",
|
|
21
21
|
SCENARIO_HAS_SERVICES = "PKU673",
|
|
22
22
|
EXPECT_EVENTUALLY_SCENARIO_ONLY = "PKU675",
|
|
23
|
-
|
|
23
|
+
SCENARIO_STEP_NEEDS_VIRTUAL_USER = "PKU677",
|
|
24
24
|
SCENARIO_STEP_TARGET_NOT_STATIC = "PKU678",
|
|
25
25
|
SCENARIO_NOT_EXTRACTABLE = "PKU679",
|
|
26
26
|
SCENARIO_HAS_NO_ASSERTION = "PKU680",
|
|
27
|
-
|
|
27
|
+
SCENARIO_STEP_PROSE_NAMES_VIRTUAL_USER = "PKU681",
|
|
28
28
|
SCENARIO_HAS_NO_FEATURE = "PKU682",
|
|
29
29
|
WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED = "PKU600",
|
|
30
30
|
INVALID_DSL_WORKFLOW = "PKU641",
|
|
31
31
|
WORKFLOW_GRAPH_ADDON_NOT_WIRED = "PKU642",
|
|
32
32
|
COMPLEX_WORKFLOW_NOT_ALLOWED = "PKU643",
|
|
33
|
+
SINGLE_STEP_WORKFLOW = "PKU644",
|
|
33
34
|
REMOTE_ADDON_NOT_DEV_DEPENDENCY = "PKU338",
|
|
34
35
|
REMOTE_ADDON_AUTH_UNRESOLVED = "PKU339",
|
|
35
36
|
ADDON_NOT_INSTALLED = "PKU340",
|
|
@@ -53,13 +54,14 @@ export declare enum ErrorCode {
|
|
|
53
54
|
FUNCTION_METADATA_NOT_FOUND = "PKU559",
|
|
54
55
|
DUPLICATE_AUTH_DEFINITION = "PKU581",
|
|
55
56
|
AUTH_NOT_EXPORTED = "PKU582",
|
|
56
|
-
|
|
57
|
+
DUPLICATE_VIRTUAL_USERS_DEFINITION = "PKU585",
|
|
57
58
|
ROUTE_PARAM_MISMATCH = "PKU571",
|
|
58
59
|
ROUTE_QUERY_MISMATCH = "PKU572",
|
|
59
60
|
AUTH_DISABLED_REQUIRES_SESSIONLESS = "PKU573",
|
|
60
61
|
EXPOSED_FUNCTION_HAS_NO_GATE = "PKU574",
|
|
61
62
|
TAG_RESOLVES_TO_NO_MIDDLEWARE = "PKU575",
|
|
62
63
|
PERMISSIONS_IN_BODY_NOT_ALLOWED = "PKU576",
|
|
64
|
+
REGISTRATION_NOT_A_DIRECT_CALL = "PKU577",
|
|
63
65
|
DUPLICATE_FUNCTION_VERSION = "PKU850",
|
|
64
66
|
DUPLICATE_FUNCTION_NAME = "PKU851",
|
|
65
67
|
MANIFEST_MISSING = "PKU860",
|
package/dist/error-codes.js
CHANGED
|
@@ -22,16 +22,17 @@ export var ErrorCode;
|
|
|
22
22
|
ErrorCode["CLI_CLIENTSIDE_RENDERER_HAS_SERVICES"] = "PKU672";
|
|
23
23
|
ErrorCode["SCENARIO_HAS_SERVICES"] = "PKU673";
|
|
24
24
|
ErrorCode["EXPECT_EVENTUALLY_SCENARIO_ONLY"] = "PKU675";
|
|
25
|
-
ErrorCode["
|
|
25
|
+
ErrorCode["SCENARIO_STEP_NEEDS_VIRTUAL_USER"] = "PKU677";
|
|
26
26
|
ErrorCode["SCENARIO_STEP_TARGET_NOT_STATIC"] = "PKU678";
|
|
27
27
|
ErrorCode["SCENARIO_NOT_EXTRACTABLE"] = "PKU679";
|
|
28
28
|
ErrorCode["SCENARIO_HAS_NO_ASSERTION"] = "PKU680";
|
|
29
|
-
ErrorCode["
|
|
29
|
+
ErrorCode["SCENARIO_STEP_PROSE_NAMES_VIRTUAL_USER"] = "PKU681";
|
|
30
30
|
ErrorCode["SCENARIO_HAS_NO_FEATURE"] = "PKU682";
|
|
31
31
|
ErrorCode["WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED"] = "PKU600";
|
|
32
32
|
ErrorCode["INVALID_DSL_WORKFLOW"] = "PKU641";
|
|
33
33
|
ErrorCode["WORKFLOW_GRAPH_ADDON_NOT_WIRED"] = "PKU642";
|
|
34
34
|
ErrorCode["COMPLEX_WORKFLOW_NOT_ALLOWED"] = "PKU643";
|
|
35
|
+
ErrorCode["SINGLE_STEP_WORKFLOW"] = "PKU644";
|
|
35
36
|
// Remote addon (wireRemoteAddon) validation
|
|
36
37
|
ErrorCode["REMOTE_ADDON_NOT_DEV_DEPENDENCY"] = "PKU338";
|
|
37
38
|
ErrorCode["REMOTE_ADDON_AUTH_UNRESOLVED"] = "PKU339";
|
|
@@ -65,7 +66,7 @@ export var ErrorCode;
|
|
|
65
66
|
// scopes and roles held this rule until the generated `admin` tree made it
|
|
66
67
|
// unsatisfiable, and get it back once `admin` is a default scope nobody
|
|
67
68
|
// declares. Do not reuse those two numbers for anything else.
|
|
68
|
-
ErrorCode["
|
|
69
|
+
ErrorCode["DUPLICATE_VIRTUAL_USERS_DEFINITION"] = "PKU585";
|
|
69
70
|
// HTTP Route errors
|
|
70
71
|
ErrorCode["ROUTE_PARAM_MISMATCH"] = "PKU571";
|
|
71
72
|
ErrorCode["ROUTE_QUERY_MISMATCH"] = "PKU572";
|
|
@@ -73,6 +74,7 @@ export var ErrorCode;
|
|
|
73
74
|
ErrorCode["EXPOSED_FUNCTION_HAS_NO_GATE"] = "PKU574";
|
|
74
75
|
ErrorCode["TAG_RESOLVES_TO_NO_MIDDLEWARE"] = "PKU575";
|
|
75
76
|
ErrorCode["PERMISSIONS_IN_BODY_NOT_ALLOWED"] = "PKU576";
|
|
77
|
+
ErrorCode["REGISTRATION_NOT_A_DIRECT_CALL"] = "PKU577";
|
|
76
78
|
// Versioning errors
|
|
77
79
|
ErrorCode["DUPLICATE_FUNCTION_VERSION"] = "PKU850";
|
|
78
80
|
ErrorCode["DUPLICATE_FUNCTION_NAME"] = "PKU851";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InspectorState, InspectorLogger, InspectorOptions } from './types.js';
|
|
2
|
+
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
3
|
+
export type { SerializableInspectorState } from './utils/serialize-inspector-state.js';
|
|
4
|
+
/**
|
|
5
|
+
* The checker-free half of an inspection: everything that derives from the
|
|
6
|
+
* state analysis produced. It never loads `typescript`, so it runs the same
|
|
7
|
+
* against a live analysis and against a state deserialized from another
|
|
8
|
+
* engine.
|
|
9
|
+
*/
|
|
10
|
+
export declare const finalizeInspectorState: <S extends Omit<InspectorState, "typesLookup">>(logger: InspectorLogger, analyzed: S, options?: InspectorOptions) => Promise<S>;
|
package/dist/finalize.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { performance } from 'perf_hooks';
|
|
2
|
+
import { applyDeclaredScopes } from './utils/apply-declared-scopes.js';
|
|
3
|
+
import { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
4
|
+
import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateAgentScorerReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateAddonUses, validateAddonContentGrants, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes, validateVirtualUserRoles, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, validateNoSecretAliasServices, registerDerivedOAuth2AppSecrets, validateSecretUsage, computeDiagnostics, validateSchemaReferences, validateSchemaWiringSeparation, validateScenarioServices, validateScenarioSteps, validateScenarioFeatures, validateWorkflowGraphAddons, } from './utils/post-process.js';
|
|
5
|
+
import { validateExposedFunctionsGated } from './utils/validate-exposed-functions-gated.js';
|
|
6
|
+
import { validateTagsResolveToMiddleware } from './utils/validate-tags-resolve-to-middleware.js';
|
|
7
|
+
import { validateSingleStepWorkflows } from './utils/validate-single-step-workflows.js';
|
|
8
|
+
import { annotateHttpRouteAuth } from './utils/annotate-http-route-auth.js';
|
|
9
|
+
import { generateOpenAPISpec } from './utils/serialize-openapi-json.js';
|
|
10
|
+
import { pikkuState } from '@pikku/core/state';
|
|
11
|
+
import { finalizeWorkflows } from './utils/workflow/graph/finalize-workflows.js';
|
|
12
|
+
import { finalizeWorkflowHelperTypes, finalizeWorkflowWires, } from './utils/workflow/graph/finalize-workflow-wires.js';
|
|
13
|
+
import { loadAddonSchemas } from './utils/load-addon-functions-meta.js';
|
|
14
|
+
import { computeContractHashes, extractContractsFromMeta, updateManifest, createEmptyManifest, validateContracts, } from './utils/contract-hashes.js';
|
|
15
|
+
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
16
|
+
/**
|
|
17
|
+
* The checker-free half of an inspection: everything that derives from the
|
|
18
|
+
* state analysis produced. It never loads `typescript`, so it runs the same
|
|
19
|
+
* against a live analysis and against a state deserialized from another
|
|
20
|
+
* engine.
|
|
21
|
+
*/
|
|
22
|
+
export const finalizeInspectorState = async (logger, analyzed, options = {}) => {
|
|
23
|
+
const state = analyzed;
|
|
24
|
+
if (!options.setupOnly) {
|
|
25
|
+
if (options.schemaConfig) {
|
|
26
|
+
computeContractHashes(state.schemas, state.functions.typesMap, state.functions.meta);
|
|
27
|
+
computeRequiredSchemas(state, options);
|
|
28
|
+
}
|
|
29
|
+
// Re-load addon schemas (generateAllSchemas replaces state.schemas)
|
|
30
|
+
await loadAddonSchemas(logger, state);
|
|
31
|
+
// After the addon merge, not before: an addon supplies its own schemas here,
|
|
32
|
+
// and checking earlier would report every one of them as unresolved.
|
|
33
|
+
if (options.schemaConfig) {
|
|
34
|
+
validateSchemaReferences(logger, state);
|
|
35
|
+
}
|
|
36
|
+
state.manifest.initial = options.manifest ?? null;
|
|
37
|
+
const contracts = extractContractsFromMeta(state.functions.meta);
|
|
38
|
+
const baseManifest = state.manifest.initial ?? createEmptyManifest();
|
|
39
|
+
state.manifest.current = updateManifest(baseManifest, contracts);
|
|
40
|
+
state.manifest.errors = validateContracts(baseManifest, contracts).errors;
|
|
41
|
+
finalizeWorkflows(state);
|
|
42
|
+
finalizeWorkflowHelperTypes(state);
|
|
43
|
+
finalizeWorkflowWires(state);
|
|
44
|
+
}
|
|
45
|
+
// Populate filesAndMethods
|
|
46
|
+
const startFilesAndMethods = performance.now();
|
|
47
|
+
const { result, errors } = getFilesAndMethods(state, options.types);
|
|
48
|
+
state.filesAndMethods = result;
|
|
49
|
+
state.filesAndMethodsErrors = errors;
|
|
50
|
+
logger.debug(`Get files and methods completed in ${(performance.now() - startFilesAndMethods).toFixed(2)}ms`);
|
|
51
|
+
if (!options.setupOnly) {
|
|
52
|
+
// Everything below re-derives from the state this pass just built, so it
|
|
53
|
+
// supersedes whatever an earlier pass concluded about a source graph the
|
|
54
|
+
// run has since finished generating into.
|
|
55
|
+
logger.beginValidationPass?.();
|
|
56
|
+
const startAggregate = performance.now();
|
|
57
|
+
// Apply the inspected auth handler service set before aggregation so it
|
|
58
|
+
// flows into requiredServices (the generated handler's own func is opaque).
|
|
59
|
+
stampAuthHandlerServices(state);
|
|
60
|
+
aggregateRequiredServices(state);
|
|
61
|
+
logger.debug(`Aggregate required services completed in ${(performance.now() - startAggregate).toFixed(2)}ms`);
|
|
62
|
+
computeResolvedIOTypes(state);
|
|
63
|
+
computeMiddlewareGroupsMeta(state);
|
|
64
|
+
computePermissionsGroupsMeta(state);
|
|
65
|
+
validateNoSecretAliasServices(logger, state);
|
|
66
|
+
registerDerivedOAuth2AppSecrets(state);
|
|
67
|
+
validateSecretUsage(logger, state);
|
|
68
|
+
computeDiagnostics(state);
|
|
69
|
+
validateSchemaWiringSeparation(logger, state);
|
|
70
|
+
validateWorkflowGraphAddons(logger, state);
|
|
71
|
+
validateSingleStepWorkflows(logger, state);
|
|
72
|
+
validateScenarioServices(logger, state);
|
|
73
|
+
validateScenarioSteps(logger, state);
|
|
74
|
+
validateScenarioFeatures(logger, state);
|
|
75
|
+
// Needs every route, every function and every wireAddon declaration
|
|
76
|
+
// together, so it can only run once the whole program is inspected.
|
|
77
|
+
annotateHttpRouteAuth(state);
|
|
78
|
+
// Last of the validators: they read function meta and every wireAddon
|
|
79
|
+
// declaration together, so they need the whole program inspected.
|
|
80
|
+
validateExposedFunctionsGated(logger, state);
|
|
81
|
+
validateTagsResolveToMiddleware(logger, state);
|
|
82
|
+
if (options.openAPI) {
|
|
83
|
+
state.openAPISpec = await generateOpenAPISpec(logger, state.functions.meta, state.http.meta, state.schemas, options.openAPI.additionalInfo, pikkuState(null, 'misc', 'errors'));
|
|
84
|
+
}
|
|
85
|
+
validateAgentModels(logger, state, options.modelAliases);
|
|
86
|
+
validateAgentToolReferences(logger, state, options);
|
|
87
|
+
validateAgentScorerReferences(logger, state);
|
|
88
|
+
validateSecretOverrides(logger, state);
|
|
89
|
+
validateVariableOverrides(logger, state);
|
|
90
|
+
validateCredentialOverrides(logger, state);
|
|
91
|
+
validateAddonUses(logger, state);
|
|
92
|
+
validateAddonContentGrants(logger, state);
|
|
93
|
+
validateRemoteAddonDependencies(logger, state);
|
|
94
|
+
validateRemoteAddonAuth(logger, state);
|
|
95
|
+
applyDeclaredScopes(state);
|
|
96
|
+
validateScopeReferences(logger, state);
|
|
97
|
+
validateSystemRoleScopes(logger, state);
|
|
98
|
+
validateVirtualUserRoles(logger, state);
|
|
99
|
+
logger.endValidationPass?.();
|
|
100
|
+
}
|
|
101
|
+
return analyzed;
|
|
102
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
export { inspect,
|
|
1
|
+
export { inspect, analyzeProgram } from './inspector.js';
|
|
2
|
+
export { getInitialInspectorState } from './initial-state.js';
|
|
3
|
+
export { finalizeInspectorState } from './finalize.js';
|
|
2
4
|
export type { TypesMap } from './types-map.js';
|
|
3
|
-
export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, ScreensManifestMeta, AddonScreenMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
|
|
5
|
+
export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, ScreensManifestMeta, AddonScreenMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorServiceTypes, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
|
|
4
6
|
export type { FilesAndMethodsErrors } from './utils/get-files-and-methods.js';
|
|
5
7
|
export { ErrorCode } from './error-codes.js';
|
|
6
8
|
export type { DiagnosticSeverity, CodedDiagnostic } from './error-codes.js';
|
|
7
|
-
export { AUTH_HANDLER_FUNC_ID } from './
|
|
9
|
+
export { AUTH_HANDLER_FUNC_ID } from './utils/inspector-constants.js';
|
|
8
10
|
export { SCENARIO_INSTRUMENTATION_FUNCTIONS, isScenarioInstrumentationFunction, } from './add/scenario-instrumentation.js';
|
|
9
11
|
export type { ScenarioInstrumentationFunction } from './add/scenario-instrumentation.js';
|
|
10
12
|
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
11
13
|
export type { SerializableInspectorState } from './utils/serialize-inspector-state.js';
|
|
12
14
|
export { filterInspectorState } from './utils/filter-inspector-state.js';
|
|
13
15
|
export { incompatibleServicesFor, resolveDeployTarget, } from './utils/resolve-deploy-target.js';
|
|
14
|
-
export { generateCustomTypes, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
16
|
+
export { generateCustomTypes, customTypeNames, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
17
|
+
export type { GenerateCustomTypesOptions } from './utils/custom-types-generator.js';
|
|
15
18
|
export { unresolvedSchemaReferences } from './utils/post-process.js';
|
|
16
19
|
export type { SurfaceUsageCounts } from './utils/extract-surface-usage.js';
|
|
17
20
|
export { createEmptyManifest, serializeManifest, } from './utils/contract-hashes.js';
|
|
@@ -19,11 +22,10 @@ export type { ContractEntry, VersionHashEntry, VersionValidateError, VersionMani
|
|
|
19
22
|
export type { InspectorFeature, InspectorFeatureEntry } from './types.js';
|
|
20
23
|
export { serializeMCPJson } from './utils/serialize-mcp-json.js';
|
|
21
24
|
export type { OpenAPISpecInfo } from './utils/serialize-openapi-json.js';
|
|
22
|
-
export { deserializeDslWorkflow, deserializeGraphWorkflow, deserializeAllDslWorkflows, } from './utils/workflow/dsl/
|
|
25
|
+
export { deserializeDslWorkflow, deserializeGraphWorkflow, deserializeAllDslWorkflows, } from './utils/workflow/dsl/deserialize-dsl-workflow.js';
|
|
23
26
|
export { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
24
27
|
export { resolveFunctionMeta } from './utils/resolve-function-meta.js';
|
|
25
28
|
export type { SerializedWorkflowGraph, SerializedWorkflowGraphs, } from './utils/workflow/graph/index.js';
|
|
26
|
-
export { resolveCoreType } from './utils/resolve-core-type.js';
|
|
27
29
|
export { readModuleSpecifiers } from './utils/read-module-specifiers.js';
|
|
28
30
|
export { readJsxLiteralText } from './utils/read-jsx-literal-text.js';
|
|
29
31
|
export { readTsconfigOutDir } from './utils/read-tsconfig-out-dir.js';
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
export { inspect,
|
|
1
|
+
export { inspect, analyzeProgram } from './inspector.js';
|
|
2
|
+
export { getInitialInspectorState } from './initial-state.js';
|
|
3
|
+
export { finalizeInspectorState } from './finalize.js';
|
|
2
4
|
export { ErrorCode } from './error-codes.js';
|
|
3
|
-
export { AUTH_HANDLER_FUNC_ID } from './
|
|
5
|
+
export { AUTH_HANDLER_FUNC_ID } from './utils/inspector-constants.js';
|
|
4
6
|
export { SCENARIO_INSTRUMENTATION_FUNCTIONS, isScenarioInstrumentationFunction, } from './add/scenario-instrumentation.js';
|
|
5
7
|
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
6
8
|
export { filterInspectorState } from './utils/filter-inspector-state.js';
|
|
7
9
|
export { incompatibleServicesFor, resolveDeployTarget, } from './utils/resolve-deploy-target.js';
|
|
8
|
-
export { generateCustomTypes, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
10
|
+
export { generateCustomTypes, customTypeNames, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
9
11
|
export { unresolvedSchemaReferences } from './utils/post-process.js';
|
|
10
12
|
export { createEmptyManifest, serializeManifest, } from './utils/contract-hashes.js';
|
|
11
13
|
export { serializeMCPJson } from './utils/serialize-mcp-json.js';
|
|
12
|
-
export { deserializeDslWorkflow, deserializeGraphWorkflow, deserializeAllDslWorkflows, } from './utils/workflow/dsl/
|
|
14
|
+
export { deserializeDslWorkflow, deserializeGraphWorkflow, deserializeAllDslWorkflows, } from './utils/workflow/dsl/deserialize-dsl-workflow.js';
|
|
13
15
|
export { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
14
16
|
export { resolveFunctionMeta } from './utils/resolve-function-meta.js';
|
|
15
|
-
export { resolveCoreType } from './utils/resolve-core-type.js';
|
|
16
17
|
export { readModuleSpecifiers } from './utils/read-module-specifiers.js';
|
|
17
18
|
export { readJsxLiteralText } from './utils/read-jsx-literal-text.js';
|
|
18
19
|
export { readTsconfigOutDir } from './utils/read-tsconfig-out-dir.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InspectorState } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an initial/empty inspector state with all required properties initialized
|
|
4
|
+
* @param rootDir - The root directory for the project
|
|
5
|
+
* @returns A fresh InspectorState with empty collections
|
|
6
|
+
*/
|
|
7
|
+
export declare function getInitialInspectorState(rootDir: string): InspectorState;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { TypesMap } from './types-map.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an initial/empty inspector state with all required properties initialized
|
|
4
|
+
* @param rootDir - The root directory for the project
|
|
5
|
+
* @returns A fresh InspectorState with empty collections
|
|
6
|
+
*/
|
|
7
|
+
export function getInitialInspectorState(rootDir) {
|
|
8
|
+
return {
|
|
9
|
+
rootDir,
|
|
10
|
+
singletonServicesTypeImportMap: new Map(),
|
|
11
|
+
wireServicesTypeImportMap: new Map(),
|
|
12
|
+
userSessionTypeImportMap: new Map(),
|
|
13
|
+
configTypeImportMap: new Map(),
|
|
14
|
+
singletonServicesFactories: new Map(),
|
|
15
|
+
wireServicesFactories: new Map(),
|
|
16
|
+
wireServicesMeta: new Map(),
|
|
17
|
+
addonRequiredParentServices: [],
|
|
18
|
+
addonCreatedServices: [],
|
|
19
|
+
addonServicesFactorySeen: false,
|
|
20
|
+
addonServerlessIncompatible: new Map(),
|
|
21
|
+
configFactories: new Map(),
|
|
22
|
+
serverLifecycleFactories: new Map(),
|
|
23
|
+
filesAndMethods: {},
|
|
24
|
+
filesAndMethodsErrors: new Map(),
|
|
25
|
+
typesLookup: new Map(),
|
|
26
|
+
schemaLookup: new Map(),
|
|
27
|
+
schemas: {},
|
|
28
|
+
functions: {
|
|
29
|
+
typesMap: new TypesMap(),
|
|
30
|
+
meta: {},
|
|
31
|
+
files: new Map(),
|
|
32
|
+
approvalDescriptions: {},
|
|
33
|
+
dynamicImportIds: new Set(),
|
|
34
|
+
},
|
|
35
|
+
http: {
|
|
36
|
+
metaInputTypes: new Map(),
|
|
37
|
+
meta: {
|
|
38
|
+
get: {},
|
|
39
|
+
post: {},
|
|
40
|
+
put: {},
|
|
41
|
+
delete: {},
|
|
42
|
+
head: {},
|
|
43
|
+
patch: {},
|
|
44
|
+
options: {},
|
|
45
|
+
},
|
|
46
|
+
files: new Set(),
|
|
47
|
+
routeMiddleware: new Map(),
|
|
48
|
+
},
|
|
49
|
+
channels: {
|
|
50
|
+
files: new Set(),
|
|
51
|
+
meta: {},
|
|
52
|
+
},
|
|
53
|
+
gateways: {
|
|
54
|
+
meta: {},
|
|
55
|
+
files: new Set(),
|
|
56
|
+
},
|
|
57
|
+
triggers: {
|
|
58
|
+
meta: {},
|
|
59
|
+
sourceMeta: {},
|
|
60
|
+
webhookSourceMeta: {},
|
|
61
|
+
files: new Set(),
|
|
62
|
+
},
|
|
63
|
+
scheduledTasks: {
|
|
64
|
+
meta: {},
|
|
65
|
+
files: new Set(),
|
|
66
|
+
},
|
|
67
|
+
queueWorkers: {
|
|
68
|
+
meta: {},
|
|
69
|
+
files: new Set(),
|
|
70
|
+
},
|
|
71
|
+
workflows: {
|
|
72
|
+
meta: {},
|
|
73
|
+
files: new Map(),
|
|
74
|
+
graphMeta: {},
|
|
75
|
+
graphFiles: new Map(),
|
|
76
|
+
featureFiles: new Map(),
|
|
77
|
+
invokedWorkflows: new Set(),
|
|
78
|
+
},
|
|
79
|
+
rpc: {
|
|
80
|
+
internalMeta: {},
|
|
81
|
+
internalFiles: new Map(),
|
|
82
|
+
exposedMeta: {},
|
|
83
|
+
exposedFiles: new Map(),
|
|
84
|
+
remoteMeta: {},
|
|
85
|
+
remoteFiles: new Map(),
|
|
86
|
+
invokedFunctions: new Set(),
|
|
87
|
+
invokedFunctionsByFile: new Map(),
|
|
88
|
+
usedAddons: new Set(),
|
|
89
|
+
wireAddonDeclarations: new Map(),
|
|
90
|
+
wireAddonFiles: new Set(),
|
|
91
|
+
},
|
|
92
|
+
mcpEndpoints: {
|
|
93
|
+
resourcesMeta: {},
|
|
94
|
+
toolsMeta: {},
|
|
95
|
+
promptsMeta: {},
|
|
96
|
+
files: new Set(),
|
|
97
|
+
surfaces: {},
|
|
98
|
+
},
|
|
99
|
+
agents: {
|
|
100
|
+
agentsMeta: {},
|
|
101
|
+
files: new Map(),
|
|
102
|
+
invokedAgentsByFile: new Map(),
|
|
103
|
+
},
|
|
104
|
+
scorers: {
|
|
105
|
+
scorersMeta: {},
|
|
106
|
+
files: new Map(),
|
|
107
|
+
},
|
|
108
|
+
cli: {
|
|
109
|
+
meta: {
|
|
110
|
+
programs: {},
|
|
111
|
+
renderers: {},
|
|
112
|
+
},
|
|
113
|
+
files: new Set(),
|
|
114
|
+
},
|
|
115
|
+
nodes: {
|
|
116
|
+
meta: {},
|
|
117
|
+
files: new Set(),
|
|
118
|
+
},
|
|
119
|
+
auth: {
|
|
120
|
+
providers: [],
|
|
121
|
+
plugins: [],
|
|
122
|
+
files: new Set(),
|
|
123
|
+
definition: null,
|
|
124
|
+
},
|
|
125
|
+
secrets: {
|
|
126
|
+
definitions: [],
|
|
127
|
+
files: new Set(),
|
|
128
|
+
usage: new Map(),
|
|
129
|
+
},
|
|
130
|
+
surfaceUsage: {},
|
|
131
|
+
credentials: {
|
|
132
|
+
definitions: [],
|
|
133
|
+
files: new Set(),
|
|
134
|
+
},
|
|
135
|
+
scopes: {
|
|
136
|
+
definitions: [],
|
|
137
|
+
files: new Set(),
|
|
138
|
+
},
|
|
139
|
+
systemRoles: {
|
|
140
|
+
definitions: [],
|
|
141
|
+
files: new Set(),
|
|
142
|
+
},
|
|
143
|
+
featureFlags: {
|
|
144
|
+
definitions: [],
|
|
145
|
+
files: new Set(),
|
|
146
|
+
},
|
|
147
|
+
virtualUsers: {
|
|
148
|
+
definitions: [],
|
|
149
|
+
files: new Set(),
|
|
150
|
+
},
|
|
151
|
+
variables: {
|
|
152
|
+
definitions: [],
|
|
153
|
+
files: new Set(),
|
|
154
|
+
},
|
|
155
|
+
manifest: {
|
|
156
|
+
initial: null,
|
|
157
|
+
current: null,
|
|
158
|
+
errors: [],
|
|
159
|
+
},
|
|
160
|
+
middleware: {
|
|
161
|
+
definitions: {},
|
|
162
|
+
instances: {},
|
|
163
|
+
tagMiddleware: new Map(),
|
|
164
|
+
globalFiles: new Set(),
|
|
165
|
+
},
|
|
166
|
+
channelMiddleware: {
|
|
167
|
+
definitions: {},
|
|
168
|
+
instances: {},
|
|
169
|
+
tagMiddleware: new Map(),
|
|
170
|
+
},
|
|
171
|
+
agentMiddleware: {
|
|
172
|
+
definitions: {},
|
|
173
|
+
},
|
|
174
|
+
permissions: {
|
|
175
|
+
definitions: {},
|
|
176
|
+
instances: {},
|
|
177
|
+
global: [],
|
|
178
|
+
},
|
|
179
|
+
serviceAggregation: {
|
|
180
|
+
requiredServices: new Set(),
|
|
181
|
+
usedFunctions: new Set(),
|
|
182
|
+
usedMiddleware: new Set(),
|
|
183
|
+
usedPermissions: new Set(),
|
|
184
|
+
allSingletonServices: [],
|
|
185
|
+
allWireServices: [],
|
|
186
|
+
},
|
|
187
|
+
resolvedIOTypes: {},
|
|
188
|
+
middlewareGroupsMeta: {
|
|
189
|
+
definitions: {},
|
|
190
|
+
instances: {},
|
|
191
|
+
httpGroups: {},
|
|
192
|
+
tagGroups: {},
|
|
193
|
+
channelMiddleware: {
|
|
194
|
+
definitions: {},
|
|
195
|
+
instances: {},
|
|
196
|
+
tagGroups: {},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
permissionsGroupsMeta: {
|
|
200
|
+
definitions: {},
|
|
201
|
+
},
|
|
202
|
+
requiredSchemas: new Set(),
|
|
203
|
+
openAPISpec: null,
|
|
204
|
+
diagnostics: [],
|
|
205
|
+
addonFunctions: {},
|
|
206
|
+
exportedContracts: {
|
|
207
|
+
http: {},
|
|
208
|
+
cli: {},
|
|
209
|
+
channel: {},
|
|
210
|
+
addonHttp: {},
|
|
211
|
+
addonCli: {},
|
|
212
|
+
addonChannel: {},
|
|
213
|
+
},
|
|
214
|
+
program: null,
|
|
215
|
+
};
|
|
216
|
+
}
|
package/dist/inspector.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { InspectorState, InspectorLogger, InspectorOptions } from './types.js';
|
|
2
|
+
import { getInitialInspectorState } from './initial-state.js';
|
|
3
|
+
export { getInitialInspectorState };
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
5
|
+
* The engine-specific half of an inspection: builds the program, walks it with
|
|
6
|
+
* the checker and generates the schemas. What it returns is the pre-finalize
|
|
7
|
+
* state that `finalizeInspectorState` completes.
|
|
6
8
|
*/
|
|
7
|
-
export declare
|
|
9
|
+
export declare const analyzeProgram: (logger: InspectorLogger, routeFiles: string[], options?: InspectorOptions) => Promise<InspectorState>;
|
|
8
10
|
export declare const inspect: (logger: InspectorLogger, routeFiles: string[], options?: InspectorOptions) => Promise<InspectorState>;
|