@ankhorage/data-sources 0.6.0 → 1.0.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 +6 -0
- package/README.md +5 -5
- package/dist/discovery/index.d.ts +3 -3
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +19 -28
- package/dist/discovery/index.js.map +1 -1
- package/dist/generated-api/index.d.ts +10 -0
- package/dist/generated-api/index.d.ts.map +1 -0
- package/dist/generated-api/index.js +272 -0
- package/dist/generated-api/index.js.map +1 -0
- package/dist/graphql/index.d.ts +3 -3
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js +24 -60
- package/dist/graphql/index.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.d.ts +2 -2
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +19 -29
- package/dist/openapi/index.js.map +1 -1
- package/dist/rest/index.d.ts +3 -3
- package/dist/rest/index.d.ts.map +1 -1
- package/dist/rest/index.js +51 -51
- package/dist/rest/index.js.map +1 -1
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/index.js +60 -104
- package/dist/test-runner/index.js.map +1 -1
- package/package.json +2 -2
- package/src/discovery/index.test.ts +25 -101
- package/src/discovery/index.ts +22 -35
- package/src/{managed-api → generated-api}/index.test.ts +59 -67
- package/src/generated-api/index.ts +410 -0
- package/src/graphql/index.test.ts +28 -134
- package/src/graphql/index.ts +29 -89
- package/src/index.test.ts +25 -18
- package/src/index.ts +28 -7
- package/src/openapi/index.test.ts +36 -246
- package/src/openapi/index.ts +22 -60
- package/src/rest/index.test.ts +22 -173
- package/src/rest/index.ts +62 -59
- package/src/test-runner/index.test.ts +82 -150
- package/src/test-runner/index.ts +73 -143
- package/dist/managed-api/index.d.ts +0 -30
- package/dist/managed-api/index.d.ts.map +0 -1
- package/dist/managed-api/index.js +0 -257
- package/dist/managed-api/index.js.map +0 -1
- package/src/managed-api/index.ts +0 -364
package/src/test-runner/index.ts
CHANGED
|
@@ -90,23 +90,17 @@ interface EndpointOperationSelection {
|
|
|
90
90
|
|
|
91
91
|
export async function testEndpoint(input: EndpointTestInput): Promise<EndpointTestResult> {
|
|
92
92
|
const built = await buildEndpointTestRequest(input);
|
|
93
|
-
|
|
94
|
-
if (!built.ok) return built;
|
|
95
|
-
if (input.dryRun === true) return built;
|
|
93
|
+
if (!built.ok || input.dryRun === true) return built;
|
|
96
94
|
|
|
97
95
|
if (input.fetch === undefined) {
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
'Endpoint test runner requires an injected fetch function.',
|
|
107
|
-
),
|
|
108
|
-
],
|
|
109
|
-
};
|
|
96
|
+
return failure(built.request, [
|
|
97
|
+
...built.diagnostics,
|
|
98
|
+
createDiagnostic(
|
|
99
|
+
input,
|
|
100
|
+
'invalid-config',
|
|
101
|
+
'Endpoint test runner requires an injected fetch function.',
|
|
102
|
+
),
|
|
103
|
+
]);
|
|
110
104
|
}
|
|
111
105
|
|
|
112
106
|
try {
|
|
@@ -117,7 +111,6 @@ export async function testEndpoint(input: EndpointTestInput): Promise<EndpointTe
|
|
|
117
111
|
});
|
|
118
112
|
const responseDiagnostic = await createResponseDiagnostic(response);
|
|
119
113
|
const diagnostics = [...built.diagnostics];
|
|
120
|
-
|
|
121
114
|
if (!responseDiagnostic.ok) {
|
|
122
115
|
diagnostics.push(
|
|
123
116
|
createDiagnostic(
|
|
@@ -127,7 +120,6 @@ export async function testEndpoint(input: EndpointTestInput): Promise<EndpointTe
|
|
|
127
120
|
),
|
|
128
121
|
);
|
|
129
122
|
}
|
|
130
|
-
|
|
131
123
|
return responseDiagnostic.ok
|
|
132
124
|
? {
|
|
133
125
|
ok: true,
|
|
@@ -136,21 +128,12 @@ export async function testEndpoint(input: EndpointTestInput): Promise<EndpointTe
|
|
|
136
128
|
data: responseDiagnostic.parsedBody,
|
|
137
129
|
diagnostics,
|
|
138
130
|
}
|
|
139
|
-
:
|
|
140
|
-
ok: false,
|
|
141
|
-
request: built.request,
|
|
142
|
-
response: responseDiagnostic,
|
|
143
|
-
diagnostics,
|
|
144
|
-
};
|
|
131
|
+
: failure(built.request, diagnostics, responseDiagnostic);
|
|
145
132
|
} catch (error) {
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
...built.diagnostics,
|
|
151
|
-
createDiagnostic(input, 'network-error', createNetworkErrorMessage(error)),
|
|
152
|
-
],
|
|
153
|
-
};
|
|
133
|
+
return failure(built.request, [
|
|
134
|
+
...built.diagnostics,
|
|
135
|
+
createDiagnostic(input, 'network-error', createNetworkErrorMessage(error)),
|
|
136
|
+
]);
|
|
154
137
|
}
|
|
155
138
|
}
|
|
156
139
|
|
|
@@ -159,12 +142,19 @@ export async function buildEndpointTestRequest(
|
|
|
159
142
|
): Promise<EndpointTestResult> {
|
|
160
143
|
const selection = selectEndpointOperation(input);
|
|
161
144
|
if (selection === undefined) {
|
|
162
|
-
return
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
145
|
+
return failure(undefined, [
|
|
146
|
+
createDiagnostic(input, 'missing-operation', 'Endpoint or operation could not be found.'),
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (selection.operation.protocol === 'database') {
|
|
151
|
+
return failure(undefined, [
|
|
152
|
+
createDiagnostic(
|
|
153
|
+
input,
|
|
154
|
+
'invalid-config',
|
|
155
|
+
'Database-backed generated API operations require an adapter executor and cannot be tested through the HTTP endpoint runner.',
|
|
156
|
+
),
|
|
157
|
+
]);
|
|
168
158
|
}
|
|
169
159
|
|
|
170
160
|
const diagnostics: DataSourceDiagnostic[] = [];
|
|
@@ -175,27 +165,15 @@ export async function buildEndpointTestRequest(
|
|
|
175
165
|
: buildHttpRequest(input, selection, credential, diagnostics);
|
|
176
166
|
|
|
177
167
|
if (request === undefined || diagnostics.some((diagnostic) => diagnostic.severity === 'error')) {
|
|
178
|
-
return
|
|
179
|
-
ok: false,
|
|
180
|
-
request,
|
|
181
|
-
diagnostics,
|
|
182
|
-
};
|
|
168
|
+
return failure(request, diagnostics);
|
|
183
169
|
}
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
ok: true,
|
|
187
|
-
request,
|
|
188
|
-
diagnostics,
|
|
189
|
-
};
|
|
170
|
+
return { ok: true, request, diagnostics };
|
|
190
171
|
}
|
|
191
172
|
|
|
192
173
|
function selectEndpointOperation(input: EndpointTestInput): EndpointOperationSelection | undefined {
|
|
193
174
|
const endpoint = input.dataSource.endpoints[input.endpointId];
|
|
194
175
|
const operation = endpoint?.operations[input.operationId];
|
|
195
|
-
|
|
196
|
-
if (endpoint === undefined || operation === undefined) return undefined;
|
|
197
|
-
|
|
198
|
-
return { endpoint, operation };
|
|
176
|
+
return endpoint === undefined || operation === undefined ? undefined : { endpoint, operation };
|
|
199
177
|
}
|
|
200
178
|
|
|
201
179
|
async function resolveEndpointCredential(
|
|
@@ -203,34 +181,25 @@ async function resolveEndpointCredential(
|
|
|
203
181
|
selection: EndpointOperationSelection,
|
|
204
182
|
diagnostics: DataSourceDiagnostic[],
|
|
205
183
|
): Promise<EndpointTestCredential | undefined> {
|
|
206
|
-
const
|
|
184
|
+
const ref =
|
|
207
185
|
selection.operation.credential ?? selection.endpoint.credential ?? input.dataSource.credential;
|
|
208
|
-
|
|
209
|
-
if (credentialRef === undefined) return undefined;
|
|
210
|
-
|
|
186
|
+
if (ref === undefined) return undefined;
|
|
211
187
|
if (input.credentialResolver === undefined) {
|
|
212
188
|
diagnostics.push(
|
|
213
|
-
createDiagnostic(
|
|
214
|
-
input,
|
|
215
|
-
'missing-credential',
|
|
216
|
-
`Credential '${credentialRef.id}' requires a resolver.`,
|
|
217
|
-
),
|
|
189
|
+
createDiagnostic(input, 'missing-credential', `Credential '${ref.id}' requires a resolver.`),
|
|
218
190
|
);
|
|
219
191
|
return undefined;
|
|
220
192
|
}
|
|
221
|
-
|
|
222
|
-
const credential = await input.credentialResolver(credentialRef);
|
|
223
|
-
|
|
193
|
+
const credential = await input.credentialResolver(ref);
|
|
224
194
|
if (credential === undefined) {
|
|
225
195
|
diagnostics.push(
|
|
226
196
|
createDiagnostic(
|
|
227
197
|
input,
|
|
228
198
|
'missing-credential',
|
|
229
|
-
`Credential '${
|
|
199
|
+
`Credential '${ref.id}' could not be resolved.`,
|
|
230
200
|
),
|
|
231
201
|
);
|
|
232
202
|
}
|
|
233
|
-
|
|
234
203
|
return credential;
|
|
235
204
|
}
|
|
236
205
|
|
|
@@ -242,14 +211,12 @@ function buildHttpRequest(
|
|
|
242
211
|
): EndpointTestRequestDiagnostic | undefined {
|
|
243
212
|
const baseUrl = getDataSourceBaseUrl(input.dataSource, selection.endpoint);
|
|
244
213
|
const path = selection.operation.path ?? selection.endpoint.path;
|
|
245
|
-
|
|
246
|
-
if (baseUrl === undefined || baseUrl.trim().length === 0) {
|
|
214
|
+
if (!baseUrl) {
|
|
247
215
|
diagnostics.push(
|
|
248
216
|
createDiagnostic(input, 'invalid-config', 'HTTP endpoint requires a base URL.'),
|
|
249
217
|
);
|
|
250
218
|
return undefined;
|
|
251
219
|
}
|
|
252
|
-
|
|
253
220
|
if (path === undefined) {
|
|
254
221
|
diagnostics.push(createDiagnostic(input, 'invalid-config', 'HTTP operation requires a path.'));
|
|
255
222
|
return undefined;
|
|
@@ -257,23 +224,17 @@ function buildHttpRequest(
|
|
|
257
224
|
|
|
258
225
|
const values = input.values ?? {};
|
|
259
226
|
const parameters = selection.operation.request?.parameters ?? [];
|
|
260
|
-
const
|
|
227
|
+
const resolvedPath = interpolatePath(path, parameters, values, input, diagnostics);
|
|
261
228
|
const query = collectQuery(parameters, values, credential?.query);
|
|
262
|
-
const url = appendQuery(joinUrl(baseUrl, pathResult), query);
|
|
263
229
|
const body = createHttpBody(selection.operation, values);
|
|
264
|
-
const headers: Record<string, string> = {
|
|
265
|
-
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
if (body !== undefined) {
|
|
269
|
-
headers['content-type'] = headers['content-type'] ?? 'application/json';
|
|
270
|
-
}
|
|
230
|
+
const headers: Record<string, string> = { ...(credential?.headers ?? {}) };
|
|
231
|
+
if (body !== undefined) headers['content-type'] = headers['content-type'] ?? 'application/json';
|
|
271
232
|
|
|
272
233
|
return {
|
|
273
234
|
dataSourceId: input.dataSource.id,
|
|
274
235
|
endpointId: input.endpointId,
|
|
275
236
|
operationId: input.operationId,
|
|
276
|
-
url,
|
|
237
|
+
url: appendQuery(joinUrl(baseUrl, resolvedPath), query),
|
|
277
238
|
method: selection.operation.method ?? 'GET',
|
|
278
239
|
headers,
|
|
279
240
|
body,
|
|
@@ -288,8 +249,7 @@ function buildGraphQlRequest(
|
|
|
288
249
|
diagnostics: DataSourceDiagnostic[],
|
|
289
250
|
): EndpointTestRequestDiagnostic | undefined {
|
|
290
251
|
const endpointUrl = getGraphQlEndpointUrl(input.dataSource, selection.endpoint);
|
|
291
|
-
|
|
292
|
-
if (endpointUrl === undefined || endpointUrl.trim().length === 0) {
|
|
252
|
+
if (!endpointUrl) {
|
|
293
253
|
diagnostics.push(
|
|
294
254
|
createDiagnostic(input, 'invalid-config', 'GraphQL endpoint requires an endpoint URL.'),
|
|
295
255
|
);
|
|
@@ -299,7 +259,6 @@ function buildGraphQlRequest(
|
|
|
299
259
|
const query =
|
|
300
260
|
getStringMetadataValue(selection.operation.metadata, 'document') ??
|
|
301
261
|
getStringValue(input.values, 'query');
|
|
302
|
-
|
|
303
262
|
if (query === undefined) {
|
|
304
263
|
diagnostics.push(
|
|
305
264
|
createDiagnostic(input, 'invalid-config', 'GraphQL operation requires a query document.'),
|
|
@@ -308,41 +267,35 @@ function buildGraphQlRequest(
|
|
|
308
267
|
}
|
|
309
268
|
|
|
310
269
|
const variables = getRecordValue(input.values, 'variables');
|
|
311
|
-
const body = JSON.stringify({ query, variables: variables ?? {} });
|
|
312
|
-
const headers: Record<string, string> = {
|
|
313
|
-
...(credential?.headers ?? {}),
|
|
314
|
-
'content-type': 'application/json',
|
|
315
|
-
};
|
|
316
|
-
|
|
317
270
|
return {
|
|
318
271
|
dataSourceId: input.dataSource.id,
|
|
319
272
|
endpointId: input.endpointId,
|
|
320
273
|
operationId: input.operationId,
|
|
321
274
|
url: appendQuery(endpointUrl, credential?.query ?? {}),
|
|
322
275
|
method: 'POST',
|
|
323
|
-
headers,
|
|
324
|
-
body,
|
|
276
|
+
headers: { ...(credential?.headers ?? {}), 'content-type': 'application/json' },
|
|
277
|
+
body: JSON.stringify({ query, variables: variables ?? {} }),
|
|
325
278
|
dryRun: input.dryRun === true,
|
|
326
279
|
};
|
|
327
280
|
}
|
|
328
281
|
|
|
329
282
|
function getDataSourceBaseUrl(
|
|
330
|
-
|
|
283
|
+
source: DataSourceConfig,
|
|
331
284
|
endpoint: DataEndpointConfig,
|
|
332
285
|
): string | undefined {
|
|
333
286
|
if (endpoint.baseUrl !== undefined) return endpoint.baseUrl;
|
|
334
|
-
if (
|
|
335
|
-
|
|
336
|
-
return undefined;
|
|
287
|
+
if (source.kind !== 'api' || source.origin !== 'external') return undefined;
|
|
288
|
+
return source.protocol === 'rest' ? source.baseUrl : source.endpointUrl;
|
|
337
289
|
}
|
|
338
290
|
|
|
339
291
|
function getGraphQlEndpointUrl(
|
|
340
|
-
|
|
292
|
+
source: DataSourceConfig,
|
|
341
293
|
endpoint: DataEndpointConfig,
|
|
342
294
|
): string | undefined {
|
|
343
295
|
if (endpoint.baseUrl !== undefined) return endpoint.baseUrl;
|
|
344
|
-
|
|
345
|
-
|
|
296
|
+
return source.kind === 'api' && source.origin === 'external' && source.protocol === 'graphql'
|
|
297
|
+
? source.endpointUrl
|
|
298
|
+
: undefined;
|
|
346
299
|
}
|
|
347
300
|
|
|
348
301
|
function interpolatePath(
|
|
@@ -352,12 +305,9 @@ function interpolatePath(
|
|
|
352
305
|
input: EndpointTestInput,
|
|
353
306
|
diagnostics: DataSourceDiagnostic[],
|
|
354
307
|
): string {
|
|
355
|
-
let
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
for (const parameter of pathParameters) {
|
|
308
|
+
let next = path;
|
|
309
|
+
for (const parameter of parameters.filter((item) => item.location === 'path')) {
|
|
359
310
|
const value = values[parameter.name] ?? parameter.default;
|
|
360
|
-
|
|
361
311
|
if (value === undefined) {
|
|
362
312
|
diagnostics.push(
|
|
363
313
|
createDiagnostic(
|
|
@@ -368,13 +318,12 @@ function interpolatePath(
|
|
|
368
318
|
);
|
|
369
319
|
continue;
|
|
370
320
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
321
|
+
const encoded = encodeURIComponent(serializeEndpointUrlValue(value));
|
|
322
|
+
next = next
|
|
323
|
+
.replaceAll(`{${parameter.name}}`, encoded)
|
|
324
|
+
.replaceAll(`:${parameter.name}`, encoded);
|
|
375
325
|
}
|
|
376
|
-
|
|
377
|
-
return nextPath;
|
|
326
|
+
return next;
|
|
378
327
|
}
|
|
379
328
|
|
|
380
329
|
function collectQuery(
|
|
@@ -383,14 +332,11 @@ function collectQuery(
|
|
|
383
332
|
credentialQuery: EndpointTestInputValues | undefined,
|
|
384
333
|
): EndpointTestInputValues {
|
|
385
334
|
const query: Record<string, DataContractValue> = { ...(credentialQuery ?? {}) };
|
|
386
|
-
|
|
387
335
|
for (const parameter of parameters) {
|
|
388
336
|
if (parameter.location !== 'query') continue;
|
|
389
|
-
|
|
390
337
|
const value = values[parameter.name] ?? parameter.default;
|
|
391
338
|
if (value !== undefined) query[parameter.name] = value;
|
|
392
339
|
}
|
|
393
|
-
|
|
394
340
|
return query;
|
|
395
341
|
}
|
|
396
342
|
|
|
@@ -399,31 +345,24 @@ function createHttpBody(
|
|
|
399
345
|
values: EndpointTestInputValues,
|
|
400
346
|
): string | undefined {
|
|
401
347
|
if (operation.method === 'GET' || operation.method === 'HEAD') return undefined;
|
|
402
|
-
|
|
403
|
-
const { body } = values;
|
|
404
|
-
if (body === undefined) return undefined;
|
|
405
|
-
|
|
406
|
-
return JSON.stringify(body);
|
|
348
|
+
return values.body === undefined ? undefined : JSON.stringify(values.body);
|
|
407
349
|
}
|
|
408
350
|
|
|
409
351
|
async function createResponseDiagnostic(
|
|
410
352
|
response: EndpointTestFetchResponse,
|
|
411
353
|
): Promise<EndpointTestResponseDiagnostic> {
|
|
412
354
|
const bodyText = await response.text();
|
|
413
|
-
const parsedBody = parseResponseBody(bodyText);
|
|
414
|
-
|
|
415
355
|
return {
|
|
416
356
|
status: response.status,
|
|
417
357
|
ok: response.status >= 200 && response.status < 300,
|
|
418
358
|
headers: response.headers,
|
|
419
359
|
bodyText,
|
|
420
|
-
parsedBody,
|
|
360
|
+
parsedBody: parseResponseBody(bodyText),
|
|
421
361
|
};
|
|
422
362
|
}
|
|
423
363
|
|
|
424
364
|
function parseResponseBody(bodyText: string): DataContractValue | undefined {
|
|
425
365
|
if (bodyText.trim().length === 0) return undefined;
|
|
426
|
-
|
|
427
366
|
try {
|
|
428
367
|
const parsed: unknown = JSON.parse(bodyText);
|
|
429
368
|
return isDataContractValue(parsed) ? parsed : { raw: bodyText };
|
|
@@ -435,31 +374,26 @@ function parseResponseBody(bodyText: string): DataContractValue | undefined {
|
|
|
435
374
|
function appendQuery(url: string, query: EndpointTestInputValues): string {
|
|
436
375
|
const entries = Object.entries(query);
|
|
437
376
|
if (entries.length === 0) return url;
|
|
438
|
-
|
|
439
377
|
const search = entries
|
|
440
378
|
.map(
|
|
441
379
|
([key, value]) =>
|
|
442
380
|
`${encodeURIComponent(key)}=${encodeURIComponent(serializeEndpointUrlValue(value))}`,
|
|
443
381
|
)
|
|
444
382
|
.join('&');
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return `${url}${separator}${search}`;
|
|
383
|
+
return `${url}${url.includes('?') ? '&' : '?'}${search}`;
|
|
448
384
|
}
|
|
449
385
|
|
|
450
386
|
function serializeEndpointUrlValue(value: DataContractValue): string {
|
|
451
387
|
if (typeof value === 'string') return value;
|
|
452
388
|
if (typeof value === 'number' || typeof value === 'boolean') return value.toString();
|
|
453
389
|
if (value === null) return '';
|
|
454
|
-
|
|
455
390
|
return JSON.stringify(value);
|
|
456
391
|
}
|
|
457
392
|
|
|
458
393
|
function joinUrl(baseUrl: string, path: string): string {
|
|
459
|
-
const
|
|
394
|
+
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
460
395
|
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
461
|
-
|
|
462
|
-
return `${normalizedBase}${normalizedPath}`;
|
|
396
|
+
return `${normalizedBaseUrl}${normalizedPath}`;
|
|
463
397
|
}
|
|
464
398
|
|
|
465
399
|
function getStringValue(
|
|
@@ -483,7 +417,6 @@ function getStringMetadataValue(
|
|
|
483
417
|
key: string,
|
|
484
418
|
): string | undefined {
|
|
485
419
|
if (!isDataContractRecord(metadata)) return undefined;
|
|
486
|
-
|
|
487
420
|
const value = metadata[key];
|
|
488
421
|
return typeof value === 'string' ? value : undefined;
|
|
489
422
|
}
|
|
@@ -503,25 +436,22 @@ function createDiagnostic(
|
|
|
503
436
|
};
|
|
504
437
|
}
|
|
505
438
|
|
|
439
|
+
function failure(
|
|
440
|
+
request: EndpointTestRequestDiagnostic | undefined,
|
|
441
|
+
diagnostics: readonly DataSourceDiagnostic[],
|
|
442
|
+
response?: EndpointTestResponseDiagnostic,
|
|
443
|
+
): EndpointTestResult {
|
|
444
|
+
return { ok: false, request, response, diagnostics };
|
|
445
|
+
}
|
|
446
|
+
|
|
506
447
|
function createNetworkErrorMessage(error: unknown): string {
|
|
507
|
-
|
|
508
|
-
return 'Endpoint test request failed.';
|
|
448
|
+
return error instanceof Error ? error.message : 'Endpoint test request failed.';
|
|
509
449
|
}
|
|
510
450
|
|
|
511
451
|
function isDataContractValue(value: unknown): value is DataContractValue {
|
|
512
|
-
if (
|
|
513
|
-
value === null ||
|
|
514
|
-
typeof value === 'string' ||
|
|
515
|
-
typeof value === 'number' ||
|
|
516
|
-
typeof value === 'boolean'
|
|
517
|
-
) {
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
|
|
452
|
+
if (value === null || ['string', 'number', 'boolean'].includes(typeof value)) return true;
|
|
521
453
|
if (Array.isArray(value)) return value.every(isDataContractValue);
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
return Object.values(value).every(isDataContractValue);
|
|
454
|
+
return typeof value === 'object' && Object.values(value).every(isDataContractValue);
|
|
525
455
|
}
|
|
526
456
|
|
|
527
457
|
function isDataContractRecord(
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { AdapterRef, DataEndpointConfig, DataOperationConfig, DataSchema, DataSourceDiagnostic, DataSourceDiagnosticResult, ManagedApiDataSourceConfig, OperationId } from '@ankhorage/contracts/data';
|
|
2
|
-
import type { DbCollectionDefinition } from '@ankhorage/contracts/db';
|
|
3
|
-
export declare const MANAGED_API_CRUD_OPERATIONS: readonly ["list", "read", "create", "update", "delete"];
|
|
4
|
-
export type ManagedApiCrudOperation = (typeof MANAGED_API_CRUD_OPERATIONS)[number];
|
|
5
|
-
export interface ManagedApiOperationPolicyRef {
|
|
6
|
-
readonly id: string;
|
|
7
|
-
readonly operation?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface ManagedApiGenerationResourceDefinition {
|
|
10
|
-
readonly name: string;
|
|
11
|
-
readonly collection: DbCollectionDefinition;
|
|
12
|
-
readonly operations?: readonly ManagedApiCrudOperation[];
|
|
13
|
-
readonly policies?: readonly ManagedApiOperationPolicyRef[];
|
|
14
|
-
}
|
|
15
|
-
export interface ManagedApiGenerationDefinition {
|
|
16
|
-
readonly id: string;
|
|
17
|
-
readonly adapter: AdapterRef;
|
|
18
|
-
readonly name?: string;
|
|
19
|
-
readonly description?: string;
|
|
20
|
-
readonly resources: readonly ManagedApiGenerationResourceDefinition[];
|
|
21
|
-
}
|
|
22
|
-
export declare function createManagedApiDataSource(definition: ManagedApiGenerationDefinition): DataSourceDiagnosticResult<ManagedApiDataSourceConfig>;
|
|
23
|
-
export declare function validateManagedApiDefinition(definition: ManagedApiGenerationDefinition): readonly DataSourceDiagnostic[];
|
|
24
|
-
export declare function normalizeManagedApiDataSource(definition: ManagedApiGenerationDefinition): ManagedApiDataSourceConfig;
|
|
25
|
-
export declare function createManagedApiEndpoint(definition: ManagedApiGenerationDefinition, resource: ManagedApiGenerationResourceDefinition, operations?: readonly ManagedApiCrudOperation[]): DataEndpointConfig;
|
|
26
|
-
export declare function createManagedApiOperation(definition: ManagedApiGenerationDefinition, resource: ManagedApiGenerationResourceDefinition, operation: ManagedApiCrudOperation): DataOperationConfig;
|
|
27
|
-
export declare function getManagedApiOperations(resource: ManagedApiGenerationResourceDefinition): readonly ManagedApiCrudOperation[];
|
|
28
|
-
export declare function createManagedApiOperationId(resourceName: string, operation: ManagedApiCrudOperation): OperationId;
|
|
29
|
-
export declare function createManagedApiResourceSchema(collection: DbCollectionDefinition): DataSchema;
|
|
30
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/managed-api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAClB,mBAAmB,EAGnB,UAAU,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAE1B,WAAW,EACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACV,sBAAsB,EAGvB,MAAM,yBAAyB,CAAC;AAEjC,eAAO,MAAM,2BAA2B,yDAA0D,CAAC;AAEnG,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,4BAA4B,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,sCAAsC,EAAE,CAAC;CACvE;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,8BAA8B,GACzC,0BAA0B,CAAC,0BAA0B,CAAC,CAWxD;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,8BAA8B,GACzC,SAAS,oBAAoB,EAAE,CAsDjC;AAED,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,8BAA8B,GACzC,0BAA0B,CA6B5B;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,8BAA8B,EAC1C,QAAQ,EAAE,sCAAsC,EAChD,UAAU,GAAE,SAAS,uBAAuB,EAAsC,GACjF,kBAAkB,CAmBpB;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,8BAA8B,EAC1C,QAAQ,EAAE,sCAAsC,EAChD,SAAS,EAAE,uBAAuB,GACjC,mBAAmB,CAsBrB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,sCAAsC,GAC/C,SAAS,uBAAuB,EAAE,CAEpC;AAED,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,uBAAuB,GACjC,WAAW,CAEb;AAED,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,sBAAsB,GAAG,UAAU,CAe7F"}
|