@pikku/inspector 0.12.4 → 0.12.5

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  ## 0.12.0
2
2
 
3
+ ## 0.12.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 65eccc6: Cache Zod schema generation between re-inspection passes and batch imports by source file. Schemas are cached using a fingerprint of schemaLookup entries + file mtimes, so reinspections skip Zod generation entirely when schemas haven't changed. Source file imports are grouped so each file is imported once instead of per-schema. Reduces `pikku all` from ~5 minutes to ~13 seconds on projects with many Zod schemas.
8
+ - 0f59432: Add per-user credential system with CredentialService, OAuth2 route handlers, and KyselyCredentialService with envelope encryption
9
+ - Updated dependencies [0f59432]
10
+ - Updated dependencies [52b64d1]
11
+ - @pikku/core@0.12.10
12
+
3
13
  ## 0.12.4
4
14
 
5
15
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ import type { AddWiring } from '../types.js';
2
+ export declare const addCredential: AddWiring;
@@ -0,0 +1,118 @@
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 { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js';
5
+ export const addCredential = (logger, node, checker, state, _options) => {
6
+ if (!ts.isCallExpression(node)) {
7
+ return;
8
+ }
9
+ const args = node.arguments;
10
+ const firstArg = args[0];
11
+ const expression = node.expression;
12
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireCredential') {
13
+ return;
14
+ }
15
+ if (!firstArg) {
16
+ return;
17
+ }
18
+ if (ts.isObjectLiteralExpression(firstArg)) {
19
+ const obj = firstArg;
20
+ const nameValue = getPropertyValue(obj, 'name');
21
+ const displayNameValue = getPropertyValue(obj, 'displayName');
22
+ const descriptionValue = getPropertyValue(obj, 'description');
23
+ const typeValue = getPropertyValue(obj, 'type');
24
+ if (!nameValue) {
25
+ logger.critical(ErrorCode.MISSING_NAME, "Credential is missing the required 'name' property.");
26
+ return;
27
+ }
28
+ if (!displayNameValue) {
29
+ logger.critical(ErrorCode.MISSING_NAME, `Credential '${nameValue}' is missing the required 'displayName' property.`);
30
+ return;
31
+ }
32
+ if (!typeValue || (typeValue !== 'singleton' && typeValue !== 'wire')) {
33
+ logger.critical(ErrorCode.MISSING_NAME, `Credential '${nameValue}' is missing or has invalid 'type' property. Must be 'singleton' or 'wire'.`);
34
+ return;
35
+ }
36
+ let schemaVariableName = null;
37
+ let schemaSourceFile = null;
38
+ let schemaIdentifier = null;
39
+ for (const prop of obj.properties) {
40
+ if (ts.isPropertyAssignment(prop) &&
41
+ ts.isIdentifier(prop.name) &&
42
+ prop.name.text === 'schema') {
43
+ if (ts.isIdentifier(prop.initializer)) {
44
+ schemaVariableName = prop.initializer.text;
45
+ schemaIdentifier = prop.initializer;
46
+ const symbol = checker.getSymbolAtLocation(prop.initializer);
47
+ if (symbol) {
48
+ const decl = symbol.valueDeclaration || symbol.declarations?.[0];
49
+ if (decl) {
50
+ if (ts.isImportSpecifier(decl)) {
51
+ const aliasedSymbol = checker.getAliasedSymbol(symbol);
52
+ if (aliasedSymbol) {
53
+ const aliasedDecl = aliasedSymbol.valueDeclaration ||
54
+ aliasedSymbol.declarations?.[0];
55
+ if (aliasedDecl) {
56
+ schemaSourceFile = aliasedDecl.getSourceFile().fileName;
57
+ }
58
+ }
59
+ }
60
+ else {
61
+ schemaSourceFile = decl.getSourceFile().fileName;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ break;
67
+ }
68
+ }
69
+ let oauth2 = undefined;
70
+ const oauth2Prop = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
71
+ ts.isIdentifier(p.name) &&
72
+ p.name.text === 'oauth2');
73
+ if (oauth2Prop &&
74
+ ts.isPropertyAssignment(oauth2Prop) &&
75
+ ts.isObjectLiteralExpression(oauth2Prop.initializer)) {
76
+ const oauth2Obj = oauth2Prop.initializer;
77
+ const appCredentialSecretId = getPropertyValue(oauth2Obj, 'appCredentialSecretId');
78
+ const tokenSecretId = getPropertyValue(oauth2Obj, 'tokenSecretId');
79
+ const authorizationUrl = getPropertyValue(oauth2Obj, 'authorizationUrl');
80
+ const tokenUrl = getPropertyValue(oauth2Obj, 'tokenUrl');
81
+ const scopes = getArrayPropertyValue(oauth2Obj, 'scopes');
82
+ const pkce = getPropertyValue(oauth2Obj, 'pkce');
83
+ if (appCredentialSecretId && authorizationUrl && tokenUrl && scopes) {
84
+ oauth2 = {
85
+ appCredentialSecretId,
86
+ tokenSecretId: tokenSecretId || undefined,
87
+ authorizationUrl,
88
+ tokenUrl,
89
+ scopes,
90
+ pkce: pkce || undefined,
91
+ };
92
+ }
93
+ }
94
+ const sourceFile = node.getSourceFile().fileName;
95
+ state.credentials.files.add(sourceFile);
96
+ let schemaLookupName;
97
+ if (schemaVariableName && schemaSourceFile && schemaIdentifier) {
98
+ const vendor = detectSchemaVendorOrError(schemaIdentifier, checker, logger, `Credential '${nameValue}'`, schemaSourceFile);
99
+ if (vendor) {
100
+ schemaLookupName = `CredentialSchema_${nameValue}`;
101
+ state.schemaLookup.set(schemaLookupName, {
102
+ variableName: schemaVariableName,
103
+ sourceFile: schemaSourceFile,
104
+ vendor,
105
+ });
106
+ }
107
+ }
108
+ state.credentials.definitions.push({
109
+ name: nameValue,
110
+ displayName: displayNameValue,
111
+ description: descriptionValue || undefined,
112
+ type: typeValue,
113
+ schema: schemaLookupName,
114
+ oauth2,
115
+ sourceFile,
116
+ });
117
+ }
118
+ };
@@ -1,3 +1 @@
1
- import type { AddWiring } from '../types.js';
2
- export declare const addSecret: AddWiring;
3
- export declare const addOAuth2Credential: AddWiring;
1
+ export declare const addSecret: import("../types.js").AddWiring;
@@ -1,6 +1,3 @@
1
- import * as ts from 'typescript';
2
- import { getPropertyValue, getArrayPropertyValue, } from '../utils/get-property-value.js';
3
- import { ErrorCode } from '../error-codes.js';
4
1
  import { createAddKeyedWiring } from './add-keyed-wiring.js';
5
2
  export const addSecret = createAddKeyedWiring({
6
3
  functionName: 'wireSecret',
@@ -9,74 +6,3 @@ export const addSecret = createAddKeyedWiring({
9
6
  schemaPrefix: 'SecretSchema',
10
7
  getState: (state) => state.secrets,
11
8
  });
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
- };
package/dist/inspector.js CHANGED
@@ -118,6 +118,10 @@ export function getInitialInspectorState(rootDir) {
118
118
  definitions: [],
119
119
  files: new Set(),
120
120
  },
121
+ credentials: {
122
+ definitions: [],
123
+ files: new Set(),
124
+ },
121
125
  variables: {
122
126
  definitions: [],
123
127
  files: new Set(),
package/dist/types.d.ts CHANGED
@@ -11,6 +11,7 @@ import type { AIAgentMeta } from '@pikku/core/ai-agent';
11
11
  import type { CLIMeta } from '@pikku/core/cli';
12
12
  import type { NodesMeta } from '@pikku/core/node';
13
13
  import type { SecretDefinitions } from '@pikku/core/secret';
14
+ import type { CredentialDefinitions } from '@pikku/core/credential';
14
15
  import type { VariableDefinitions } from '@pikku/core/variable';
15
16
  import type { TypesMap } from './types-map.js';
16
17
  import type { FunctionsMeta, FunctionServicesMeta, FunctionWiresMeta, JSONValue } from '@pikku/core';
@@ -349,6 +350,10 @@ export interface InspectorState {
349
350
  definitions: SecretDefinitions;
350
351
  files: Set<string>;
351
352
  };
353
+ credentials: {
354
+ definitions: CredentialDefinitions;
355
+ files: Set<string>;
356
+ };
352
357
  variables: {
353
358
  definitions: VariableDefinitions;
354
359
  files: Set<string>;
@@ -205,6 +205,10 @@ export interface SerializableInspectorState {
205
205
  definitions: InspectorState['secrets']['definitions'];
206
206
  files: string[];
207
207
  };
208
+ credentials: {
209
+ definitions: InspectorState['credentials']['definitions'];
210
+ files: string[];
211
+ };
208
212
  variables: {
209
213
  definitions: InspectorState['variables']['definitions'];
210
214
  files: string[];
@@ -101,6 +101,10 @@ export function serializeInspectorState(state) {
101
101
  definitions: state.secrets.definitions,
102
102
  files: Array.from(state.secrets.files),
103
103
  },
104
+ credentials: {
105
+ definitions: state.credentials.definitions,
106
+ files: Array.from(state.credentials.files),
107
+ },
104
108
  variables: {
105
109
  definitions: state.variables.definitions,
106
110
  files: Array.from(state.variables.files),
@@ -244,6 +248,10 @@ export function deserializeInspectorState(data) {
244
248
  definitions: data.secrets?.definitions || [],
245
249
  files: new Set(data.secrets?.files || []),
246
250
  },
251
+ credentials: {
252
+ definitions: data.credentials?.definitions || [],
253
+ files: new Set(data.credentials?.files || []),
254
+ },
247
255
  variables: {
248
256
  definitions: data.variables?.definitions || [],
249
257
  files: new Set(data.variables?.files || []),
package/dist/visit.js CHANGED
@@ -17,7 +17,8 @@ import { addWireAddon } from './add/add-wire-addon.js';
17
17
  import { addMiddleware } from './add/add-middleware.js';
18
18
  import { addPermission } from './add/add-permission.js';
19
19
  import { addCLI, addCLIRenderers } from './add/add-cli.js';
20
- import { addSecret, addOAuth2Credential } from './add/add-secret.js';
20
+ import { addSecret } from './add/add-secret.js';
21
+ import { addCredential } from './add/add-credential.js';
21
22
  import { addVariable } from './add/add-variable.js';
22
23
  import { addWorkflowGraph } from './add/add-workflow-graph.js';
23
24
  import { addAIAgent } from './add/add-ai-agent.js';
@@ -41,7 +42,7 @@ export const visitSetup = (logger, checker, node, state, options) => {
41
42
  export const visitRoutes = (logger, checker, node, state, options) => {
42
43
  addFunctions(logger, node, checker, state, options);
43
44
  addSecret(logger, node, checker, state, options);
44
- addOAuth2Credential(logger, node, checker, state, options);
45
+ addCredential(logger, node, checker, state, options);
45
46
  addVariable(logger, node, checker, state, options);
46
47
  addHTTPRoute(logger, node, checker, state, options);
47
48
  addHTTPRoutes(logger, node, checker, state, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/inspector",
3
- "version": "0.12.4",
3
+ "version": "0.12.5",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "BUSL-1.1",
6
6
  "type": "module",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@openapi-contrib/json-schema-to-openapi-schema": "^4.3.1",
38
- "@pikku/core": "^0.12.9",
38
+ "@pikku/core": "^0.12.10",
39
39
  "path-to-regexp": "^8.3.0",
40
40
  "ts-json-schema-generator": "^2.5.0",
41
41
  "tsx": "^4.21.0",
@@ -0,0 +1,178 @@
1
+ import * as ts from 'typescript'
2
+ import {
3
+ getPropertyValue,
4
+ getArrayPropertyValue,
5
+ } from '../utils/get-property-value.js'
6
+ import type { AddWiring } from '../types.js'
7
+ import { ErrorCode } from '../error-codes.js'
8
+ import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
9
+
10
+ export const addCredential: AddWiring = (
11
+ logger,
12
+ node,
13
+ checker,
14
+ state,
15
+ _options
16
+ ) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return
19
+ }
20
+
21
+ const args = node.arguments
22
+ const firstArg = args[0]
23
+ const expression = node.expression
24
+
25
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireCredential') {
26
+ return
27
+ }
28
+
29
+ if (!firstArg) {
30
+ return
31
+ }
32
+
33
+ if (ts.isObjectLiteralExpression(firstArg)) {
34
+ const obj = firstArg
35
+
36
+ const nameValue = getPropertyValue(obj, 'name') as string | null
37
+ const displayNameValue = getPropertyValue(obj, 'displayName') as
38
+ | string
39
+ | null
40
+ const descriptionValue = getPropertyValue(obj, 'description') as
41
+ | string
42
+ | null
43
+ const typeValue = getPropertyValue(obj, 'type') as string | null
44
+
45
+ if (!nameValue) {
46
+ logger.critical(
47
+ ErrorCode.MISSING_NAME,
48
+ "Credential is missing the required 'name' property."
49
+ )
50
+ return
51
+ }
52
+
53
+ if (!displayNameValue) {
54
+ logger.critical(
55
+ ErrorCode.MISSING_NAME,
56
+ `Credential '${nameValue}' is missing the required 'displayName' property.`
57
+ )
58
+ return
59
+ }
60
+
61
+ if (!typeValue || (typeValue !== 'singleton' && typeValue !== 'wire')) {
62
+ logger.critical(
63
+ ErrorCode.MISSING_NAME,
64
+ `Credential '${nameValue}' is missing or has invalid 'type' property. Must be 'singleton' or 'wire'.`
65
+ )
66
+ return
67
+ }
68
+
69
+ let schemaVariableName: string | null = null
70
+ let schemaSourceFile: string | null = null
71
+ let schemaIdentifier: ts.Identifier | null = null
72
+ for (const prop of obj.properties) {
73
+ if (
74
+ ts.isPropertyAssignment(prop) &&
75
+ ts.isIdentifier(prop.name) &&
76
+ prop.name.text === 'schema'
77
+ ) {
78
+ if (ts.isIdentifier(prop.initializer)) {
79
+ schemaVariableName = prop.initializer.text
80
+ schemaIdentifier = prop.initializer
81
+
82
+ const symbol = checker.getSymbolAtLocation(prop.initializer)
83
+ if (symbol) {
84
+ const decl = symbol.valueDeclaration || symbol.declarations?.[0]
85
+ if (decl) {
86
+ if (ts.isImportSpecifier(decl)) {
87
+ const aliasedSymbol = checker.getAliasedSymbol(symbol)
88
+ if (aliasedSymbol) {
89
+ const aliasedDecl =
90
+ aliasedSymbol.valueDeclaration ||
91
+ aliasedSymbol.declarations?.[0]
92
+ if (aliasedDecl) {
93
+ schemaSourceFile = aliasedDecl.getSourceFile().fileName
94
+ }
95
+ }
96
+ } else {
97
+ schemaSourceFile = decl.getSourceFile().fileName
98
+ }
99
+ }
100
+ }
101
+ }
102
+ break
103
+ }
104
+ }
105
+
106
+ let oauth2: any = undefined
107
+ const oauth2Prop = obj.properties.find(
108
+ (p) =>
109
+ ts.isPropertyAssignment(p) &&
110
+ ts.isIdentifier(p.name) &&
111
+ p.name.text === 'oauth2'
112
+ )
113
+ if (
114
+ oauth2Prop &&
115
+ ts.isPropertyAssignment(oauth2Prop) &&
116
+ ts.isObjectLiteralExpression(oauth2Prop.initializer)
117
+ ) {
118
+ const oauth2Obj = oauth2Prop.initializer
119
+ const appCredentialSecretId = getPropertyValue(
120
+ oauth2Obj,
121
+ 'appCredentialSecretId'
122
+ ) as string | null
123
+ const tokenSecretId = getPropertyValue(oauth2Obj, 'tokenSecretId') as
124
+ | string
125
+ | null
126
+ const authorizationUrl = getPropertyValue(
127
+ oauth2Obj,
128
+ 'authorizationUrl'
129
+ ) as string | null
130
+ const tokenUrl = getPropertyValue(oauth2Obj, 'tokenUrl') as string | null
131
+ const scopes = getArrayPropertyValue(oauth2Obj, 'scopes')
132
+ const pkce = getPropertyValue(oauth2Obj, 'pkce') as boolean | null
133
+
134
+ if (appCredentialSecretId && authorizationUrl && tokenUrl && scopes) {
135
+ oauth2 = {
136
+ appCredentialSecretId,
137
+ tokenSecretId: tokenSecretId || undefined,
138
+ authorizationUrl,
139
+ tokenUrl,
140
+ scopes,
141
+ pkce: pkce || undefined,
142
+ }
143
+ }
144
+ }
145
+
146
+ const sourceFile = node.getSourceFile().fileName
147
+ state.credentials.files.add(sourceFile)
148
+
149
+ let schemaLookupName: string | undefined
150
+ if (schemaVariableName && schemaSourceFile && schemaIdentifier) {
151
+ const vendor = detectSchemaVendorOrError(
152
+ schemaIdentifier,
153
+ checker,
154
+ logger,
155
+ `Credential '${nameValue}'`,
156
+ schemaSourceFile
157
+ )
158
+ if (vendor) {
159
+ schemaLookupName = `CredentialSchema_${nameValue}`
160
+ state.schemaLookup.set(schemaLookupName, {
161
+ variableName: schemaVariableName,
162
+ sourceFile: schemaSourceFile,
163
+ vendor,
164
+ })
165
+ }
166
+ }
167
+
168
+ state.credentials.definitions.push({
169
+ name: nameValue,
170
+ displayName: displayNameValue,
171
+ description: descriptionValue || undefined,
172
+ type: typeValue as 'singleton' | 'wire',
173
+ schema: schemaLookupName,
174
+ oauth2,
175
+ sourceFile,
176
+ })
177
+ }
178
+ }
@@ -1,10 +1,3 @@
1
- import * as ts from 'typescript'
2
- import {
3
- getPropertyValue,
4
- getArrayPropertyValue,
5
- } from '../utils/get-property-value.js'
6
- import type { AddWiring } from '../types.js'
7
- import { ErrorCode } from '../error-codes.js'
8
1
  import { createAddKeyedWiring } from './add-keyed-wiring.js'
9
2
 
10
3
  export const addSecret = createAddKeyedWiring({
@@ -14,127 +7,3 @@ export const addSecret = createAddKeyedWiring({
14
7
  schemaPrefix: 'SecretSchema',
15
8
  getState: (state) => state.secrets,
16
9
  })
17
-
18
- export const addOAuth2Credential: 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 (
34
- !ts.isIdentifier(expression) ||
35
- expression.text !== 'wireOAuth2Credential'
36
- ) {
37
- return
38
- }
39
-
40
- if (!firstArg) {
41
- return
42
- }
43
-
44
- if (ts.isObjectLiteralExpression(firstArg)) {
45
- const obj = firstArg
46
-
47
- const nameValue = getPropertyValue(obj, 'name') as string | null
48
- const displayNameValue = getPropertyValue(obj, 'displayName') as
49
- | string
50
- | null
51
- const descriptionValue = getPropertyValue(obj, 'description') as
52
- | string
53
- | null
54
- const secretIdValue = getPropertyValue(obj, 'secretId') as string | null
55
- const tokenSecretIdValue = getPropertyValue(obj, 'tokenSecretId') as
56
- | string
57
- | null
58
- const authorizationUrlValue = getPropertyValue(obj, 'authorizationUrl') as
59
- | string
60
- | null
61
- const tokenUrlValue = getPropertyValue(obj, 'tokenUrl') as string | null
62
- const scopesValue = getArrayPropertyValue(obj, 'scopes')
63
- const pkceValue = getPropertyValue(obj, 'pkce') as boolean | null
64
-
65
- if (!nameValue) {
66
- logger.critical(
67
- ErrorCode.MISSING_NAME,
68
- "OAuth2 Credential is missing the required 'name' property."
69
- )
70
- return
71
- }
72
-
73
- if (!displayNameValue) {
74
- logger.critical(
75
- ErrorCode.MISSING_NAME,
76
- `OAuth2 Credential '${nameValue}' is missing the required 'displayName' property.`
77
- )
78
- return
79
- }
80
-
81
- if (!secretIdValue) {
82
- logger.critical(
83
- ErrorCode.MISSING_NAME,
84
- `OAuth2 Credential '${nameValue}' is missing the required 'secretId' property.`
85
- )
86
- return
87
- }
88
-
89
- if (!tokenSecretIdValue) {
90
- logger.critical(
91
- ErrorCode.MISSING_NAME,
92
- `OAuth2 Credential '${nameValue}' is missing the required 'tokenSecretId' property.`
93
- )
94
- return
95
- }
96
-
97
- if (!authorizationUrlValue) {
98
- logger.critical(
99
- ErrorCode.MISSING_NAME,
100
- `OAuth2 Credential '${nameValue}' is missing the required 'authorizationUrl' property.`
101
- )
102
- return
103
- }
104
-
105
- if (!tokenUrlValue) {
106
- logger.critical(
107
- ErrorCode.MISSING_NAME,
108
- `OAuth2 Credential '${nameValue}' is missing the required 'tokenUrl' property.`
109
- )
110
- return
111
- }
112
-
113
- if (!scopesValue || scopesValue.length === 0) {
114
- logger.critical(
115
- ErrorCode.MISSING_NAME,
116
- `OAuth2 Credential '${nameValue}' is missing the required 'scopes' property.`
117
- )
118
- return
119
- }
120
-
121
- const sourceFile = node.getSourceFile().fileName
122
-
123
- state.secrets.files.add(sourceFile)
124
-
125
- state.secrets.definitions.push({
126
- name: nameValue,
127
- displayName: displayNameValue,
128
- description: descriptionValue || undefined,
129
- secretId: secretIdValue,
130
- oauth2: {
131
- tokenSecretId: tokenSecretIdValue,
132
- authorizationUrl: authorizationUrlValue,
133
- tokenUrl: tokenUrlValue,
134
- scopes: scopesValue,
135
- pkce: pkceValue || undefined,
136
- },
137
- sourceFile,
138
- })
139
- }
140
- }
package/src/inspector.ts CHANGED
@@ -148,6 +148,10 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
148
148
  definitions: [],
149
149
  files: new Set(),
150
150
  },
151
+ credentials: {
152
+ definitions: [],
153
+ files: new Set(),
154
+ },
151
155
  variables: {
152
156
  definitions: [],
153
157
  files: new Set(),
package/src/types.ts CHANGED
@@ -15,6 +15,7 @@ import type { AIAgentMeta } from '@pikku/core/ai-agent'
15
15
  import type { CLIMeta } from '@pikku/core/cli'
16
16
  import type { NodesMeta } from '@pikku/core/node'
17
17
  import type { SecretDefinitions } from '@pikku/core/secret'
18
+ import type { CredentialDefinitions } from '@pikku/core/credential'
18
19
  import type { VariableDefinitions } from '@pikku/core/variable'
19
20
  import type { TypesMap } from './types-map.js'
20
21
  import type {
@@ -379,6 +380,10 @@ export interface InspectorState {
379
380
  definitions: SecretDefinitions
380
381
  files: Set<string>
381
382
  }
383
+ credentials: {
384
+ definitions: CredentialDefinitions
385
+ files: Set<string>
386
+ }
382
387
  variables: {
383
388
  definitions: VariableDefinitions
384
389
  files: Set<string>