@jskit-ai/http-runtime 0.1.243 → 0.1.244
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/package.json +6 -35
- package/src/client/index.js +2 -3
- package/src/shared/clientRuntime/client.js +1 -57
- package/src/shared/clientRuntime/errors.js +39 -2
- package/src/shared/clientRuntime/jsonApiResourceTransport.js +27 -39
- package/src/shared/index.js +2 -21
- package/src/shared/validators/errorResponses.js +1 -13
- package/src/shared/validators/jsonApiQueryTransport.js +1 -5
- package/src/shared/validators/jsonApiRouteTransport.js +43 -54
- package/src/shared/validators/jsonApiTransport.js +1 -5
- package/src/shared/validators/operationValidation.js +5 -92
- package/test/client.test.js +29 -0
- package/test/entrypoints.boundary.test.js +15 -14
- package/test/errorResponses.test.js +0 -11
- package/test/jsonApiRouteTransport.test.js +12 -7
- package/test/operationValidation.test.js +13 -61
- package/test/transientRetryHttpClient.test.js +11 -0
- package/test/validationErrors.test.js +20 -9
- package/src/client/providers/HttpClientRuntimeClientProvider.js +0 -20
- package/src/client/providers/HttpValidatorsClientProvider.js +0 -16
- package/src/server/providers/HttpClientProvider.js +0 -16
- package/src/server/providers/HttpValidatorsProvider.js +0 -16
- package/src/shared/clientRuntime/index.js +0 -4
- package/src/shared/validators/command.js +0 -24
- package/src/shared/validators/httpValidatorsApi.js +0 -129
- package/src/shared/validators/jsonApiResponses.js +0 -3
- package/src/shared/validators/operationMessages.js +0 -318
- package/src/shared/validators/paginationQuery.js +0 -27
- package/src/shared/validators/resource.js +0 -41
- package/test/command.test.js +0 -66
- package/test/operationMessages.test.js +0 -197
- package/test/paginationQuery.test.js +0 -28
- package/test/providerRuntime.httpClient.test.js +0 -22
- package/test/providerRuntime.validators.test.js +0 -22
- package/test/resource.test.js +0 -128
package/test/client.test.js
CHANGED
|
@@ -665,6 +665,35 @@ test("request decodes json:api collection responses into JSKIT paged-list shape"
|
|
|
665
665
|
});
|
|
666
666
|
});
|
|
667
667
|
|
|
668
|
+
test("request keeps collection resources without ids as distinct records", async () => {
|
|
669
|
+
const fetchImpl = async () =>
|
|
670
|
+
mockResponse({
|
|
671
|
+
contentType: "application/vnd.api+json",
|
|
672
|
+
data: {
|
|
673
|
+
data: [
|
|
674
|
+
{ type: "books", attributes: { title: "First" } },
|
|
675
|
+
{ type: "books", attributes: { title: "Second" } }
|
|
676
|
+
]
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
const client = createHttpClient({ fetchImpl });
|
|
681
|
+
const payload = await client.request("/api/books", {
|
|
682
|
+
method: "GET",
|
|
683
|
+
transport: {
|
|
684
|
+
kind: "jsonapi-resource",
|
|
685
|
+
responseType: "books",
|
|
686
|
+
responseKind: "collection"
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
assert.deepEqual(
|
|
691
|
+
payload.items.map((item) => item.title),
|
|
692
|
+
["First", "Second"]
|
|
693
|
+
);
|
|
694
|
+
assert.notEqual(payload.items[0], payload.items[1]);
|
|
695
|
+
});
|
|
696
|
+
|
|
668
697
|
test("request decodes native json-rest-api collection pagination metadata into JSKIT nextCursor", async () => {
|
|
669
698
|
const fetchImpl = async () =>
|
|
670
699
|
mockResponse({
|
|
@@ -4,8 +4,6 @@ import test from "node:test";
|
|
|
4
4
|
|
|
5
5
|
import * as clientApi from "../src/client/index.js";
|
|
6
6
|
import * as sharedApi from "../src/shared/index.js";
|
|
7
|
-
import { HttpValidatorsProvider } from "../src/server/providers/HttpValidatorsProvider.js";
|
|
8
|
-
import { HttpClientProvider } from "../src/server/providers/HttpClientProvider.js";
|
|
9
7
|
|
|
10
8
|
test("package exports include explicit shared entrypoint and no server barrel", async () => {
|
|
11
9
|
const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
@@ -14,24 +12,25 @@ test("package exports include explicit shared entrypoint and no server barrel",
|
|
|
14
12
|
assert.equal(exportsMap["./shared"], "./src/shared/index.js");
|
|
15
13
|
});
|
|
16
14
|
|
|
17
|
-
test("
|
|
15
|
+
test("package registers no container providers; callers import its functions directly", async () => {
|
|
16
|
+
const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
17
|
+
assert.deepEqual(packageJson.jskit.capabilities.provides, []);
|
|
18
|
+
assert.deepEqual(packageJson.jskit.runtime.server.providers, []);
|
|
19
|
+
assert.deepEqual(packageJson.jskit.runtime.client.providers, []);
|
|
20
|
+
for (const surface of packageJson.jskit.metadata.apiSummary.surfaces) {
|
|
21
|
+
assert.ok(packageJson.exports[surface.subpath], `apiSummary names a real export: ${surface.subpath}`);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("client entrypoint exports client runtime helpers only", () => {
|
|
18
26
|
assert.equal(typeof clientApi.createHttpClient, "function");
|
|
19
27
|
assert.equal(typeof clientApi.createTransientRetryHttpClient, "function");
|
|
20
|
-
assert.equal(clientApi.HttpValidatorsClientProvider.id, "validators.http.client");
|
|
21
|
-
assert.equal(clientApi.HttpClientRuntimeClientProvider.id, "runtime.http-client.client");
|
|
22
28
|
assert.equal(typeof clientApi.withStandardErrorResponses, "undefined");
|
|
23
29
|
});
|
|
24
30
|
|
|
25
|
-
test("server provider modules export declarative providers only", () => {
|
|
26
|
-
assert.equal(HttpValidatorsProvider.id, "validators.http");
|
|
27
|
-
assert.equal(HttpClientProvider.id, "runtime.http-client");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
31
|
test("shared entrypoint exports shared validators only", () => {
|
|
31
32
|
assert.equal(typeof sharedApi.withStandardErrorResponses, "function");
|
|
32
|
-
assert.equal(typeof sharedApi.
|
|
33
|
-
assert.equal(typeof sharedApi.createResource, "function");
|
|
34
|
-
assert.equal(typeof sharedApi.createCommand, "function");
|
|
33
|
+
assert.equal(typeof sharedApi.validateOperationSection, "function");
|
|
35
34
|
assert.equal(typeof sharedApi.createJsonApiDocument, "function");
|
|
36
35
|
assert.equal(typeof sharedApi.createJsonApiErrorDocumentFromFailure, "function");
|
|
37
36
|
assert.equal(typeof sharedApi.normalizeJsonApiDocument, "function");
|
|
@@ -41,5 +40,7 @@ test("shared entrypoint exports shared validators only", () => {
|
|
|
41
40
|
assert.equal(typeof sharedApi.createJsonApiResourceRouteContract, "function");
|
|
42
41
|
assert.equal(typeof sharedApi.withJsonApiErrorResponses, "function");
|
|
43
42
|
assert.equal(typeof sharedApi.createHttpClient, "undefined");
|
|
44
|
-
|
|
43
|
+
for (const removed of ["createResource", "createCommand", "createPaginationQuerySchema", "mapOperationIssues", "enumSchema", "passthroughErrorResponses"]) {
|
|
44
|
+
assert.equal(typeof sharedApi[removed], "undefined", removed);
|
|
45
|
+
}
|
|
45
46
|
});
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
apiErrorTransportSchema,
|
|
9
9
|
apiValidationErrorTransportSchema,
|
|
10
10
|
fastifyDefaultErrorTransportSchema,
|
|
11
|
-
enumSchema,
|
|
12
11
|
createTransportResponseSchema,
|
|
13
12
|
withStandardErrorResponses
|
|
14
13
|
} from "../src/shared/validators/errorResponses.js";
|
|
@@ -93,16 +92,6 @@ test("withStandardErrorResponses does not override existing error schemas", () =
|
|
|
93
92
|
assert.equal(responses[400].transportSchema, custom400);
|
|
94
93
|
});
|
|
95
94
|
|
|
96
|
-
test("enumSchema creates a literal union", () => {
|
|
97
|
-
const schema = enumSchema(["one", "two", "three"]);
|
|
98
|
-
|
|
99
|
-
assert.equal(schema.anyOf.length, 3);
|
|
100
|
-
assert.deepEqual(
|
|
101
|
-
schema.anyOf.map((entry) => entry.const),
|
|
102
|
-
["one", "two", "three"]
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
95
|
test("error response validators export transport schemas from the same contracts", () => {
|
|
107
96
|
assert.equal(apiErrorOutputValidator.mode, "replace");
|
|
108
97
|
assert.equal(apiValidationErrorOutputValidator.mode, "replace");
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
} from "../src/shared/index.js";
|
|
30
30
|
import { createSchema } from "../../kernel/shared/validators/index.js";
|
|
31
31
|
import { resolveRouteValidatorOptions } from "../../kernel/server/http/lib/routeValidator.js";
|
|
32
|
-
import { registerApiErrorHandler } from "../../kernel/server/
|
|
32
|
+
import { registerApiErrorHandler } from "../../kernel/server/http/errorHandling.js";
|
|
33
33
|
import { AppError, isAppError } from "../../kernel/server/runtime/errors.js";
|
|
34
34
|
import { createHttpError } from "../src/shared/clientRuntime/errors.js";
|
|
35
35
|
import { createJsonRestApiHost } from "../../json-rest-api-core/src/server/jsonRestApiHost.js";
|
|
@@ -141,6 +141,11 @@ test("createJsonApiResourceSuccessTransportSchema wraps plain record schema in a
|
|
|
141
141
|
const resourceSchema = schema.definitions.contactsSuccessResource;
|
|
142
142
|
assert.deepEqual(resourceSchema.required, ["type", "attributes", "id"]);
|
|
143
143
|
assert.equal(resourceSchema.properties.type.const, "contacts");
|
|
144
|
+
|
|
145
|
+
const referencedNames = new Set(
|
|
146
|
+
[...JSON.stringify(schema).matchAll(/"#\/definitions\/([^"]+)"/g)].map((match) => match[1])
|
|
147
|
+
);
|
|
148
|
+
assert.deepEqual(Object.keys(schema.definitions).sort(), [...referencedNames].sort());
|
|
144
149
|
});
|
|
145
150
|
|
|
146
151
|
test("createJsonApiResourceRouteTransport unwraps request payloads and wraps resource/error responses", () => {
|
|
@@ -242,7 +247,7 @@ test("real HTTP responses classify typed JSON REST read and write errors", async
|
|
|
242
247
|
for (const wrapped of [false, true]) {
|
|
243
248
|
const prefix = `/${jsonapi ? "jsonapi" : "plain"}/${wrapped ? "write" : "read"}`;
|
|
244
249
|
app.get(`${prefix}/:kind`, {
|
|
245
|
-
config: jsonapi ? { transport
|
|
250
|
+
config: jsonapi ? { transport } : {},
|
|
246
251
|
...(jsonapi ? {} : { schema: { response: { "4xx": apiErrorTransportSchema, "5xx": apiErrorTransportSchema } } })
|
|
247
252
|
}, async (request) => {
|
|
248
253
|
const [, createError] = cases.find(([name]) => name === request.params.kind);
|
|
@@ -306,7 +311,7 @@ test("real resource validation, permission hooks and completion failures retain
|
|
|
306
311
|
const transport = createJsonApiResourceRouteTransport({ type: "books" });
|
|
307
312
|
for (const jsonapi of [false, true]) {
|
|
308
313
|
const prefix = `/${jsonapi ? "jsonapi" : "plain"}`;
|
|
309
|
-
const options = { config: jsonapi ? { transport
|
|
314
|
+
const options = { config: jsonapi ? { transport } : {} };
|
|
310
315
|
app.get(`${prefix}/denied`, options, async () => api.resources.books.query({}, { deny: true }));
|
|
311
316
|
app.post(`${prefix}/invalid`, options, async (request) => api.resources.books.post({ data: request.body }));
|
|
312
317
|
app.post(`${prefix}/committed`, options, async (request) => api.resources.books.post({ data: request.body }, { failAfterCommit: true }));
|
|
@@ -336,7 +341,7 @@ test("real resource validation, permission hooks and completion failures retain
|
|
|
336
341
|
|
|
337
342
|
test("error handler, JSON:API transport and client preserve outcomes without disclosing internal failures", () => {
|
|
338
343
|
const transport = createJsonApiResourceRouteTransport({ type: "books" });
|
|
339
|
-
const app = { log: { error() {} }, setErrorHandler(handler) { this.errorHandler = handler; } };
|
|
344
|
+
const app = { log: { error() {}, info() {} }, setErrorHandler(handler) { this.errorHandler = handler; } };
|
|
340
345
|
registerApiErrorHandler(app, { isAppError });
|
|
341
346
|
|
|
342
347
|
for (const transactionOutcome of ["none", "pending", "committed", "rolledBack", "unknown", "invalid", undefined]) {
|
|
@@ -355,7 +360,7 @@ test("error handler, JSON:API transport and client preserve outcomes without dis
|
|
|
355
360
|
header(name, value) { this.headers[name] = value; return this; },
|
|
356
361
|
send(payload) { this.payload = payload; return this; }
|
|
357
362
|
};
|
|
358
|
-
app.errorHandler(failure, jsonapi ? {
|
|
363
|
+
app.errorHandler(failure, jsonapi ? { routeOptions: { config: { transport } } } : {}, reply);
|
|
359
364
|
assert.equal(reply.statusCode, 500);
|
|
360
365
|
const clientError = createHttpError({ status: reply.statusCode }, reply.payload);
|
|
361
366
|
assert.equal(clientError.message, "Internal server error.");
|
|
@@ -382,7 +387,7 @@ test("JSON:API field errors retain outcomes and permission details remain privat
|
|
|
382
387
|
assert.equal(payload.errors.length, 2);
|
|
383
388
|
assert.ok(payload.errors.every((error) => error.meta.transactionOutcome === "rolledBack"));
|
|
384
389
|
|
|
385
|
-
const app = { log: { error() {} }, setErrorHandler(handler) { this.errorHandler = handler; } };
|
|
390
|
+
const app = { log: { error() {}, info() {} }, setErrorHandler(handler) { this.errorHandler = handler; } };
|
|
386
391
|
registerApiErrorHandler(app, { isAppError });
|
|
387
392
|
const reply = {
|
|
388
393
|
code() { return this; },
|
|
@@ -392,7 +397,7 @@ test("JSON:API field errors retain outcomes and permission details remain privat
|
|
|
392
397
|
app.errorHandler(new AppError(403, "Forbidden.", {
|
|
393
398
|
code: "ACTION_PERMISSION_DENIED",
|
|
394
399
|
details: { fieldErrors: { secret: "Required private permission" } }
|
|
395
|
-
}), {
|
|
400
|
+
}), { routeOptions: { config: { transport } } }, reply);
|
|
396
401
|
assert.deepEqual(reply.payload, {
|
|
397
402
|
errors: [{ status: "403", code: "ACTION_PERMISSION_DENIED", title: "Forbidden." }]
|
|
398
403
|
});
|
|
@@ -2,10 +2,7 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import { createSchema } from "json-rest-schema";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
validateOperationInput,
|
|
7
|
-
validateOperationSection
|
|
8
|
-
} from "../src/shared/validators/operationValidation.js";
|
|
5
|
+
import { validateOperationSection } from "../src/shared/validators/operationValidation.js";
|
|
9
6
|
|
|
10
7
|
const patchOperation = Object.freeze({
|
|
11
8
|
method: "PATCH",
|
|
@@ -194,66 +191,21 @@ test("validateOperationSection surfaces custom validator failures as field error
|
|
|
194
191
|
|
|
195
192
|
assert.equal(parsed.ok, false);
|
|
196
193
|
assert.equal(parsed.fieldErrors.adenovirusValidTo, "Adenovirus valid-to date is required when vaccinated.");
|
|
197
|
-
assert.deepEqual(parsed.
|
|
194
|
+
assert.deepEqual(Object.keys(parsed).sort(), ["fieldErrors", "ok", "value"]);
|
|
198
195
|
});
|
|
199
196
|
|
|
200
|
-
test("
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
workspaceSlug: { type: "string", required: true, minLength: 1 }
|
|
206
|
-
}),
|
|
207
|
-
mode: "patch"
|
|
208
|
-
},
|
|
209
|
-
query: {
|
|
210
|
-
schema: createSchema({
|
|
211
|
-
includeArchived: { type: "boolean", strictBoolean: true }
|
|
212
|
-
}),
|
|
213
|
-
mode: "patch"
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
const parsed = validateOperationInput({
|
|
218
|
-
operation: viewOperation,
|
|
219
|
-
input: {
|
|
220
|
-
params: {
|
|
221
|
-
workspaceSlug: "acme"
|
|
222
|
-
},
|
|
223
|
-
query: {}
|
|
224
|
-
}
|
|
197
|
+
test("validateOperationSection returns only ok, value and fieldErrors", () => {
|
|
198
|
+
const valid = validateOperationSection({
|
|
199
|
+
operation: patchOperation,
|
|
200
|
+
section: "body",
|
|
201
|
+
value: { name: "Acme" }
|
|
225
202
|
});
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
assert.equal(parsed.value.body, undefined);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test("validateOperationInput collects json-rest-schema field errors", () => {
|
|
234
|
-
const parsed = validateOperationInput({
|
|
235
|
-
operation: {
|
|
236
|
-
body: {
|
|
237
|
-
schema: createSchema({
|
|
238
|
-
name: {
|
|
239
|
-
type: "string",
|
|
240
|
-
required: true,
|
|
241
|
-
minLength: 1,
|
|
242
|
-
messages: {
|
|
243
|
-
minLength: "Name is required."
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}),
|
|
247
|
-
mode: "patch"
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
input: {
|
|
251
|
-
body: {
|
|
252
|
-
name: " "
|
|
253
|
-
}
|
|
254
|
-
}
|
|
203
|
+
const missingSection = validateOperationSection({
|
|
204
|
+
operation: patchOperation,
|
|
205
|
+
section: "query",
|
|
206
|
+
value: { page: "1" }
|
|
255
207
|
});
|
|
256
208
|
|
|
257
|
-
assert.
|
|
258
|
-
assert.
|
|
209
|
+
assert.deepEqual(valid, { ok: true, value: { name: "Acme" }, fieldErrors: {} });
|
|
210
|
+
assert.deepEqual(missingSection, { ok: true, value: { page: "1" }, fieldErrors: {} });
|
|
259
211
|
});
|
|
@@ -235,3 +235,14 @@ for (const phase of ["headers", "body"]) {
|
|
|
235
235
|
});
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
|
+
|
|
239
|
+
test("createTransientRetryHttpClient exposes no request path that bypasses transient retry", async () => {
|
|
240
|
+
const client = createTransientRetryHttpClient({ fetchImpl: async () => mockResponse() });
|
|
241
|
+
|
|
242
|
+
assert.deepEqual(Object.keys(client).sort(), [
|
|
243
|
+
"clearCsrfTokenCache",
|
|
244
|
+
"ensureCsrfToken",
|
|
245
|
+
"request",
|
|
246
|
+
"requestStream"
|
|
247
|
+
]);
|
|
248
|
+
});
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
normalizeFieldErrors,
|
|
6
6
|
resolveFieldErrors,
|
|
7
7
|
createValidationFailure,
|
|
8
|
-
createHttpError
|
|
8
|
+
createHttpError,
|
|
9
|
+
createNetworkError,
|
|
10
|
+
isGenericHttpErrorMessage
|
|
9
11
|
} from "../src/client/index.js";
|
|
10
12
|
|
|
11
13
|
test("normalizeFieldErrors trims keys and stringifies values", () => {
|
|
@@ -105,15 +107,15 @@ test("createHttpError preserves standard error envelopes that also contain an er
|
|
|
105
107
|
status: 409
|
|
106
108
|
},
|
|
107
109
|
{
|
|
108
|
-
code: "
|
|
110
|
+
code: "resource_conflict",
|
|
109
111
|
details: {
|
|
110
|
-
code: "
|
|
112
|
+
code: "resource_conflict"
|
|
111
113
|
},
|
|
112
|
-
error: "Finish
|
|
114
|
+
error: "Finish the pending operation first.",
|
|
113
115
|
errors: [
|
|
114
116
|
{
|
|
115
|
-
code: "
|
|
116
|
-
message: "Finish
|
|
117
|
+
code: "resource_conflict",
|
|
118
|
+
message: "Finish the pending operation first."
|
|
117
119
|
}
|
|
118
120
|
],
|
|
119
121
|
ok: false
|
|
@@ -121,13 +123,13 @@ test("createHttpError preserves standard error envelopes that also contain an er
|
|
|
121
123
|
);
|
|
122
124
|
|
|
123
125
|
assert.equal(error.status, 409);
|
|
124
|
-
assert.equal(error.code, "
|
|
126
|
+
assert.equal(error.code, "resource_conflict");
|
|
125
127
|
assert.equal(
|
|
126
128
|
error.message,
|
|
127
|
-
"Finish
|
|
129
|
+
"Finish the pending operation first."
|
|
128
130
|
);
|
|
129
131
|
assert.deepEqual(error.details, {
|
|
130
|
-
code: "
|
|
132
|
+
code: "resource_conflict"
|
|
131
133
|
});
|
|
132
134
|
});
|
|
133
135
|
|
|
@@ -181,3 +183,12 @@ test("createHttpError decodes json:api error documents into the existing fieldEr
|
|
|
181
183
|
}
|
|
182
184
|
});
|
|
183
185
|
});
|
|
186
|
+
|
|
187
|
+
test("isGenericHttpErrorMessage recognises only the transport's own wording", () => {
|
|
188
|
+
assert.equal(isGenericHttpErrorMessage(createHttpError({ status: 500 }, {})), true);
|
|
189
|
+
assert.equal(isGenericHttpErrorMessage(createNetworkError(new Error("offline"))), true);
|
|
190
|
+
assert.equal(isGenericHttpErrorMessage(createHttpError({ status: 500 }, { error: "Server exploded" })), false);
|
|
191
|
+
assert.equal(isGenericHttpErrorMessage({ statusCode: 404, message: "Request failed with status 404." }), true);
|
|
192
|
+
assert.equal(isGenericHttpErrorMessage({ message: "Request failed with status 500." }), false);
|
|
193
|
+
assert.equal(isGenericHttpErrorMessage(null), false);
|
|
194
|
+
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
2
|
-
import * as httpClientRuntime from "../../shared/clientRuntime/index.js";
|
|
3
|
-
|
|
4
|
-
const HTTP_CLIENT_RUNTIME_CLIENT_API = Object.freeze({
|
|
5
|
-
...httpClientRuntime
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
const HttpClientRuntimeClientProvider = defineProvider({
|
|
9
|
-
id: "runtime.http-client.client",
|
|
10
|
-
provides: {
|
|
11
|
-
httpClient: "runtime.http-client.client"
|
|
12
|
-
},
|
|
13
|
-
setup() {
|
|
14
|
-
return {
|
|
15
|
-
httpClient: HTTP_CLIENT_RUNTIME_CLIENT_API
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export { HttpClientRuntimeClientProvider };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
2
|
-
import { HTTP_VALIDATORS_API } from "../../shared/validators/httpValidatorsApi.js";
|
|
3
|
-
|
|
4
|
-
const HttpValidatorsClientProvider = defineProvider({
|
|
5
|
-
id: "validators.http.client",
|
|
6
|
-
provides: {
|
|
7
|
-
validators: "validators.http.client"
|
|
8
|
-
},
|
|
9
|
-
setup() {
|
|
10
|
-
return {
|
|
11
|
-
validators: HTTP_VALIDATORS_API
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export { HttpValidatorsClientProvider };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
2
|
-
import * as httpClient from "../../shared/clientRuntime/index.js";
|
|
3
|
-
|
|
4
|
-
const HttpClientProvider = defineProvider({
|
|
5
|
-
id: "runtime.http-client",
|
|
6
|
-
provides: {
|
|
7
|
-
httpClient: "runtime.http-client"
|
|
8
|
-
},
|
|
9
|
-
setup() {
|
|
10
|
-
return {
|
|
11
|
-
httpClient: Object.freeze({ ...httpClient })
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export { HttpClientProvider };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
2
|
-
import { HTTP_VALIDATORS_API } from "../../shared/validators/httpValidatorsApi.js";
|
|
3
|
-
|
|
4
|
-
const HttpValidatorsProvider = defineProvider({
|
|
5
|
-
id: "validators.http",
|
|
6
|
-
provides: {
|
|
7
|
-
validators: "validators.http"
|
|
8
|
-
},
|
|
9
|
-
setup() {
|
|
10
|
-
return {
|
|
11
|
-
validators: HTTP_VALIDATORS_API
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export { HttpValidatorsProvider };
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { createHttpClient } from "./client.js";
|
|
2
|
-
export { createHttpError, createNetworkError } from "./errors.js";
|
|
3
|
-
export { DEFAULT_RETRYABLE_CSRF_ERROR_CODES, shouldRetryForCsrfFailure } from "./retry.js";
|
|
4
|
-
export { normalizeHeaderName, hasHeader, setHeaderIfMissing } from "./headers.js";
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { asSchemaDefinition } from "./schemaUtils.js";
|
|
2
|
-
import { normalizeUniqueTextList } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
import { deepFreeze } from "@jskit-ai/kernel/shared/support/deepFreeze";
|
|
4
|
-
|
|
5
|
-
function createCommand({
|
|
6
|
-
input,
|
|
7
|
-
output,
|
|
8
|
-
idempotent = null,
|
|
9
|
-
invalidates = []
|
|
10
|
-
} = {}) {
|
|
11
|
-
const command = {
|
|
12
|
-
input: asSchemaDefinition(input, "input", "patch"),
|
|
13
|
-
output: asSchemaDefinition(output, "output", "replace"),
|
|
14
|
-
invalidates: Object.freeze(normalizeUniqueTextList(invalidates))
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
if (typeof idempotent === "boolean") {
|
|
18
|
-
command.idempotent = idempotent;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return deepFreeze(command);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { createCommand };
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { createPaginationQuerySchema } from "./paginationQuery.js";
|
|
2
|
-
import {
|
|
3
|
-
fieldErrorsFieldDefinition,
|
|
4
|
-
apiErrorDetailsSchema,
|
|
5
|
-
apiValidationErrorDetailsSchema,
|
|
6
|
-
apiErrorOutputValidator,
|
|
7
|
-
apiValidationErrorOutputValidator,
|
|
8
|
-
apiErrorTransportSchema,
|
|
9
|
-
apiValidationErrorTransportSchema,
|
|
10
|
-
fastifyDefaultErrorTransportSchema,
|
|
11
|
-
STANDARD_ERROR_STATUS_CODES,
|
|
12
|
-
createTransportResponseSchema,
|
|
13
|
-
passthroughErrorResponses,
|
|
14
|
-
withStandardErrorResponses,
|
|
15
|
-
enumSchema
|
|
16
|
-
} from "./errorResponses.js";
|
|
17
|
-
import {
|
|
18
|
-
createCursorPagedListResponseSchema,
|
|
19
|
-
createResource
|
|
20
|
-
} from "./resource.js";
|
|
21
|
-
import { createCommand } from "./command.js";
|
|
22
|
-
import {
|
|
23
|
-
resolveSchemaMessages,
|
|
24
|
-
resolveFieldSchema,
|
|
25
|
-
resolveIssueField,
|
|
26
|
-
resolveMissingRequiredFields,
|
|
27
|
-
resolveIssueMessageFromSchema,
|
|
28
|
-
mapOperationIssues
|
|
29
|
-
} from "./operationMessages.js";
|
|
30
|
-
import {
|
|
31
|
-
validateOperationSection,
|
|
32
|
-
validateOperationInput
|
|
33
|
-
} from "./operationValidation.js";
|
|
34
|
-
import {
|
|
35
|
-
JSON_API_CONTENT_TYPE,
|
|
36
|
-
createJsonApiDocument,
|
|
37
|
-
createJsonApiErrorDocumentFromFailure,
|
|
38
|
-
createJsonApiErrorObject,
|
|
39
|
-
createJsonApiResourceObject,
|
|
40
|
-
isJsonApiCollectionDocument,
|
|
41
|
-
isJsonApiContentType,
|
|
42
|
-
isJsonApiErrorDocument,
|
|
43
|
-
isJsonApiResourceDocument,
|
|
44
|
-
isJsonContentType,
|
|
45
|
-
normalizeJsonApiDocument,
|
|
46
|
-
normalizeJsonApiResourceObject,
|
|
47
|
-
resolveJsonApiTransportTypes,
|
|
48
|
-
simplifyJsonApiDocument
|
|
49
|
-
} from "./jsonApiTransport.js";
|
|
50
|
-
import {
|
|
51
|
-
JSON_API_QUERY_PAGE_CURSOR_KEY,
|
|
52
|
-
JSON_API_QUERY_PAGE_LIMIT_KEY,
|
|
53
|
-
JSON_API_QUERY_INCLUDE_KEY,
|
|
54
|
-
JSON_API_QUERY_SORT_KEY,
|
|
55
|
-
mapPlainQueryKeyToTransportKey,
|
|
56
|
-
mapTransportQueryKeyToPlainKey,
|
|
57
|
-
encodeJsonApiResourceQueryObject,
|
|
58
|
-
decodeJsonApiResourceQueryObject,
|
|
59
|
-
createJsonApiResourceQueryTransportSchema
|
|
60
|
-
} from "./jsonApiQueryTransport.js";
|
|
61
|
-
import {
|
|
62
|
-
JSON_API_ERROR_DOCUMENT_SCHEMA,
|
|
63
|
-
createJsonApiResourceObjectTransportSchema,
|
|
64
|
-
createJsonApiResourceRequestBodyTransportSchema,
|
|
65
|
-
createJsonApiResourceSuccessTransportSchema,
|
|
66
|
-
withJsonApiErrorResponses,
|
|
67
|
-
createJsonApiResourceRouteTransport,
|
|
68
|
-
createJsonApiResourceRouteContract
|
|
69
|
-
} from "./jsonApiRouteTransport.js";
|
|
70
|
-
|
|
71
|
-
const HTTP_VALIDATORS_API = Object.freeze({
|
|
72
|
-
createPaginationQuerySchema,
|
|
73
|
-
fieldErrorsFieldDefinition,
|
|
74
|
-
apiErrorDetailsSchema,
|
|
75
|
-
apiValidationErrorDetailsSchema,
|
|
76
|
-
apiErrorOutputValidator,
|
|
77
|
-
apiValidationErrorOutputValidator,
|
|
78
|
-
apiErrorTransportSchema,
|
|
79
|
-
apiValidationErrorTransportSchema,
|
|
80
|
-
fastifyDefaultErrorTransportSchema,
|
|
81
|
-
STANDARD_ERROR_STATUS_CODES,
|
|
82
|
-
createTransportResponseSchema,
|
|
83
|
-
passthroughErrorResponses,
|
|
84
|
-
withStandardErrorResponses,
|
|
85
|
-
enumSchema,
|
|
86
|
-
createCursorPagedListResponseSchema,
|
|
87
|
-
createResource,
|
|
88
|
-
createCommand,
|
|
89
|
-
resolveSchemaMessages,
|
|
90
|
-
resolveFieldSchema,
|
|
91
|
-
resolveIssueField,
|
|
92
|
-
resolveMissingRequiredFields,
|
|
93
|
-
resolveIssueMessageFromSchema,
|
|
94
|
-
mapOperationIssues,
|
|
95
|
-
validateOperationSection,
|
|
96
|
-
validateOperationInput,
|
|
97
|
-
JSON_API_CONTENT_TYPE,
|
|
98
|
-
createJsonApiDocument,
|
|
99
|
-
createJsonApiErrorDocumentFromFailure,
|
|
100
|
-
createJsonApiErrorObject,
|
|
101
|
-
createJsonApiResourceObject,
|
|
102
|
-
isJsonApiCollectionDocument,
|
|
103
|
-
isJsonApiContentType,
|
|
104
|
-
isJsonApiErrorDocument,
|
|
105
|
-
isJsonApiResourceDocument,
|
|
106
|
-
isJsonContentType,
|
|
107
|
-
normalizeJsonApiDocument,
|
|
108
|
-
normalizeJsonApiResourceObject,
|
|
109
|
-
resolveJsonApiTransportTypes,
|
|
110
|
-
simplifyJsonApiDocument,
|
|
111
|
-
JSON_API_QUERY_PAGE_CURSOR_KEY,
|
|
112
|
-
JSON_API_QUERY_PAGE_LIMIT_KEY,
|
|
113
|
-
JSON_API_QUERY_INCLUDE_KEY,
|
|
114
|
-
JSON_API_QUERY_SORT_KEY,
|
|
115
|
-
mapPlainQueryKeyToTransportKey,
|
|
116
|
-
mapTransportQueryKeyToPlainKey,
|
|
117
|
-
encodeJsonApiResourceQueryObject,
|
|
118
|
-
decodeJsonApiResourceQueryObject,
|
|
119
|
-
createJsonApiResourceQueryTransportSchema,
|
|
120
|
-
JSON_API_ERROR_DOCUMENT_SCHEMA,
|
|
121
|
-
createJsonApiResourceObjectTransportSchema,
|
|
122
|
-
createJsonApiResourceRequestBodyTransportSchema,
|
|
123
|
-
createJsonApiResourceSuccessTransportSchema,
|
|
124
|
-
withJsonApiErrorResponses,
|
|
125
|
-
createJsonApiResourceRouteTransport,
|
|
126
|
-
createJsonApiResourceRouteContract
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
export { HTTP_VALIDATORS_API };
|