@distilled.cloud/core 1.0.0-rc.12 → 1.0.0-rc.13
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/lib/api.d.ts +4 -4
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +1 -1
- package/lib/api.js.map +1 -1
- package/lib/category.js +1 -1
- package/lib/category.js.map +1 -1
- package/lib/codegen/boolean-string-enums.d.ts +8 -8
- package/lib/codegen/boolean-string-enums.d.ts.map +1 -1
- package/lib/codegen/boolean-string-enums.js +84 -27
- package/lib/codegen/boolean-string-enums.js.map +1 -1
- package/lib/codegen/boolean-string-enums.test.js +130 -0
- package/lib/codegen/boolean-string-enums.test.js.map +1 -1
- package/lib/codegen/cli.js +2 -2
- package/lib/codegen/cli.js.map +1 -1
- package/lib/codegen/generator.d.ts +20 -3
- package/lib/codegen/generator.d.ts.map +1 -1
- package/lib/codegen/generator.js +36 -9
- package/lib/codegen/generator.js.map +1 -1
- package/lib/codegen/generator.test.d.ts +2 -0
- package/lib/codegen/generator.test.d.ts.map +1 -0
- package/lib/codegen/generator.test.js +126 -0
- package/lib/codegen/generator.test.js.map +1 -0
- package/lib/codegen/graphql-client.d.ts +7 -1
- package/lib/codegen/graphql-client.d.ts.map +1 -1
- package/lib/codegen/graphql-client.js +262 -125
- package/lib/codegen/graphql-client.js.map +1 -1
- package/lib/codegen/graphql-client.test.js +104 -236
- package/lib/codegen/graphql-client.test.js.map +1 -1
- package/lib/codegen/openapi-binary.test.d.ts +2 -0
- package/lib/codegen/openapi-binary.test.d.ts.map +1 -0
- package/lib/codegen/openapi-binary.test.js +67 -0
- package/lib/codegen/openapi-binary.test.js.map +1 -0
- package/lib/codegen/openapi.d.ts +7 -1
- package/lib/codegen/openapi.d.ts.map +1 -1
- package/lib/codegen/openapi.js +15 -4
- package/lib/codegen/openapi.js.map +1 -1
- package/lib/codegen/patches.d.ts +16 -1
- package/lib/codegen/patches.d.ts.map +1 -1
- package/lib/codegen/patches.js +70 -4
- package/lib/codegen/patches.js.map +1 -1
- package/lib/codegen/patches.test.js +48 -2
- package/lib/codegen/patches.test.js.map +1 -1
- package/lib/codegen/untagged-unions.test.d.ts +2 -0
- package/lib/codegen/untagged-unions.test.d.ts.map +1 -0
- package/lib/codegen/untagged-unions.test.js +80 -0
- package/lib/codegen/untagged-unions.test.js.map +1 -0
- package/lib/errors.d.ts +2 -1
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +5 -2
- package/lib/errors.js.map +1 -1
- package/lib/fixtures/xml/upstream-validator.json +397 -0
- package/lib/graphql.d.ts +296 -205
- package/lib/graphql.d.ts.map +1 -1
- package/lib/graphql.js +968 -631
- package/lib/graphql.js.map +1 -1
- package/lib/graphql.test.js +134 -763
- package/lib/graphql.test.js.map +1 -1
- package/lib/graphql.types.d.ts +10 -0
- package/lib/graphql.types.d.ts.map +1 -1
- package/lib/graphql.types.js +4 -44
- package/lib/graphql.types.js.map +1 -1
- package/lib/index.d.ts +27 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +27 -0
- package/lib/index.js.map +1 -0
- package/lib/pagination.d.ts +2 -1
- package/lib/pagination.d.ts.map +1 -1
- package/lib/pagination.js +24 -16
- package/lib/pagination.js.map +1 -1
- package/lib/pagination.test.d.ts +2 -0
- package/lib/pagination.test.d.ts.map +1 -0
- package/lib/pagination.test.js +134 -0
- package/lib/pagination.test.js.map +1 -0
- package/lib/protocol-http.d.ts +12 -17
- package/lib/protocol-http.d.ts.map +1 -1
- package/lib/protocol-http.js +100 -45
- package/lib/protocol-http.js.map +1 -1
- package/lib/protocol-http.test.js +130 -0
- package/lib/protocol-http.test.js.map +1 -1
- package/lib/protocol-rest.d.ts +18 -1
- package/lib/protocol-rest.d.ts.map +1 -1
- package/lib/protocol-rest.js +24 -4
- package/lib/protocol-rest.js.map +1 -1
- package/lib/query.d.ts +29 -0
- package/lib/query.d.ts.map +1 -0
- package/lib/query.js +27 -0
- package/lib/query.js.map +1 -0
- package/lib/response-validation.d.ts +67 -0
- package/lib/response-validation.d.ts.map +1 -0
- package/lib/response-validation.js +76 -0
- package/lib/response-validation.js.map +1 -0
- package/lib/response-validation.test.d.ts +2 -0
- package/lib/response-validation.test.d.ts.map +1 -0
- package/lib/response-validation.test.js +67 -0
- package/lib/response-validation.test.js.map +1 -0
- package/lib/testing.d.ts +39 -0
- package/lib/testing.d.ts.map +1 -0
- package/lib/testing.js +41 -0
- package/lib/testing.js.map +1 -0
- package/lib/trait.d.ts +29 -9
- package/lib/trait.d.ts.map +1 -1
- package/lib/trait.js +8 -0
- package/lib/trait.js.map +1 -1
- package/lib/xml.d.ts +44 -0
- package/lib/xml.d.ts.map +1 -0
- package/lib/xml.js +315 -0
- package/lib/xml.js.map +1 -0
- package/lib/xml.test.d.ts +2 -0
- package/lib/xml.test.d.ts.map +1 -0
- package/lib/xml.test.js +211 -0
- package/lib/xml.test.js.map +1 -0
- package/package.json +4 -4
- package/src/api.ts +4 -4
- package/src/category.ts +1 -1
- package/src/codegen/boolean-string-enums.test.ts +147 -0
- package/src/codegen/boolean-string-enums.ts +84 -27
- package/src/codegen/cli.ts +2 -2
- package/src/codegen/generator.test.ts +151 -0
- package/src/codegen/generator.ts +70 -12
- package/src/codegen/graphql-client.test.ts +116 -283
- package/src/codegen/graphql-client.ts +326 -169
- package/src/codegen/openapi-binary.test.ts +98 -0
- package/src/codegen/openapi.ts +26 -4
- package/src/codegen/patches.test.ts +66 -1
- package/src/codegen/patches.ts +84 -4
- package/src/codegen/untagged-unions.test.ts +89 -0
- package/src/errors.ts +5 -2
- package/src/fixtures/xml/upstream-validator.json +397 -0
- package/src/graphql.test.ts +174 -948
- package/src/graphql.ts +1592 -1167
- package/src/graphql.types.ts +92 -163
- package/src/index.ts +26 -0
- package/src/pagination.test.ts +191 -0
- package/src/pagination.ts +35 -25
- package/src/protocol-http.test.ts +163 -0
- package/src/protocol-http.ts +122 -46
- package/src/protocol-rest.ts +62 -13
- package/src/query.ts +39 -0
- package/src/response-validation.test.ts +95 -0
- package/src/response-validation.ts +116 -0
- package/src/testing.ts +78 -0
- package/src/trait.ts +39 -8
- package/src/xml.test.ts +269 -0
- package/src/xml.ts +339 -0
- package/lib/graphql.fixture.d.ts +0 -249
- package/lib/graphql.fixture.d.ts.map +0 -1
- package/lib/graphql.fixture.js +0 -240
- package/lib/graphql.fixture.js.map +0 -1
- package/src/graphql.fixture.ts +0 -371
package/lib/protocol-rest.js
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
* values first)
|
|
13
13
|
*
|
|
14
14
|
* response: 2xx JSON → optional `transformResponse` → recursive wire→TS
|
|
15
|
-
* key mapping (`mapKeys`) →
|
|
15
|
+
* key mapping (`mapKeys`) → in strict mode, a schema check
|
|
16
|
+
* failing with the provider's `parseError` (see
|
|
17
|
+
* `core/response-validation`) → `Redacted` wrapping of members
|
|
16
18
|
* marked with {@link SensitiveValue}; non-2xx → typed error:
|
|
17
19
|
* per-op matcher classes (`matchTypedError`), then the status
|
|
18
20
|
* map (default `HTTP_STATUS_MAP`), then an `InternalServerError`
|
|
@@ -31,6 +33,7 @@ import { httpSymbol, makeAnnotation } from "./trait.js";
|
|
|
31
33
|
import { buildRequest, getAnn, getPropAnn, getProps, isOpaqueValue, mapKeys, matchTypedError, resolveNode, } from "./protocol-http.js";
|
|
32
34
|
import { HTTP_STATUS_MAP, InternalServerError } from "./errors.js";
|
|
33
35
|
import { parseRetryAfterForStatus } from "./retry-after.js";
|
|
36
|
+
import { validateResponse } from "./response-validation.js";
|
|
34
37
|
// =============================================================================
|
|
35
38
|
// Traits
|
|
36
39
|
// =============================================================================
|
|
@@ -57,6 +60,9 @@ export const rawResponseRootSymbol = Symbol.for("@distilled.cloud/core/raw-respo
|
|
|
57
60
|
* directly.
|
|
58
61
|
*/
|
|
59
62
|
export const RawResponseRoot = () => makeAnnotation(rawResponseRootSymbol, true);
|
|
63
|
+
export const binaryResponseSymbol = Symbol.for("@distilled.cloud/core/binary-response");
|
|
64
|
+
/** Decode a successful raw binary response as bytes, without text conversion. */
|
|
65
|
+
export const BinaryResponse = () => makeAnnotation(binaryResponseSymbol, true);
|
|
60
66
|
// =============================================================================
|
|
61
67
|
// Value helpers
|
|
62
68
|
// =============================================================================
|
|
@@ -98,6 +104,10 @@ export const wrapSensitive = (ast, value) => {
|
|
|
98
104
|
return value;
|
|
99
105
|
}
|
|
100
106
|
const node = resolveNode(ast);
|
|
107
|
+
if (node._tag === "Union") {
|
|
108
|
+
// Redact every possible sensitive member, including in partial responses.
|
|
109
|
+
return node.types.reduce((redacted, arm) => wrapSensitive(arm, redacted), value);
|
|
110
|
+
}
|
|
101
111
|
if (node._tag === "Arrays") {
|
|
102
112
|
if (!Array.isArray(value))
|
|
103
113
|
return value;
|
|
@@ -182,10 +192,16 @@ export const makeRestProtocol = (options) => {
|
|
|
182
192
|
});
|
|
183
193
|
});
|
|
184
194
|
const decode = ({ response, outputAst, errors: errorClasses, }) => Effect.gen(function* () {
|
|
195
|
+
if (response.status >= 200 &&
|
|
196
|
+
response.status < 300 &&
|
|
197
|
+
getAnn(outputAst, binaryResponseSymbol) !== undefined) {
|
|
198
|
+
const bytes = yield* response.arrayBuffer.pipe(Effect.orDie);
|
|
199
|
+
return new Uint8Array(bytes);
|
|
200
|
+
}
|
|
185
201
|
// Read as text and parse tolerantly — error pages are often non-JSON.
|
|
186
202
|
const text = (yield* response.text.pipe(Effect.orDie)) ?? "";
|
|
187
203
|
if (process.env.DISTILLED_DEBUG_HTTP) {
|
|
188
|
-
console.error(`[distilled] <- ${response.status}
|
|
204
|
+
console.error(`[distilled] <- ${response.status}`);
|
|
189
205
|
}
|
|
190
206
|
let json;
|
|
191
207
|
let nonJson = false;
|
|
@@ -209,7 +225,7 @@ export const makeRestProtocol = (options) => {
|
|
|
209
225
|
code: typeof env.code === "number" ? env.code : undefined,
|
|
210
226
|
message,
|
|
211
227
|
},
|
|
212
|
-
]);
|
|
228
|
+
], { body: nonJson ? text : json, headers });
|
|
213
229
|
if (typed !== undefined)
|
|
214
230
|
return yield* fail(typed);
|
|
215
231
|
// 2. Status-mapped class (retryAfter only stamps on retryable
|
|
@@ -241,10 +257,14 @@ export const makeRestProtocol = (options) => {
|
|
|
241
257
|
// 2xx: the response body IS the payload (no envelope). Wire→TS key
|
|
242
258
|
// mapping is schema-driven; `RawResponseRoot` responses are the body
|
|
243
259
|
// verbatim (mapKeys handles arrays/scalars structurally either way).
|
|
260
|
+
// Strict mode (core/response-validation) checks the mapped body against
|
|
261
|
+
// the output schema — a non-JSON body reaches it as a string and fails
|
|
262
|
+
// there unless the operation's output is itself a string.
|
|
244
263
|
let body = nonJson ? text : (json ?? {});
|
|
245
264
|
if (options.transformResponse)
|
|
246
265
|
body = options.transformResponse(body);
|
|
247
|
-
|
|
266
|
+
const mapped = yield* validateResponse(outputAst, mapKeys(outputAst, body, "decode"), (cause) => options.parseError({ body: nonJson ? text : json, cause })).pipe(Effect.catch(fail));
|
|
267
|
+
return wrapSensitive(outputAst, mapped);
|
|
248
268
|
});
|
|
249
269
|
return Layer.succeed(API.Protocol, API.Protocol.of({
|
|
250
270
|
// Erase encode's credentials requirement (resolved on the calling
|
package/lib/protocol-rest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-rest.js","sourceRoot":"","sources":["../src/protocol-rest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"protocol-rest.js","sourceRoot":"","sources":["../src/protocol-rest.ts"],"names":[],"mappings":"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"}
|
package/lib/query.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query combinators for GraphQL SDKs.
|
|
3
|
+
*
|
|
4
|
+
* Import this module next to a generated client:
|
|
5
|
+
*
|
|
6
|
+
* import { Query } from "@distilled.cloud/core/query"
|
|
7
|
+
* import { Railway } from "@distilled.cloud/railway"
|
|
8
|
+
*
|
|
9
|
+
* `Query.fn` takes a **builder** (plain function, not `Effect.gen`) that
|
|
10
|
+
* returns a plan of `Query<Value>` and `Effect` values. It walks Map /
|
|
11
|
+
* Filter / FlatMap / Of, posts one GraphQL document, then interprets the
|
|
12
|
+
* plan. Roots (`Railway.me`) come from the generated SDK; they are not
|
|
13
|
+
* combinators.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link file://./graphql.ts} for the algebra, compiler, and transport.
|
|
16
|
+
*/
|
|
17
|
+
import { filterQuery, flatMapQuery, itemsQuery, mapQuery, ofQuery, pagesQuery, queryFn, type Query as QueryType } from "./graphql.ts";
|
|
18
|
+
export type Query<Value, Error = never> = QueryType<Value, Error>;
|
|
19
|
+
export type { PlanError, QueryError, UnwrapPlan } from "./graphql.ts";
|
|
20
|
+
export declare const Query: {
|
|
21
|
+
fn: typeof queryFn;
|
|
22
|
+
filter: typeof filterQuery;
|
|
23
|
+
map: typeof mapQuery;
|
|
24
|
+
flatMap: typeof flatMapQuery;
|
|
25
|
+
of: typeof ofQuery;
|
|
26
|
+
pages: typeof pagesQuery;
|
|
27
|
+
items: typeof itemsQuery;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,OAAO,EACP,UAAU,EACV,OAAO,EACP,KAAK,KAAK,IAAI,SAAS,EACxB,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAClE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtE,eAAO,MAAM,KAAK;IAChB,EAAE;IACF,MAAM;IACN,GAAG;IACH,OAAO;IACP,EAAE;IACF,KAAK;IACL,KAAK;CACN,CAAC"}
|
package/lib/query.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query combinators for GraphQL SDKs.
|
|
3
|
+
*
|
|
4
|
+
* Import this module next to a generated client:
|
|
5
|
+
*
|
|
6
|
+
* import { Query } from "@distilled.cloud/core/query"
|
|
7
|
+
* import { Railway } from "@distilled.cloud/railway"
|
|
8
|
+
*
|
|
9
|
+
* `Query.fn` takes a **builder** (plain function, not `Effect.gen`) that
|
|
10
|
+
* returns a plan of `Query<Value>` and `Effect` values. It walks Map /
|
|
11
|
+
* Filter / FlatMap / Of, posts one GraphQL document, then interprets the
|
|
12
|
+
* plan. Roots (`Railway.me`) come from the generated SDK; they are not
|
|
13
|
+
* combinators.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link file://./graphql.ts} for the algebra, compiler, and transport.
|
|
16
|
+
*/
|
|
17
|
+
import { filterQuery, flatMapQuery, itemsQuery, mapQuery, ofQuery, pagesQuery, queryFn, } from "./graphql.js";
|
|
18
|
+
export const Query = {
|
|
19
|
+
fn: queryFn,
|
|
20
|
+
filter: filterQuery,
|
|
21
|
+
map: mapQuery,
|
|
22
|
+
flatMap: flatMapQuery,
|
|
23
|
+
of: ofQuery,
|
|
24
|
+
pages: pagesQuery,
|
|
25
|
+
items: itemsQuery,
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=query.js.map
|
package/lib/query.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,OAAO,EACP,UAAU,EACV,OAAO,GAER,MAAM,cAAc,CAAC;AAKtB,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,EAAE,EAAE,OAAO;IACX,MAAM,EAAE,WAAW;IACnB,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,YAAY;IACrB,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;CAClB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response validation mode, shared by every distilled SDK.
|
|
3
|
+
*
|
|
4
|
+
* Generated SDKs carry a schema for every operation's output. What a
|
|
5
|
+
* protocol does with it on a 2xx response depends on the mode:
|
|
6
|
+
*
|
|
7
|
+
* lenient (default): the response is returned as the protocol read it.
|
|
8
|
+
* A body that does not match the declared output type
|
|
9
|
+
* (a missing member, a wrong primitive, a non-JSON
|
|
10
|
+
* body) still succeeds.
|
|
11
|
+
* strict: the response is decoded against the output schema,
|
|
12
|
+
* and a mismatch fails the call with the SDK's
|
|
13
|
+
* `<Sdk>ParseError` (AWS: `ParseError`).
|
|
14
|
+
*
|
|
15
|
+
* The mode is one {@link ResponseValidation} reference keyed by a string, so
|
|
16
|
+
* a single `Layer` switches every distilled SDK in a program — AWS,
|
|
17
|
+
* Cloudflare, Neon, … — at once, and nests like any other Effect service:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { ResponseValidation } from "@distilled.cloud/core";
|
|
21
|
+
*
|
|
22
|
+
* // whole program
|
|
23
|
+
* program.pipe(Effect.provide(ResponseValidation.strict));
|
|
24
|
+
*
|
|
25
|
+
* // one call back to lenient inside a strict program
|
|
26
|
+
* Neon.getProject({ projectId }).pipe(Effect.provide(ResponseValidation.lenient));
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The mode is set only by these layers; without one, every call is lenient.
|
|
30
|
+
*/
|
|
31
|
+
import * as Context from "effect/Context";
|
|
32
|
+
import * as Effect from "effect/Effect";
|
|
33
|
+
import * as Layer from "effect/Layer";
|
|
34
|
+
import * as Schema from "effect/Schema";
|
|
35
|
+
import type * as AST from "effect/SchemaAST";
|
|
36
|
+
export type Mode = "lenient" | "strict";
|
|
37
|
+
/**
|
|
38
|
+
* The active validation mode. Read by protocols at call time on the calling
|
|
39
|
+
* fiber; `lenient` unless a {@link strict} layer is provided.
|
|
40
|
+
*/
|
|
41
|
+
export declare const ResponseValidation: Context.Reference<Mode>;
|
|
42
|
+
/** Decode every 2xx response against its output schema; fail on mismatch. */
|
|
43
|
+
export declare const strict: Layer.Layer<never>;
|
|
44
|
+
/** Return 2xx responses as read, without checking them against the schema. */
|
|
45
|
+
export declare const lenient: Layer.Layer<never>;
|
|
46
|
+
/** Whether the calling fiber is in strict mode. */
|
|
47
|
+
export declare const isStrict: Effect.Effect<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* For a 2xx body the protocol could not read into the shape it transforms
|
|
50
|
+
* (e.g. invalid JSON): fail with `error` in strict mode, succeed with
|
|
51
|
+
* `asRead` (usually the body text) in lenient mode.
|
|
52
|
+
*/
|
|
53
|
+
export declare const failIfStrict: <A, E>(error: E, asRead: A) => Effect.Effect<A, E>;
|
|
54
|
+
/**
|
|
55
|
+
* Check a 2xx response value against the operation's output schema.
|
|
56
|
+
*
|
|
57
|
+
* Lenient mode returns `value` untouched. Strict mode decodes it and, on a
|
|
58
|
+
* mismatch, fails with `onError(schemaError)` — protocols pass their SDK's
|
|
59
|
+
* `<Sdk>ParseError` constructor. On success the ORIGINAL value is returned
|
|
60
|
+
* (members the schema does not model are kept), so switching modes never
|
|
61
|
+
* changes what a successful call returns.
|
|
62
|
+
*
|
|
63
|
+
* `value` must already be in the schema's shape (TS member names), i.e.
|
|
64
|
+
* after any wire→TS key mapping and before `Redacted` wrapping.
|
|
65
|
+
*/
|
|
66
|
+
export declare const validateResponse: <E>(outputAst: AST.AST, value: unknown, onError: (cause: Schema.SchemaError) => E) => Effect.Effect<unknown, E>;
|
|
67
|
+
//# sourceMappingURL=response-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-validation.d.ts","sourceRoot":"","sources":["../src/response-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAE7C,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,yBAG9B,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAGrC,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAGtC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAG3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAGxE,CAAC;AAkBJ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,aACrB,GAAG,CAAC,GAAG,SACX,OAAO,WACL,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,KAAK,CAAC,KACxC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAQxB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response validation mode, shared by every distilled SDK.
|
|
3
|
+
*
|
|
4
|
+
* Generated SDKs carry a schema for every operation's output. What a
|
|
5
|
+
* protocol does with it on a 2xx response depends on the mode:
|
|
6
|
+
*
|
|
7
|
+
* lenient (default): the response is returned as the protocol read it.
|
|
8
|
+
* A body that does not match the declared output type
|
|
9
|
+
* (a missing member, a wrong primitive, a non-JSON
|
|
10
|
+
* body) still succeeds.
|
|
11
|
+
* strict: the response is decoded against the output schema,
|
|
12
|
+
* and a mismatch fails the call with the SDK's
|
|
13
|
+
* `<Sdk>ParseError` (AWS: `ParseError`).
|
|
14
|
+
*
|
|
15
|
+
* The mode is one {@link ResponseValidation} reference keyed by a string, so
|
|
16
|
+
* a single `Layer` switches every distilled SDK in a program — AWS,
|
|
17
|
+
* Cloudflare, Neon, … — at once, and nests like any other Effect service:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { ResponseValidation } from "@distilled.cloud/core";
|
|
21
|
+
*
|
|
22
|
+
* // whole program
|
|
23
|
+
* program.pipe(Effect.provide(ResponseValidation.strict));
|
|
24
|
+
*
|
|
25
|
+
* // one call back to lenient inside a strict program
|
|
26
|
+
* Neon.getProject({ projectId }).pipe(Effect.provide(ResponseValidation.lenient));
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The mode is set only by these layers; without one, every call is lenient.
|
|
30
|
+
*/
|
|
31
|
+
import * as Context from "effect/Context";
|
|
32
|
+
import * as Effect from "effect/Effect";
|
|
33
|
+
import * as Layer from "effect/Layer";
|
|
34
|
+
import * as Schema from "effect/Schema";
|
|
35
|
+
/**
|
|
36
|
+
* The active validation mode. Read by protocols at call time on the calling
|
|
37
|
+
* fiber; `lenient` unless a {@link strict} layer is provided.
|
|
38
|
+
*/
|
|
39
|
+
export const ResponseValidation = Context.Reference("@distilled.cloud/core/ResponseValidation", { defaultValue: () => "lenient" });
|
|
40
|
+
/** Decode every 2xx response against its output schema; fail on mismatch. */
|
|
41
|
+
export const strict = Layer.succeed(ResponseValidation, "strict");
|
|
42
|
+
/** Return 2xx responses as read, without checking them against the schema. */
|
|
43
|
+
export const lenient = Layer.succeed(ResponseValidation, "lenient");
|
|
44
|
+
/** Whether the calling fiber is in strict mode. */
|
|
45
|
+
export const isStrict = Effect.map(ResponseValidation, (mode) => mode === "strict");
|
|
46
|
+
/**
|
|
47
|
+
* For a 2xx body the protocol could not read into the shape it transforms
|
|
48
|
+
* (e.g. invalid JSON): fail with `error` in strict mode, succeed with
|
|
49
|
+
* `asRead` (usually the body text) in lenient mode.
|
|
50
|
+
*/
|
|
51
|
+
export const failIfStrict = (error, asRead) => Effect.flatMap(ResponseValidation, (mode) => mode === "strict" ? Effect.fail(error) : Effect.succeed(asRead));
|
|
52
|
+
const decoders = new WeakMap();
|
|
53
|
+
const decoderFor = (ast) => {
|
|
54
|
+
let decode = decoders.get(ast);
|
|
55
|
+
if (!decode) {
|
|
56
|
+
decode = Schema.decodeUnknownEffect(Schema.make(ast));
|
|
57
|
+
decoders.set(ast, decode);
|
|
58
|
+
}
|
|
59
|
+
return decode;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Check a 2xx response value against the operation's output schema.
|
|
63
|
+
*
|
|
64
|
+
* Lenient mode returns `value` untouched. Strict mode decodes it and, on a
|
|
65
|
+
* mismatch, fails with `onError(schemaError)` — protocols pass their SDK's
|
|
66
|
+
* `<Sdk>ParseError` constructor. On success the ORIGINAL value is returned
|
|
67
|
+
* (members the schema does not model are kept), so switching modes never
|
|
68
|
+
* changes what a successful call returns.
|
|
69
|
+
*
|
|
70
|
+
* `value` must already be in the schema's shape (TS member names), i.e.
|
|
71
|
+
* after any wire→TS key mapping and before `Redacted` wrapping.
|
|
72
|
+
*/
|
|
73
|
+
export const validateResponse = (outputAst, value, onError) => Effect.flatMap(ResponseValidation, (mode) => mode === "lenient"
|
|
74
|
+
? Effect.succeed(value)
|
|
75
|
+
: decoderFor(outputAst)(value).pipe(Effect.mapError(onError), Effect.as(value)));
|
|
76
|
+
//# sourceMappingURL=response-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-validation.js","sourceRoot":"","sources":["../src/response-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAKxC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CACjD,0CAA0C,EAC1C,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAClC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,MAAM,GAAuB,KAAK,CAAC,OAAO,CACrD,kBAAkB,EAClB,QAAQ,CACT,CAAC;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,OAAO,GAAuB,KAAK,CAAC,OAAO,CACtD,kBAAkB,EAClB,SAAS,CACV,CAAC;AAEF,mDAAmD;AACnD,MAAM,CAAC,MAAM,QAAQ,GAA2B,MAAM,CAAC,GAAG,CACxD,kBAAkB,EAClB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAC5B,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAO,KAAQ,EAAE,MAAS,EAAuB,EAAE,CAC7E,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,EAAE,EAAE,CAC1C,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAChE,CAAC;AAEJ,MAAM,QAAQ,GAAG,IAAI,OAAO,EAGzB,CAAC;AAEJ,MAAM,UAAU,GAAG,CAAC,GAAY,EAAE,EAAE;IAClC,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAa,GAAG,CAAC,CAEjB,CAAC;QAChD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,SAAkB,EAClB,KAAc,EACd,OAAyC,EACd,EAAE,CAC7B,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,EAAE,EAAE,CAC1C,IAAI,KAAK,SAAS;IAChB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;IACvB,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAC/B,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EACxB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CACjB,CACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-validation.test.d.ts","sourceRoot":"","sources":["../src/response-validation.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
6
|
+
import * as HttpClientResponse from "effect/http/HttpClientResponse";
|
|
7
|
+
import * as API from "./api.js";
|
|
8
|
+
import { makeRestProtocol } from "./protocol-rest.js";
|
|
9
|
+
import * as ResponseValidation from "./response-validation.js";
|
|
10
|
+
class TestParseError extends Schema.TaggedError()("TestParseError", { body: Schema.Unknown, cause: Schema.Unknown }) {
|
|
11
|
+
}
|
|
12
|
+
class TestUnknownError extends Schema.TaggedError()("TestUnknownError", { message: Schema.String }) {
|
|
13
|
+
}
|
|
14
|
+
const TestProtocol = makeRestProtocol({
|
|
15
|
+
credentials: Effect.succeed({}),
|
|
16
|
+
baseUrl: () => "https://api.test",
|
|
17
|
+
headers: () => ({}),
|
|
18
|
+
unknownError: ({ message }) => new TestUnknownError({ message }),
|
|
19
|
+
parseError: ({ body, cause }) => new TestParseError({ body, cause }),
|
|
20
|
+
});
|
|
21
|
+
const Output = Schema.Struct({ id: Schema.String });
|
|
22
|
+
const decode = (body) => Effect.gen(function* () {
|
|
23
|
+
const protocol = yield* API.Protocol;
|
|
24
|
+
const request = HttpClientRequest.get("https://api.test/thing");
|
|
25
|
+
return yield* protocol.decode({
|
|
26
|
+
response: HttpClientResponse.fromWeb(request, new Response(body, { status: 200 })),
|
|
27
|
+
outputAst: Output.ast,
|
|
28
|
+
errors: [],
|
|
29
|
+
config: {},
|
|
30
|
+
});
|
|
31
|
+
}).pipe(Effect.provide(TestProtocol));
|
|
32
|
+
const run = (effect, layer) => Effect.runPromise(Effect.result(layer ? effect.pipe(Effect.provide(layer)) : effect));
|
|
33
|
+
describe("makeRestProtocol response validation", () => {
|
|
34
|
+
test("lenient (default) returns a non-JSON 2xx body as text", async () => {
|
|
35
|
+
const result = await run(decode("not json"));
|
|
36
|
+
expect(result).toMatchObject({ _tag: "Success", success: "not json" });
|
|
37
|
+
});
|
|
38
|
+
test("lenient (default) returns {} for an output that requires id", async () => {
|
|
39
|
+
const result = await run(decode("{}"));
|
|
40
|
+
expect(result).toMatchObject({ _tag: "Success", success: {} });
|
|
41
|
+
});
|
|
42
|
+
test("strict fails a non-JSON 2xx body with the provider's parse error", async () => {
|
|
43
|
+
const result = await run(decode("not json"), ResponseValidation.strict);
|
|
44
|
+
expect(result._tag).toBe("Failure");
|
|
45
|
+
const error = result.failure;
|
|
46
|
+
expect(error).toBeInstanceOf(TestParseError);
|
|
47
|
+
expect(error.body).toBe("not json");
|
|
48
|
+
});
|
|
49
|
+
test("strict fails a body missing a required member", async () => {
|
|
50
|
+
const result = await run(decode("{}"), ResponseValidation.strict);
|
|
51
|
+
expect(result._tag).toBe("Failure");
|
|
52
|
+
expect(result.failure).toBeInstanceOf(TestParseError);
|
|
53
|
+
expect(result.failure.body).toEqual({});
|
|
54
|
+
});
|
|
55
|
+
test("strict passes a matching body through unchanged, extra members included", async () => {
|
|
56
|
+
const result = await run(decode(JSON.stringify({ id: "a", extra: 1 })), ResponseValidation.strict);
|
|
57
|
+
expect(result).toMatchObject({
|
|
58
|
+
_tag: "Success",
|
|
59
|
+
success: { id: "a", extra: 1 },
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
test("an inner lenient layer overrides an outer strict one", async () => {
|
|
63
|
+
const result = await run(decode("{}").pipe(Effect.provide(ResponseValidation.lenient)), ResponseValidation.strict);
|
|
64
|
+
expect(result).toMatchObject({ _tag: "Success", success: {} });
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=response-validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-validation.test.js","sourceRoot":"","sources":["../src/response-validation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAE/D,MAAM,cAAe,SAAQ,MAAM,CAAC,WAAW,EAAkB,CAC/D,gBAAgB,EAChB,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAChD;CAAG;AAEJ,MAAM,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CACnE,kBAAkB,EAClB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAC3B;CAAG;AAEJ,MAAM,YAAY,GAAG,gBAAgB,CAAK;IACxC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,kBAAkB;IACjC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;IACnB,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAChE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;CACrE,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAEpD,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAC9B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;IACrC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAChE,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5B,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAClC,OAAO,EACP,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CACpC;QACD,SAAS,EAAE,MAAM,CAAC,GAAG;QACrB,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;AACL,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAExC,MAAM,GAAG,GAAG,CAAO,MAA2B,EAAE,KAA0B,EAAE,EAAE,CAC5E,MAAM,CAAC,UAAU,CACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CACnE,CAAC;AAEJ,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,KAAK,GAAI,MAAc,CAAC,OAAO,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAE,MAAc,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QAC/D,MAAM,CAAE,MAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7C,kBAAkB,CAAC,MAAM,CAC1B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC;YAC3B,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAC7D,kBAAkB,CAAC,MAAM,CAC1B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/lib/testing.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test helpers for SDK packages: a canned-response `HttpClient` and a runner
|
|
3
|
+
* that executes one operation under both response-validation modes.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* const { lenient, strict } = await runValidationModes(
|
|
7
|
+
* Pkg.getThing({ id: "a" }).pipe(Retry.none, Effect.provide(TestCredentials)),
|
|
8
|
+
* { body: "{}" },
|
|
9
|
+
* );
|
|
10
|
+
* expect(lenient).toMatchObject({ _tag: "Success", success: {} });
|
|
11
|
+
* expect(strict).toMatchObject({ _tag: "Failure" });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as Layer from "effect/Layer";
|
|
16
|
+
import type * as Result from "effect/Result";
|
|
17
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
18
|
+
import type * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
19
|
+
export interface MockResponse {
|
|
20
|
+
/** Default 200. */
|
|
21
|
+
readonly status?: number;
|
|
22
|
+
/** Default `application/json`. */
|
|
23
|
+
readonly headers?: Record<string, string>;
|
|
24
|
+
readonly body: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An `HttpClient` that answers every request with `response` (or with what
|
|
28
|
+
* `response(request)` returns, for protocols that make more than one call).
|
|
29
|
+
*/
|
|
30
|
+
export declare const mockHttpClient: (response: MockResponse | ((request: HttpClientRequest.HttpClientRequest) => MockResponse)) => Layer.Layer<HttpClient.HttpClient>;
|
|
31
|
+
/**
|
|
32
|
+
* Run `effect` against `mockHttpClient(response)` once in lenient mode and
|
|
33
|
+
* once in strict mode.
|
|
34
|
+
*/
|
|
35
|
+
export declare const runValidationModes: <A, E>(effect: Effect.Effect<A, E, HttpClient.HttpClient>, response: Parameters<typeof mockHttpClient>[0]) => Promise<{
|
|
36
|
+
readonly lenient: Result.Result<A, E>;
|
|
37
|
+
readonly strict: Result.Result<A, E>;
|
|
38
|
+
}>;
|
|
39
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AAIxE,MAAM,WAAW,YAAY;IAC3B,mBAAmB;IACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kCAAkC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,aAErB,YAAY,GACZ,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,KAAK,YAAY,CAAC,KACnE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAejC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,CAAC,UAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,YACxC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,KAC7C,OAAO,CAAC;IACT,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACtC,CAaA,CAAC"}
|
package/lib/testing.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test helpers for SDK packages: a canned-response `HttpClient` and a runner
|
|
3
|
+
* that executes one operation under both response-validation modes.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* const { lenient, strict } = await runValidationModes(
|
|
7
|
+
* Pkg.getThing({ id: "a" }).pipe(Retry.none, Effect.provide(TestCredentials)),
|
|
8
|
+
* { body: "{}" },
|
|
9
|
+
* );
|
|
10
|
+
* expect(lenient).toMatchObject({ _tag: "Success", success: {} });
|
|
11
|
+
* expect(strict).toMatchObject({ _tag: "Failure" });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as Layer from "effect/Layer";
|
|
16
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
17
|
+
import * as HttpClientResponse from "effect/http/HttpClientResponse";
|
|
18
|
+
import * as ResponseValidation from "./response-validation.js";
|
|
19
|
+
/**
|
|
20
|
+
* An `HttpClient` that answers every request with `response` (or with what
|
|
21
|
+
* `response(request)` returns, for protocols that make more than one call).
|
|
22
|
+
*/
|
|
23
|
+
export const mockHttpClient = (response) => Layer.succeed(HttpClient.HttpClient, HttpClient.make((request) => Effect.sync(() => {
|
|
24
|
+
const r = typeof response === "function" ? response(request) : response;
|
|
25
|
+
return HttpClientResponse.fromWeb(request, new Response(r.body, {
|
|
26
|
+
status: r.status ?? 200,
|
|
27
|
+
headers: r.headers ?? { "content-type": "application/json" },
|
|
28
|
+
}));
|
|
29
|
+
})));
|
|
30
|
+
/**
|
|
31
|
+
* Run `effect` against `mockHttpClient(response)` once in lenient mode and
|
|
32
|
+
* once in strict mode.
|
|
33
|
+
*/
|
|
34
|
+
export const runValidationModes = (effect, response) => {
|
|
35
|
+
const run = (mode) => effect.pipe(Effect.provide(mockHttpClient(response)), Effect.provide(mode), Effect.result);
|
|
36
|
+
return Effect.runPromise(Effect.all({
|
|
37
|
+
lenient: run(ResponseValidation.lenient),
|
|
38
|
+
strict: run(ResponseValidation.strict),
|
|
39
|
+
}));
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AAErD,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAU/D;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAEoE,EAChC,EAAE,CACtC,KAAK,CAAC,OAAO,CACX,UAAU,CAAC,UAAU,EACrB,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,MAAM,CAAC,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxE,OAAO,kBAAkB,CAAC,OAAO,CAC/B,OAAO,EACP,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG;QACvB,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAC7D,CAAC,CACH,CAAC;AACJ,CAAC,CAAC,CACH,CACF,CAAC;AAEJ;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAkD,EAClD,QAA8C,EAI7C,EAAE;IACH,MAAM,GAAG,GAAG,CAAC,IAAwB,EAAE,EAAE,CACvC,MAAM,CAAC,IAAI,CACT,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EACpB,MAAM,CAAC,MAAM,CACd,CAAC;IACJ,OAAO,MAAM,CAAC,UAAU,CACtB,MAAM,CAAC,GAAG,CAAC;QACT,OAAO,EAAE,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC;QACxC,MAAM,EAAE,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC;KACvC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC"}
|
package/lib/trait.d.ts
CHANGED
|
@@ -65,6 +65,11 @@ export declare const Http: (trait: HttpTrait) => Annotation;
|
|
|
65
65
|
export declare const labelSymbol: unique symbol;
|
|
66
66
|
/** Bind a member to a `{name}` placeholder in the operation's URI template. */
|
|
67
67
|
export declare const Label: (name?: string) => Annotation;
|
|
68
|
+
export declare const labelEncodingSymbol: unique symbol;
|
|
69
|
+
/** Preserve selected RFC 3986 pchar delimiters inside a single URI label. */
|
|
70
|
+
export declare const LabelEncoding: (options: {
|
|
71
|
+
readonly preserve: string;
|
|
72
|
+
}) => Annotation;
|
|
68
73
|
export declare const responseCodeSymbol: unique symbol;
|
|
69
74
|
export declare const ResponseCode: () => Annotation;
|
|
70
75
|
export declare const headerSymbol: unique symbol;
|
|
@@ -147,20 +152,35 @@ export interface UnionDiscriminator {
|
|
|
147
152
|
*/
|
|
148
153
|
export declare const UnionCases: (cases: ReadonlyArray<ReadonlyArray<string>>, discriminator?: UnionDiscriminator) => Annotation;
|
|
149
154
|
export declare const errorMatchersSymbol: unique symbol;
|
|
155
|
+
/** Exact text, or the conjunction of substring and regular-expression constraints. */
|
|
156
|
+
export type ErrorTextMatcher = string | {
|
|
157
|
+
readonly includes?: string;
|
|
158
|
+
readonly matches?: string;
|
|
159
|
+
};
|
|
150
160
|
/**
|
|
151
|
-
* One wire-matching rule
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* `
|
|
161
|
+
* One wire-matching rule. All supplied constraints must match; separate
|
|
162
|
+
* matchers on a class are alternatives. Empty matchers match nothing.
|
|
163
|
+
*
|
|
164
|
+
* `body` maps RFC 6901 JSON Pointers to scalar constraints. For example,
|
|
165
|
+
* `{ "/success": false, "/result/status": "error" }`. Strings also accept
|
|
166
|
+
* `includes` / `matches`. Missing fields never match, including against null.
|
|
167
|
+
* The empty pointer addresses the entire body; array indices are supported.
|
|
168
|
+
* Header names are case-insensitive; their value constraints are case-sensitive.
|
|
169
|
+
* Each body path and header adds one specificity point, like code/status/message.
|
|
170
|
+
* Protocols evaluate these rules only after identifying a failed response.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* { status: 200, body: { "/success": false, "/result/status": "error" } }
|
|
175
|
+
* { status: 409, headers: { "x-error-type": { includes: "Conflict" } } }
|
|
176
|
+
* ```
|
|
156
177
|
*/
|
|
157
178
|
export interface ErrorMatcher {
|
|
158
179
|
readonly code?: number;
|
|
159
180
|
readonly status?: number;
|
|
160
|
-
readonly message?:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
};
|
|
181
|
+
readonly message?: ErrorTextMatcher;
|
|
182
|
+
readonly body?: Readonly<Record<string, ErrorTextMatcher | number | boolean | null>>;
|
|
183
|
+
readonly headers?: Readonly<Record<string, ErrorTextMatcher>>;
|
|
164
184
|
}
|
|
165
185
|
/**
|
|
166
186
|
* Stamp wire-matching rules onto a generated error class. Protocols consult
|
package/lib/trait.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trait.d.ts","sourceRoot":"","sources":["../src/trait.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"trait.d.ts","sourceRoot":"","sources":["../src/trait.ts"],"names":[],"mappings":"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"}
|
package/lib/trait.js
CHANGED
|
@@ -43,6 +43,14 @@ export const Http = (trait) => makeAnnotation(httpSymbol, trait);
|
|
|
43
43
|
export const labelSymbol = Symbol.for("@distilled.cloud/core/http/label");
|
|
44
44
|
/** Bind a member to a `{name}` placeholder in the operation's URI template. */
|
|
45
45
|
export const Label = (name) => makeAnnotation(labelSymbol, name ?? true);
|
|
46
|
+
export const labelEncodingSymbol = Symbol.for("@distilled.cloud/core/http/label-encoding");
|
|
47
|
+
/** Preserve selected RFC 3986 pchar delimiters inside a single URI label. */
|
|
48
|
+
export const LabelEncoding = (options) => {
|
|
49
|
+
if (!/^[!$&'()*+,;=:@]*$/.test(options.preserve)) {
|
|
50
|
+
throw new TypeError("LabelEncoding can preserve only URI path-segment delimiters");
|
|
51
|
+
}
|
|
52
|
+
return makeAnnotation(labelEncodingSymbol, options.preserve);
|
|
53
|
+
};
|
|
46
54
|
export const responseCodeSymbol = Symbol.for("@distilled.cloud/core/http/response-code");
|
|
47
55
|
export const ResponseCode = () => makeAnnotation(responseCodeSymbol, true);
|
|
48
56
|
export const headerSymbol = Symbol.for("@distilled.cloud/core/http/header");
|