@pikku/inspector 0.11.1 → 0.12.0
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 +26 -1
- package/OPTIMIZATION-PLAN.md +195 -0
- package/dist/add/add-ai-agent.d.ts +2 -0
- package/dist/add/add-ai-agent.js +314 -0
- package/dist/add/add-channel.js +69 -61
- package/dist/add/add-cli.js +36 -18
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.js +327 -59
- package/dist/add/add-http-route.d.ts +19 -10
- package/dist/add/add-http-route.js +153 -44
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +159 -0
- package/dist/add/add-keyed-wiring.d.ts +12 -0
- package/dist/add/add-keyed-wiring.js +97 -0
- package/dist/add/add-mcp-prompt.js +14 -9
- package/dist/add/add-mcp-resource.js +14 -9
- package/dist/add/add-middleware.d.ts +1 -4
- package/dist/add/add-middleware.js +364 -79
- package/dist/add/add-permission.d.ts +1 -1
- package/dist/add/add-permission.js +152 -40
- package/dist/add/add-queue-worker.js +18 -12
- package/dist/add/add-rpc-invocations.d.ts +3 -0
- package/dist/add/add-rpc-invocations.js +65 -25
- package/dist/add/add-schedule.js +11 -5
- package/dist/add/add-secret.d.ts +3 -0
- package/dist/add/add-secret.js +82 -0
- package/dist/add/add-trigger.d.ts +2 -0
- package/dist/add/add-trigger.js +87 -0
- package/dist/add/add-variable.d.ts +1 -0
- package/dist/add/add-variable.js +8 -0
- package/dist/add/add-workflow-graph.d.ts +7 -0
- package/dist/add/add-workflow-graph.js +396 -0
- package/dist/add/add-workflow.js +124 -26
- package/dist/error-codes.d.ts +16 -1
- package/dist/error-codes.js +21 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +5 -2
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +106 -13
- package/dist/schema-generator.d.ts +1 -0
- package/dist/schema-generator.js +1 -0
- package/dist/types-map.js +10 -1
- package/dist/types.d.ts +180 -30
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +41 -0
- package/dist/utils/contract-hashes.d.ts +35 -0
- package/dist/utils/contract-hashes.js +202 -0
- package/dist/utils/custom-types-generator.d.ts +9 -0
- package/dist/utils/custom-types-generator.js +71 -0
- package/dist/utils/detect-schema-vendor.d.ts +22 -0
- package/dist/utils/detect-schema-vendor.js +76 -0
- package/dist/utils/ensure-function-metadata.d.ts +5 -2
- package/dist/utils/ensure-function-metadata.js +220 -6
- package/dist/utils/extract-function-name.d.ts +5 -16
- package/dist/utils/extract-function-name.js +93 -298
- package/dist/utils/extract-services.d.ts +2 -1
- package/dist/utils/extract-services.js +25 -1
- package/dist/utils/filter-inspector-state.js +107 -23
- package/dist/utils/get-property-value.d.ts +8 -2
- package/dist/utils/get-property-value.js +33 -4
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils/middleware.d.ts +7 -30
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +2 -2
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +9 -10
- package/dist/utils/post-process.js +231 -24
- package/dist/utils/resolve-external-package.d.ts +12 -0
- package/dist/utils/resolve-external-package.js +34 -0
- package/dist/utils/resolve-function-types.d.ts +6 -0
- package/dist/utils/resolve-function-types.js +29 -0
- package/dist/utils/resolve-identifier.d.ts +10 -0
- package/dist/utils/resolve-identifier.js +36 -0
- package/dist/utils/resolve-versions.d.ts +2 -0
- package/dist/utils/resolve-versions.js +78 -0
- package/dist/utils/schema-generator.d.ts +9 -0
- package/dist/utils/schema-generator.js +209 -0
- package/dist/utils/serialize-inspector-state.d.ts +73 -13
- package/dist/utils/serialize-inspector-state.js +102 -6
- package/dist/utils/serialize-mcp-json.d.ts +2 -0
- package/dist/utils/serialize-mcp-json.js +99 -0
- package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
- package/dist/utils/serialize-middleware-groups-meta.js +28 -0
- package/dist/utils/serialize-openapi-json.d.ts +85 -0
- package/dist/utils/serialize-openapi-json.js +151 -0
- package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
- package/dist/utils/serialize-permissions-groups-meta.js +31 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.d.ts +24 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +830 -0
- package/dist/{workflow/extract-simple-workflow.d.ts → utils/workflow/dsl/extract-dsl-workflow.d.ts} +4 -2
- package/dist/{workflow/extract-simple-workflow.js → utils/workflow/dsl/extract-dsl-workflow.js} +572 -72
- package/dist/utils/workflow/dsl/index.d.ts +7 -0
- package/dist/utils/workflow/dsl/index.js +7 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.d.ts +21 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.js +90 -10
- package/dist/{workflow → utils/workflow/dsl}/validation.d.ts +2 -0
- package/dist/{workflow → utils/workflow/dsl}/validation.js +25 -7
- package/dist/utils/workflow/graph/convert-dsl-to-graph.d.ts +13 -0
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +318 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
- package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
- package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
- package/dist/utils/workflow/graph/index.d.ts +8 -0
- package/dist/utils/workflow/graph/index.js +8 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +35 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +150 -0
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +203 -0
- package/dist/utils/workflow/graph/workflow-graph.types.js +38 -0
- package/dist/visit.js +13 -2
- package/package.json +26 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +82 -79
- package/src/add/add-cli.ts +49 -20
- package/src/add/add-file-with-factory.ts +2 -0
- package/src/add/add-functions.ts +429 -71
- package/src/add/add-http-route.ts +246 -65
- package/src/add/add-http-routes.ts +228 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +26 -15
- package/src/add/add-mcp-resource.ts +27 -15
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +24 -19
- package/src/add/add-rpc-invocations.ts +78 -31
- package/src/add/add-schedule.ts +16 -11
- package/src/add/add-secret.ts +140 -0
- package/src/add/add-trigger.ts +154 -0
- package/src/add/add-variable.ts +9 -0
- package/src/add/add-workflow-graph.ts +522 -0
- package/src/add/add-workflow.ts +117 -30
- package/src/error-codes.ts +26 -1
- package/src/index.ts +27 -8
- package/src/inspector.ts +145 -17
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +192 -51
- package/src/utils/compute-required-schemas.ts +49 -0
- package/src/utils/contract-hashes.test.ts +528 -0
- package/src/utils/contract-hashes.ts +290 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/ensure-function-metadata.ts +324 -7
- package/src/utils/extract-function-name.ts +108 -358
- package/src/utils/extract-services.ts +35 -2
- package/src/utils/filter-inspector-state.test.ts +34 -20
- package/src/utils/filter-inspector-state.ts +140 -31
- package/src/utils/get-property-value.ts +50 -5
- package/src/utils/hash.ts +26 -0
- package/src/utils/middleware.test.ts +204 -0
- package/src/utils/middleware.ts +129 -67
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +10 -10
- package/src/utils/post-process.ts +283 -43
- package/src/utils/resolve-external-package.ts +42 -0
- package/src/utils/resolve-function-types.ts +42 -0
- package/src/utils/resolve-identifier.ts +46 -0
- package/src/utils/resolve-versions.test.ts +249 -0
- package/src/utils/resolve-versions.ts +105 -0
- package/src/utils/schema-generator.ts +329 -0
- package/src/utils/serialize-inspector-state.ts +181 -20
- package/src/utils/serialize-mcp-json.ts +145 -0
- package/src/utils/serialize-middleware-groups-meta.ts +33 -0
- package/src/utils/serialize-openapi-json.ts +277 -0
- package/src/utils/serialize-permissions-groups-meta.ts +35 -0
- package/src/utils/test-data/inspector-state.json +69 -66
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +1104 -0
- package/src/{workflow/extract-simple-workflow.ts → utils/workflow/dsl/extract-dsl-workflow.ts} +678 -85
- package/src/utils/workflow/dsl/index.ts +11 -0
- package/src/{workflow → utils/workflow/dsl}/patterns.ts +108 -11
- package/src/{workflow → utils/workflow/dsl}/validation.ts +34 -7
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +422 -0
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
- package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
- package/src/utils/workflow/graph/index.ts +11 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +216 -0
- package/src/utils/workflow/graph/workflow-graph.types.ts +231 -0
- package/src/visit.ts +14 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-mcp-tool.d.ts +0 -2
- package/dist/add/add-mcp-tool.js +0 -81
- package/dist/utils/extract-service-metadata.d.ts +0 -19
- package/dist/utils/extract-service-metadata.js +0 -244
- package/dist/utils/write-service-metadata.d.ts +0 -13
- package/dist/utils/write-service-metadata.js +0 -37
- package/src/add/add-mcp-tool.ts +0 -141
- package/src/utils/extract-service-metadata.ts +0 -353
- package/src/utils/write-service-metadata.ts +0 -51
|
@@ -1,9 +1,38 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { extractFunctionName, isNamedExport, } from '../utils/extract-function-name.js';
|
|
3
|
-
import { extractServicesFromFunction } from '../utils/extract-services.js';
|
|
2
|
+
import { extractFunctionName, isNamedExport, makeContextBasedId, } from '../utils/extract-function-name.js';
|
|
3
|
+
import { extractServicesFromFunction, extractUsedWires, } from '../utils/extract-services.js';
|
|
4
4
|
import { extractPermissionPikkuNames } from '../utils/permissions.js';
|
|
5
5
|
import { getPropertyValue } from '../utils/get-property-value.js';
|
|
6
6
|
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js';
|
|
7
|
+
function renameTempDefinitions(state, definitionIds, groupType, groupKey) {
|
|
8
|
+
const tempIndices = definitionIds
|
|
9
|
+
.map((name, i) => (name.startsWith('__temp_') ? i : -1))
|
|
10
|
+
.filter((i) => i >= 0);
|
|
11
|
+
for (const idx of tempIndices) {
|
|
12
|
+
const oldId = definitionIds[idx];
|
|
13
|
+
const newId = tempIndices.length === 1
|
|
14
|
+
? makeContextBasedId(groupType, groupKey)
|
|
15
|
+
: makeContextBasedId(groupType, groupKey, String(idx));
|
|
16
|
+
const existing = state.permissions.definitions[oldId];
|
|
17
|
+
if (existing) {
|
|
18
|
+
delete state.permissions.definitions[oldId];
|
|
19
|
+
state.permissions.definitions[newId] = existing;
|
|
20
|
+
}
|
|
21
|
+
definitionIds[idx] = newId;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isInsidePermissionFactory(node) {
|
|
25
|
+
let current = node.parent;
|
|
26
|
+
while (current) {
|
|
27
|
+
if (ts.isCallExpression(current) &&
|
|
28
|
+
ts.isIdentifier(current.expression) &&
|
|
29
|
+
current.expression.text === 'pikkuPermissionFactory') {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
current = current.parent;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
7
36
|
/**
|
|
8
37
|
* Inspect pikkuPermission calls, addPermission calls, and addHTTPPermission calls
|
|
9
38
|
*/
|
|
@@ -17,20 +46,20 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
17
46
|
}
|
|
18
47
|
// Handle pikkuPermission(...) - individual permission function definition
|
|
19
48
|
if (expression.text === 'pikkuPermission') {
|
|
49
|
+
// Skip if nested inside pikkuPermissionFactory — the factory handler extracts services itself
|
|
50
|
+
if (isInsidePermissionFactory(node))
|
|
51
|
+
return;
|
|
20
52
|
const arg = args[0];
|
|
21
53
|
if (!arg)
|
|
22
54
|
return;
|
|
23
55
|
let actualHandler;
|
|
24
56
|
let name;
|
|
25
57
|
let description;
|
|
26
|
-
// Check if using object syntax: pikkuPermission({ func: ..., name: '...', description: '...' })
|
|
27
58
|
if (ts.isObjectLiteralExpression(arg)) {
|
|
28
|
-
// Extract name and description metadata
|
|
29
59
|
const nameValue = getPropertyValue(arg, 'name');
|
|
30
60
|
const descValue = getPropertyValue(arg, 'description');
|
|
31
61
|
name = typeof nameValue === 'string' ? nameValue : undefined;
|
|
32
62
|
description = typeof descValue === 'string' ? descValue : undefined;
|
|
33
|
-
// Extract the func property
|
|
34
63
|
const fnProp = getPropertyAssignmentInitializer(arg, 'func', true, checker);
|
|
35
64
|
if (!fnProp ||
|
|
36
65
|
(!ts.isArrowFunction(fnProp) && !ts.isFunctionExpression(fnProp))) {
|
|
@@ -47,16 +76,97 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
47
76
|
return;
|
|
48
77
|
}
|
|
49
78
|
const services = extractServicesFromFunction(actualHandler);
|
|
50
|
-
const
|
|
51
|
-
|
|
79
|
+
const wires = extractUsedWires(actualHandler, 2);
|
|
80
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
81
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
82
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
83
|
+
ts.isIdentifier(node.parent.name)) {
|
|
84
|
+
pikkuFuncId = node.parent.name.text;
|
|
85
|
+
}
|
|
86
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
87
|
+
ts.isIdentifier(node.parent.name)) {
|
|
88
|
+
pikkuFuncId = node.parent.name.text;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
logger.error(`• pikkuPermission() must be assigned to a variable or object property. ` +
|
|
92
|
+
`Extract it to a const: const myPermission = pikkuPermission(...)`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const dataParam = actualHandler.parameters[1];
|
|
97
|
+
const dataParamName = dataParam && ts.isIdentifier(dataParam.name) ? dataParam.name.text : null;
|
|
98
|
+
const requiresData = !(dataParamName && dataParamName.startsWith('_'));
|
|
99
|
+
state.permissions.definitions[pikkuFuncId] = {
|
|
100
|
+
services,
|
|
101
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
102
|
+
sourceFile: node.getSourceFile().fileName,
|
|
103
|
+
position: node.getStart(),
|
|
104
|
+
exportedName,
|
|
105
|
+
name,
|
|
106
|
+
description,
|
|
107
|
+
...(requiresData ? {} : { requiresData: false }),
|
|
108
|
+
};
|
|
109
|
+
logger.debug(`• Found permission with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}${!requiresData ? ' (auth-only)' : ''}`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (expression.text === 'pikkuAuth') {
|
|
113
|
+
if (isInsidePermissionFactory(node))
|
|
114
|
+
return;
|
|
115
|
+
const arg = args[0];
|
|
116
|
+
if (!arg)
|
|
117
|
+
return;
|
|
118
|
+
let actualHandler;
|
|
119
|
+
let name;
|
|
120
|
+
let description;
|
|
121
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
122
|
+
const nameValue = getPropertyValue(arg, 'name');
|
|
123
|
+
const descValue = getPropertyValue(arg, 'description');
|
|
124
|
+
name = typeof nameValue === 'string' ? nameValue : undefined;
|
|
125
|
+
description = typeof descValue === 'string' ? descValue : undefined;
|
|
126
|
+
const fnProp = getPropertyAssignmentInitializer(arg, 'func', true, checker);
|
|
127
|
+
if (!fnProp ||
|
|
128
|
+
(!ts.isArrowFunction(fnProp) && !ts.isFunctionExpression(fnProp))) {
|
|
129
|
+
logger.error(`• pikkuAuth object missing required 'func' property.`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
actualHandler = fnProp;
|
|
133
|
+
}
|
|
134
|
+
else if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
135
|
+
actualHandler = arg;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
logger.error(`• Handler for pikkuAuth is not a function.`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const services = extractServicesFromFunction(actualHandler);
|
|
142
|
+
const wires = extractUsedWires(actualHandler, 1);
|
|
143
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
144
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
145
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
146
|
+
ts.isIdentifier(node.parent.name)) {
|
|
147
|
+
pikkuFuncId = node.parent.name.text;
|
|
148
|
+
}
|
|
149
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
150
|
+
ts.isIdentifier(node.parent.name)) {
|
|
151
|
+
pikkuFuncId = node.parent.name.text;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
logger.error(`• pikkuAuth() must be assigned to a variable or object property. ` +
|
|
155
|
+
`Extract it to a const: const myAuth = pikkuAuth(...)`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
state.permissions.definitions[pikkuFuncId] = {
|
|
52
160
|
services,
|
|
161
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
53
162
|
sourceFile: node.getSourceFile().fileName,
|
|
54
163
|
position: node.getStart(),
|
|
55
164
|
exportedName,
|
|
56
165
|
name,
|
|
57
166
|
description,
|
|
167
|
+
requiresData: false,
|
|
58
168
|
};
|
|
59
|
-
logger.debug(`• Found permission with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`);
|
|
169
|
+
logger.debug(`• Found auth permission with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`);
|
|
60
170
|
return;
|
|
61
171
|
}
|
|
62
172
|
// Handle pikkuPermissionFactory(...) - permission factory function
|
|
@@ -73,6 +183,10 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
73
183
|
// The factory should return pikkuPermission(...), so we need to find that call
|
|
74
184
|
// If no wrapper is found, extract from the factory's returned function directly
|
|
75
185
|
let services = { optimized: false, services: [] };
|
|
186
|
+
let wires = {
|
|
187
|
+
optimized: true,
|
|
188
|
+
wires: [],
|
|
189
|
+
};
|
|
76
190
|
const findPikkuPermissionCall = (node) => {
|
|
77
191
|
if (ts.isCallExpression(node)) {
|
|
78
192
|
const expr = node.expression;
|
|
@@ -88,24 +202,39 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
88
202
|
if (ts.isArrowFunction(permissionHandler) ||
|
|
89
203
|
ts.isFunctionExpression(permissionHandler)) {
|
|
90
204
|
services = extractServicesFromFunction(permissionHandler);
|
|
205
|
+
wires = extractUsedWires(permissionHandler, 2);
|
|
91
206
|
}
|
|
92
207
|
}
|
|
93
208
|
else {
|
|
94
|
-
// No pikkuPermission wrapper found - extract from factory's return value directly
|
|
95
|
-
// Factory pattern: (config) => (services, data, wire) => { ... }
|
|
96
209
|
if (ts.isArrowFunction(factoryNode) ||
|
|
97
210
|
ts.isFunctionExpression(factoryNode)) {
|
|
98
211
|
const factoryBody = factoryNode.body;
|
|
99
|
-
// Check if the body is an arrow function (direct return)
|
|
100
212
|
if (ts.isArrowFunction(factoryBody) ||
|
|
101
213
|
ts.isFunctionExpression(factoryBody)) {
|
|
102
214
|
services = extractServicesFromFunction(factoryBody);
|
|
215
|
+
wires = extractUsedWires(factoryBody, 2);
|
|
103
216
|
}
|
|
104
217
|
}
|
|
105
218
|
}
|
|
106
|
-
|
|
107
|
-
|
|
219
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
220
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
221
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
222
|
+
ts.isIdentifier(node.parent.name)) {
|
|
223
|
+
pikkuFuncId = node.parent.name.text;
|
|
224
|
+
}
|
|
225
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
226
|
+
ts.isIdentifier(node.parent.name)) {
|
|
227
|
+
pikkuFuncId = node.parent.name.text;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
logger.error(`• pikkuPermissionFactory() must be assigned to a variable or object property. ` +
|
|
231
|
+
`Extract it to a const: const myPermission = pikkuPermissionFactory(...)`);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
state.permissions.definitions[pikkuFuncId] = {
|
|
108
236
|
services,
|
|
237
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
109
238
|
sourceFile: node.getSourceFile().fileName,
|
|
110
239
|
position: node.getStart(),
|
|
111
240
|
exportedName,
|
|
@@ -138,38 +267,31 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
138
267
|
logger.error(`• addPermission('${tag}', ...) must have a literal array or object as second argument`);
|
|
139
268
|
return;
|
|
140
269
|
}
|
|
141
|
-
// Extract permission
|
|
270
|
+
// Extract permission pikkuFuncIds from array
|
|
142
271
|
const permissionNames = extractPermissionPikkuNames(permissionsArrayArg, checker, state.rootDir);
|
|
143
272
|
if (permissionNames.length === 0) {
|
|
144
273
|
logger.warn(`• addPermission('${tag}', ...) has empty permissions array`);
|
|
145
274
|
return;
|
|
146
275
|
}
|
|
147
|
-
|
|
276
|
+
renameTempDefinitions(state, permissionNames, 'tag', tag);
|
|
148
277
|
const allServices = new Set();
|
|
149
278
|
for (const permissionName of permissionNames) {
|
|
150
|
-
const permissionMeta = state.permissions.
|
|
279
|
+
const permissionMeta = state.permissions.definitions[permissionName];
|
|
151
280
|
if (permissionMeta && permissionMeta.services) {
|
|
152
281
|
for (const service of permissionMeta.services.services) {
|
|
153
282
|
allServices.add(service);
|
|
154
283
|
}
|
|
155
284
|
}
|
|
156
285
|
}
|
|
157
|
-
// Check if this call is wrapped in a factory function
|
|
158
|
-
// We need to walk up the tree to see if the parent is: const x = () => addPermission(...)
|
|
159
286
|
let isFactory = false;
|
|
160
287
|
let exportedName = null;
|
|
161
288
|
let parent = node.parent;
|
|
162
|
-
// Check if parent is arrow function: () => addPermission(...)
|
|
163
289
|
if (parent && ts.isArrowFunction(parent)) {
|
|
164
|
-
// Check if arrow function has no parameters
|
|
165
290
|
if (parent.parameters.length === 0) {
|
|
166
291
|
isFactory = true;
|
|
167
|
-
// For factories, we need to check the arrow function's parent for the export name
|
|
168
|
-
// const apiTagPermissions = () => addPermission(...)
|
|
169
292
|
const arrowParent = parent.parent;
|
|
170
293
|
if (arrowParent && ts.isVariableDeclaration(arrowParent)) {
|
|
171
294
|
if (ts.isIdentifier(arrowParent.name)) {
|
|
172
|
-
// Check if it's exported
|
|
173
295
|
if (isNamedExport(arrowParent)) {
|
|
174
296
|
exportedName = arrowParent.name.text;
|
|
175
297
|
}
|
|
@@ -177,17 +299,14 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
177
299
|
}
|
|
178
300
|
}
|
|
179
301
|
}
|
|
180
|
-
// If not a factory, get export name from the call expression itself
|
|
181
302
|
if (!isFactory) {
|
|
182
303
|
const extracted = extractFunctionName(node, checker, state.rootDir);
|
|
183
304
|
exportedName = extracted.exportedName;
|
|
184
305
|
}
|
|
185
|
-
// Log warning if not using factory pattern
|
|
186
306
|
if (!isFactory && exportedName) {
|
|
187
307
|
logger.warn(`• Permission group '${exportedName}' for tag '${tag}' is not wrapped in a factory function. ` +
|
|
188
308
|
`For tree-shaking, use: export const ${exportedName} = () => addPermission('${tag}', [...])`);
|
|
189
309
|
}
|
|
190
|
-
// Store group metadata
|
|
191
310
|
state.permissions.tagPermissions.set(tag, {
|
|
192
311
|
exportName: exportedName,
|
|
193
312
|
sourceFile: node.getSourceFile().fileName,
|
|
@@ -196,7 +315,8 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
196
315
|
optimized: false,
|
|
197
316
|
services: Array.from(allServices),
|
|
198
317
|
},
|
|
199
|
-
|
|
318
|
+
count: permissionNames.length,
|
|
319
|
+
instanceIds: permissionNames,
|
|
200
320
|
isFactory,
|
|
201
321
|
});
|
|
202
322
|
logger.debug(`• Found tag permission group: ${tag} -> [${permissionNames.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
@@ -226,37 +346,31 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
226
346
|
logger.error(`• addHTTPPermission('${pattern}', ...) must have a literal array or object as second argument`);
|
|
227
347
|
return;
|
|
228
348
|
}
|
|
229
|
-
// Extract permission
|
|
349
|
+
// Extract permission pikkuFuncIds from array
|
|
230
350
|
const permissionNames = extractPermissionPikkuNames(permissionsArrayArg, checker, state.rootDir);
|
|
231
351
|
if (permissionNames.length === 0) {
|
|
232
352
|
logger.warn(`• addHTTPPermission('${pattern}', ...) has empty permissions array`);
|
|
233
353
|
return;
|
|
234
354
|
}
|
|
235
|
-
|
|
355
|
+
renameTempDefinitions(state, permissionNames, 'http', pattern);
|
|
236
356
|
const allServices = new Set();
|
|
237
357
|
for (const permissionName of permissionNames) {
|
|
238
|
-
const permissionMeta = state.permissions.
|
|
358
|
+
const permissionMeta = state.permissions.definitions[permissionName];
|
|
239
359
|
if (permissionMeta && permissionMeta.services) {
|
|
240
360
|
for (const service of permissionMeta.services.services) {
|
|
241
361
|
allServices.add(service);
|
|
242
362
|
}
|
|
243
363
|
}
|
|
244
364
|
}
|
|
245
|
-
// Check if this call is wrapped in a factory function
|
|
246
365
|
let isFactory = false;
|
|
247
366
|
let exportedName = null;
|
|
248
367
|
let parent = node.parent;
|
|
249
|
-
// Check if parent is arrow function: () => addHTTPPermission(...)
|
|
250
368
|
if (parent && ts.isArrowFunction(parent)) {
|
|
251
|
-
// Check if arrow function has no parameters
|
|
252
369
|
if (parent.parameters.length === 0) {
|
|
253
370
|
isFactory = true;
|
|
254
|
-
// For factories, we need to check the arrow function's parent for the export name
|
|
255
|
-
// const apiRoutePermissions = () => addHTTPPermission(...)
|
|
256
371
|
const arrowParent = parent.parent;
|
|
257
372
|
if (arrowParent && ts.isVariableDeclaration(arrowParent)) {
|
|
258
373
|
if (ts.isIdentifier(arrowParent.name)) {
|
|
259
|
-
// Check if it's exported
|
|
260
374
|
if (isNamedExport(arrowParent)) {
|
|
261
375
|
exportedName = arrowParent.name.text;
|
|
262
376
|
}
|
|
@@ -264,17 +378,14 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
264
378
|
}
|
|
265
379
|
}
|
|
266
380
|
}
|
|
267
|
-
// If not a factory, get export name from the call expression itself
|
|
268
381
|
if (!isFactory) {
|
|
269
382
|
const extracted = extractFunctionName(node, checker, state.rootDir);
|
|
270
383
|
exportedName = extracted.exportedName;
|
|
271
384
|
}
|
|
272
|
-
// Log warning if not using factory pattern
|
|
273
385
|
if (!isFactory && exportedName) {
|
|
274
386
|
logger.warn(`• HTTP permission group '${exportedName}' for pattern '${pattern}' is not wrapped in a factory function. ` +
|
|
275
387
|
`For tree-shaking, use: export const ${exportedName} = () => addHTTPPermission('${pattern}', [...])`);
|
|
276
388
|
}
|
|
277
|
-
// Store group metadata
|
|
278
389
|
state.http.routePermissions.set(pattern, {
|
|
279
390
|
exportName: exportedName,
|
|
280
391
|
sourceFile: node.getSourceFile().fileName,
|
|
@@ -283,7 +394,8 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
283
394
|
optimized: false,
|
|
284
395
|
services: Array.from(allServices),
|
|
285
396
|
},
|
|
286
|
-
|
|
397
|
+
count: permissionNames.length,
|
|
398
|
+
instanceIds: permissionNames,
|
|
287
399
|
isFactory,
|
|
288
400
|
});
|
|
289
401
|
logger.debug(`• Found HTTP route permission group: ${pattern} -> [${permissionNames.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { getPropertyValue, getCommonWireMetaData, } from '../utils/get-property-value.js';
|
|
3
|
-
import { extractFunctionName } from '../utils/extract-function-name.js';
|
|
3
|
+
import { extractFunctionName, makeContextBasedId, } from '../utils/extract-function-name.js';
|
|
4
4
|
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js';
|
|
5
5
|
import { resolveMiddleware } from '../utils/middleware.js';
|
|
6
6
|
import { extractWireNames } from '../utils/post-process.js';
|
|
@@ -21,28 +21,34 @@ export const addQueueWorker = (logger, node, checker, state) => {
|
|
|
21
21
|
}
|
|
22
22
|
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
23
23
|
const obj = firstArg;
|
|
24
|
-
const
|
|
25
|
-
const { tags, summary, description, errors } = getCommonWireMetaData(obj, 'Queue worker',
|
|
24
|
+
const name = getPropertyValue(obj, 'name');
|
|
25
|
+
const { disabled, tags, summary, description, errors } = getCommonWireMetaData(obj, 'Queue worker', name, logger);
|
|
26
|
+
if (disabled)
|
|
27
|
+
return;
|
|
26
28
|
// --- find the referenced function ---
|
|
27
29
|
const funcInitializer = getPropertyAssignmentInitializer(obj, 'func', true, checker);
|
|
28
30
|
if (!funcInitializer) {
|
|
29
|
-
logger.critical(ErrorCode.MISSING_FUNC, `No valid 'func' property for queue processor '${
|
|
31
|
+
logger.critical(ErrorCode.MISSING_FUNC, `No valid 'func' property for queue processor '${name}'.`);
|
|
30
32
|
return;
|
|
31
33
|
}
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const extracted = extractFunctionName(funcInitializer, checker, state.rootDir);
|
|
35
|
+
let pikkuFuncId = extracted.pikkuFuncId;
|
|
36
|
+
if (pikkuFuncId.startsWith('__temp_') && name) {
|
|
37
|
+
pikkuFuncId = makeContextBasedId('queue', name);
|
|
38
|
+
}
|
|
39
|
+
if (!name) {
|
|
40
|
+
logger.critical(ErrorCode.MISSING_QUEUE_NAME, `No 'name' provided for queue processor function '${pikkuFuncId}'.`);
|
|
35
41
|
return;
|
|
36
42
|
}
|
|
37
43
|
// --- resolve middleware ---
|
|
38
44
|
const middleware = resolveMiddleware(state, obj, tags, checker);
|
|
39
45
|
// --- track used functions/middleware for service aggregation ---
|
|
40
|
-
state.serviceAggregation.usedFunctions.add(
|
|
41
|
-
extractWireNames(middleware).forEach((
|
|
46
|
+
state.serviceAggregation.usedFunctions.add(pikkuFuncId);
|
|
47
|
+
extractWireNames(middleware).forEach((n) => state.serviceAggregation.usedMiddleware.add(n));
|
|
42
48
|
state.queueWorkers.files.add(node.getSourceFile().fileName);
|
|
43
|
-
state.queueWorkers.meta[
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
state.queueWorkers.meta[name] = {
|
|
50
|
+
pikkuFuncId,
|
|
51
|
+
name,
|
|
46
52
|
summary,
|
|
47
53
|
description,
|
|
48
54
|
errors,
|
|
@@ -2,5 +2,8 @@ import * as ts from 'typescript';
|
|
|
2
2
|
import { InspectorState, InspectorLogger } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Scan for rpc.invoke() calls to track which functions are actually being invoked
|
|
5
|
+
* Also detects external package usage via:
|
|
6
|
+
* - Namespaced calls: rpc.invoke('namespace:function')
|
|
7
|
+
* - External helper: external('namespace:function')
|
|
5
8
|
*/
|
|
6
9
|
export declare function addRPCInvocations(node: ts.Node, state: InspectorState, logger: InspectorLogger): void;
|
|
@@ -1,35 +1,75 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Helper to extract namespace from a namespaced function reference like 'ext:hello'
|
|
4
|
+
*/
|
|
5
|
+
function extractNamespace(functionRef) {
|
|
6
|
+
const colonIndex = functionRef.indexOf(':');
|
|
7
|
+
if (colonIndex !== -1) {
|
|
8
|
+
return functionRef.substring(0, colonIndex);
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
2
12
|
/**
|
|
3
13
|
* Scan for rpc.invoke() calls to track which functions are actually being invoked
|
|
14
|
+
* Also detects external package usage via:
|
|
15
|
+
* - Namespaced calls: rpc.invoke('namespace:function')
|
|
16
|
+
* - External helper: external('namespace:function')
|
|
4
17
|
*/
|
|
5
18
|
export function addRPCInvocations(node, state, logger) {
|
|
6
|
-
// Look for
|
|
7
|
-
if (ts.
|
|
8
|
-
const { expression,
|
|
9
|
-
// Check
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
// Look for call expressions: external('ext:hello') or rpc.invoke('...')
|
|
20
|
+
if (ts.isCallExpression(node)) {
|
|
21
|
+
const { expression, arguments: args } = node;
|
|
22
|
+
// Check for external('namespace:function') calls
|
|
23
|
+
if (ts.isIdentifier(expression) && expression.text === 'external') {
|
|
24
|
+
const [firstArg] = args;
|
|
25
|
+
if (firstArg && ts.isStringLiteral(firstArg)) {
|
|
26
|
+
const functionRef = firstArg.text;
|
|
27
|
+
logger.debug(`• Found external() call: ${functionRef}`);
|
|
28
|
+
state.rpc.invokedFunctions.add(functionRef);
|
|
29
|
+
const namespace = extractNamespace(functionRef);
|
|
30
|
+
if (namespace) {
|
|
31
|
+
logger.debug(` → External package detected: ${namespace}`);
|
|
32
|
+
state.rpc.usedExternalPackages.add(namespace);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Check for workflow('...'), workflowStart('...'), workflowRun('...'), workflowStatus('...'), graphStart('...') calls
|
|
37
|
+
if (ts.isIdentifier(expression) &&
|
|
38
|
+
(expression.text === 'workflow' ||
|
|
39
|
+
expression.text === 'workflowStart' ||
|
|
40
|
+
expression.text === 'workflowRun' ||
|
|
41
|
+
expression.text === 'workflowStatus' ||
|
|
42
|
+
expression.text === 'graphStart')) {
|
|
43
|
+
const [firstArg] = args;
|
|
44
|
+
if (firstArg && ts.isStringLiteral(firstArg)) {
|
|
45
|
+
const workflowName = firstArg.text;
|
|
46
|
+
logger.debug(`• Found ${expression.text}() call: ${workflowName}`);
|
|
47
|
+
state.workflows.invokedWorkflows.add(workflowName);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Check for rpc.invoke('...') calls
|
|
51
|
+
if (ts.isPropertyAccessExpression(expression) &&
|
|
52
|
+
expression.name.text === 'invoke' &&
|
|
53
|
+
ts.isIdentifier(expression.expression) &&
|
|
54
|
+
expression.expression.text === 'rpc') {
|
|
55
|
+
const [firstArg] = args;
|
|
56
|
+
if (firstArg) {
|
|
57
|
+
if (ts.isStringLiteral(firstArg)) {
|
|
58
|
+
const functionRef = firstArg.text;
|
|
59
|
+
logger.debug(`• Found RPC invocation: ${functionRef}`);
|
|
60
|
+
state.rpc.invokedFunctions.add(functionRef);
|
|
61
|
+
const namespace = extractNamespace(functionRef);
|
|
62
|
+
if (namespace) {
|
|
63
|
+
logger.debug(` → External package detected: ${namespace}`);
|
|
64
|
+
state.rpc.usedExternalPackages.add(namespace);
|
|
31
65
|
}
|
|
32
66
|
}
|
|
67
|
+
// Handle template literals like `function-${name}`
|
|
68
|
+
else if (ts.isTemplateExpression(firstArg) ||
|
|
69
|
+
ts.isNoSubstitutionTemplateLiteral(firstArg)) {
|
|
70
|
+
logger.warn(`• Found dynamic RPC invocation: ${firstArg.getText()}`);
|
|
71
|
+
logger.warn(`\tYou can only use string literals for RPC function names, with ' or " and not \``);
|
|
72
|
+
}
|
|
33
73
|
}
|
|
34
74
|
}
|
|
35
75
|
}
|
package/dist/add/add-schedule.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { getPropertyValue, getCommonWireMetaData, } from '../utils/get-property-value.js';
|
|
3
|
-
import { extractFunctionName } from '../utils/extract-function-name.js';
|
|
3
|
+
import { extractFunctionName, makeContextBasedId, } from '../utils/extract-function-name.js';
|
|
4
4
|
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js';
|
|
5
5
|
import { resolveMiddleware } from '../utils/middleware.js';
|
|
6
6
|
import { extractWireNames } from '../utils/post-process.js';
|
|
@@ -23,24 +23,30 @@ export const addSchedule = (logger, node, checker, state, options) => {
|
|
|
23
23
|
const obj = firstArg;
|
|
24
24
|
const nameValue = getPropertyValue(obj, 'name');
|
|
25
25
|
const scheduleValue = getPropertyValue(obj, 'schedule');
|
|
26
|
-
const { tags, summary, description, errors } = getCommonWireMetaData(obj, 'Scheduler', nameValue, logger);
|
|
26
|
+
const { disabled, tags, summary, description, errors } = getCommonWireMetaData(obj, 'Scheduler', nameValue, logger);
|
|
27
|
+
if (disabled)
|
|
28
|
+
return;
|
|
27
29
|
const funcInitializer = getPropertyAssignmentInitializer(obj, 'func', true, checker);
|
|
28
30
|
if (!funcInitializer) {
|
|
29
31
|
logger.critical(ErrorCode.MISSING_FUNC, `No valid 'func' property for scheduled task '${nameValue}'.`);
|
|
30
32
|
return;
|
|
31
33
|
}
|
|
32
|
-
const
|
|
34
|
+
const extracted = extractFunctionName(funcInitializer, checker, state.rootDir);
|
|
35
|
+
let pikkuFuncId = extracted.pikkuFuncId;
|
|
36
|
+
if (pikkuFuncId.startsWith('__temp_') && nameValue) {
|
|
37
|
+
pikkuFuncId = makeContextBasedId('scheduler', nameValue);
|
|
38
|
+
}
|
|
33
39
|
if (!nameValue || !scheduleValue) {
|
|
34
40
|
return;
|
|
35
41
|
}
|
|
36
42
|
// --- resolve middleware ---
|
|
37
43
|
const middleware = resolveMiddleware(state, obj, tags, checker);
|
|
38
44
|
// --- track used functions/middleware for service aggregation ---
|
|
39
|
-
state.serviceAggregation.usedFunctions.add(
|
|
45
|
+
state.serviceAggregation.usedFunctions.add(pikkuFuncId);
|
|
40
46
|
extractWireNames(middleware).forEach((name) => state.serviceAggregation.usedMiddleware.add(name));
|
|
41
47
|
state.scheduledTasks.files.add(node.getSourceFile().fileName);
|
|
42
48
|
state.scheduledTasks.meta[nameValue] = {
|
|
43
|
-
|
|
49
|
+
pikkuFuncId,
|
|
44
50
|
name: nameValue,
|
|
45
51
|
schedule: scheduleValue,
|
|
46
52
|
summary,
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { getPropertyValue, getArrayPropertyValue, } from '../utils/get-property-value.js';
|
|
3
|
+
import { ErrorCode } from '../error-codes.js';
|
|
4
|
+
import { createAddKeyedWiring } from './add-keyed-wiring.js';
|
|
5
|
+
export const addSecret = createAddKeyedWiring({
|
|
6
|
+
functionName: 'wireSecret',
|
|
7
|
+
idField: 'secretId',
|
|
8
|
+
label: 'Secret',
|
|
9
|
+
schemaPrefix: 'SecretSchema',
|
|
10
|
+
getState: (state) => state.secrets,
|
|
11
|
+
});
|
|
12
|
+
export const addOAuth2Credential = (logger, node, _checker, state, _options) => {
|
|
13
|
+
if (!ts.isCallExpression(node)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const args = node.arguments;
|
|
17
|
+
const firstArg = args[0];
|
|
18
|
+
const expression = node.expression;
|
|
19
|
+
if (!ts.isIdentifier(expression) ||
|
|
20
|
+
expression.text !== 'wireOAuth2Credential') {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!firstArg) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
27
|
+
const obj = firstArg;
|
|
28
|
+
const nameValue = getPropertyValue(obj, 'name');
|
|
29
|
+
const displayNameValue = getPropertyValue(obj, 'displayName');
|
|
30
|
+
const descriptionValue = getPropertyValue(obj, 'description');
|
|
31
|
+
const secretIdValue = getPropertyValue(obj, 'secretId');
|
|
32
|
+
const tokenSecretIdValue = getPropertyValue(obj, 'tokenSecretId');
|
|
33
|
+
const authorizationUrlValue = getPropertyValue(obj, 'authorizationUrl');
|
|
34
|
+
const tokenUrlValue = getPropertyValue(obj, 'tokenUrl');
|
|
35
|
+
const scopesValue = getArrayPropertyValue(obj, 'scopes');
|
|
36
|
+
const pkceValue = getPropertyValue(obj, 'pkce');
|
|
37
|
+
if (!nameValue) {
|
|
38
|
+
logger.critical(ErrorCode.MISSING_NAME, "OAuth2 Credential is missing the required 'name' property.");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!displayNameValue) {
|
|
42
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'displayName' property.`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!secretIdValue) {
|
|
46
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'secretId' property.`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!tokenSecretIdValue) {
|
|
50
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'tokenSecretId' property.`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (!authorizationUrlValue) {
|
|
54
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'authorizationUrl' property.`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!tokenUrlValue) {
|
|
58
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'tokenUrl' property.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!scopesValue || scopesValue.length === 0) {
|
|
62
|
+
logger.critical(ErrorCode.MISSING_NAME, `OAuth2 Credential '${nameValue}' is missing the required 'scopes' property.`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const sourceFile = node.getSourceFile().fileName;
|
|
66
|
+
state.secrets.files.add(sourceFile);
|
|
67
|
+
state.secrets.definitions.push({
|
|
68
|
+
name: nameValue,
|
|
69
|
+
displayName: displayNameValue,
|
|
70
|
+
description: descriptionValue || undefined,
|
|
71
|
+
secretId: secretIdValue,
|
|
72
|
+
oauth2: {
|
|
73
|
+
tokenSecretId: tokenSecretIdValue,
|
|
74
|
+
authorizationUrl: authorizationUrlValue,
|
|
75
|
+
tokenUrl: tokenUrlValue,
|
|
76
|
+
scopes: scopesValue,
|
|
77
|
+
pkce: pkceValue || undefined,
|
|
78
|
+
},
|
|
79
|
+
sourceFile,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|