@distilled.cloud/core 0.0.0-john
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/README.md +30 -0
- package/lib/category.d.ts +260 -0
- package/lib/category.d.ts.map +1 -0
- package/lib/category.js +264 -0
- package/lib/category.js.map +1 -0
- package/lib/client.d.ts +149 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +342 -0
- package/lib/client.js.map +1 -0
- package/lib/errors.d.ts +211 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +138 -0
- package/lib/errors.js.map +1 -0
- package/lib/json-patch.d.ts +44 -0
- package/lib/json-patch.d.ts.map +1 -0
- package/lib/json-patch.js +208 -0
- package/lib/json-patch.js.map +1 -0
- package/lib/pagination.d.ts +85 -0
- package/lib/pagination.d.ts.map +1 -0
- package/lib/pagination.js +177 -0
- package/lib/pagination.js.map +1 -0
- package/lib/retry.d.ts +99 -0
- package/lib/retry.d.ts.map +1 -0
- package/lib/retry.js +106 -0
- package/lib/retry.js.map +1 -0
- package/lib/sensitive.d.ts +50 -0
- package/lib/sensitive.d.ts.map +1 -0
- package/lib/sensitive.js +64 -0
- package/lib/sensitive.js.map +1 -0
- package/lib/traits.d.ts +274 -0
- package/lib/traits.d.ts.map +1 -0
- package/lib/traits.js +479 -0
- package/lib/traits.js.map +1 -0
- package/package.json +80 -0
- package/src/category.ts +406 -0
- package/src/client.ts +631 -0
- package/src/errors.ts +178 -0
- package/src/json-patch.ts +261 -0
- package/src/pagination.ts +303 -0
- package/src/retry.ts +177 -0
- package/src/sensitive.ts +74 -0
- package/src/traits.ts +641 -0
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST API Client
|
|
3
|
+
*
|
|
4
|
+
* Provides the core API.make() factory for building typed Effect-based API operations.
|
|
5
|
+
* This is the shared client for REST/OpenAPI-style SDKs (PlanetScale, Neon, GCP).
|
|
6
|
+
*
|
|
7
|
+
* AWS and Cloudflare have their own more specialized client implementations,
|
|
8
|
+
* but they share the same OperationMethod pattern.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { API } from "@distilled.cloud/core/client";
|
|
13
|
+
*
|
|
14
|
+
* const listDatabases = API.make(() => ({
|
|
15
|
+
* inputSchema: ListDatabasesInput,
|
|
16
|
+
* outputSchema: ListDatabasesOutput,
|
|
17
|
+
* errors: [NotFound, Forbidden] as const,
|
|
18
|
+
* }));
|
|
19
|
+
*
|
|
20
|
+
* // Direct call
|
|
21
|
+
* const result = yield* listDatabases({ organization: "my-org" });
|
|
22
|
+
*
|
|
23
|
+
* // Yield first for requirement-free function
|
|
24
|
+
* const fn = yield* listDatabases;
|
|
25
|
+
* const result = yield* fn({ organization: "my-org" });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import * as Effect from "effect/Effect";
|
|
29
|
+
import * as Schema from "effect/Schema";
|
|
30
|
+
import * as Stream from "effect/Stream";
|
|
31
|
+
import { type PaginatedTrait, type PaginationStrategy } from "./pagination.ts";
|
|
32
|
+
import * as Traits from "./traits.ts";
|
|
33
|
+
/**
|
|
34
|
+
* An operation that can be used in two ways:
|
|
35
|
+
* 1. Direct call: `yield* operation(input)` - returns Effect with requirements
|
|
36
|
+
* 2. Yield first: `const fn = yield* operation` - captures services, returns requirement-free function
|
|
37
|
+
*/
|
|
38
|
+
export type OperationMethod<I, A, E, R> = Effect.Effect<(input: I) => Effect.Effect<A, E, never>, never, R> & ((input: I) => Effect.Effect<A, E, R>);
|
|
39
|
+
/**
|
|
40
|
+
* A paginated operation that additionally has `.pages()` and `.items()` methods.
|
|
41
|
+
*/
|
|
42
|
+
type PaginatedItem<A> = A extends ReadonlyArray<infer Item> ? Item : A extends {
|
|
43
|
+
result: ReadonlyArray<infer Item>;
|
|
44
|
+
} ? Item : A extends {
|
|
45
|
+
result?: ReadonlyArray<infer Item> | null | undefined;
|
|
46
|
+
} ? Item : A extends {
|
|
47
|
+
result: {
|
|
48
|
+
items: ReadonlyArray<infer Item>;
|
|
49
|
+
};
|
|
50
|
+
} ? Item : A extends {
|
|
51
|
+
result?: {
|
|
52
|
+
items?: ReadonlyArray<infer Item> | null | undefined;
|
|
53
|
+
} | null | undefined;
|
|
54
|
+
} ? Item : unknown;
|
|
55
|
+
export type PaginatedOperationMethod<I, A, E, R> = OperationMethod<I, A, E, R> & {
|
|
56
|
+
pages: (input: I) => Stream.Stream<A, E, R>;
|
|
57
|
+
items: (input: I) => Stream.Stream<PaginatedItem<A>, E, R>;
|
|
58
|
+
};
|
|
59
|
+
type ResolvedClientCredentials<Creds> = Creds extends Effect.Effect<infer Resolved, any, any> ? Resolved : Creds;
|
|
60
|
+
/**
|
|
61
|
+
* Configuration for the API client factory.
|
|
62
|
+
* SDKs provide this to customize how errors are matched and credentials are applied.
|
|
63
|
+
*/
|
|
64
|
+
export interface ClientConfig<Creds> {
|
|
65
|
+
/** The credentials service tag */
|
|
66
|
+
credentials: {
|
|
67
|
+
new (): Creds;
|
|
68
|
+
};
|
|
69
|
+
/** Get the base URL from credentials */
|
|
70
|
+
getBaseUrl: (creds: ResolvedClientCredentials<Creds>) => string;
|
|
71
|
+
/** Get authorization header(s) from credentials */
|
|
72
|
+
getAuthHeaders: (creds: ResolvedClientCredentials<Creds>) => Record<string, string>;
|
|
73
|
+
/** Match an error response body to a typed error.
|
|
74
|
+
* Should return Effect.fail(error) for known errors,
|
|
75
|
+
* or Effect.fail(fallbackError) for unknown errors.
|
|
76
|
+
* The optional `errors` parameter provides per-operation typed error classes.
|
|
77
|
+
*/
|
|
78
|
+
matchError: (status: number, body: unknown, errors?: readonly ApiErrorClass[]) => Effect.Effect<never, unknown>;
|
|
79
|
+
/** Parse error class for schema decode failures */
|
|
80
|
+
ParseError: new (props: {
|
|
81
|
+
body: unknown;
|
|
82
|
+
cause: unknown;
|
|
83
|
+
}) => unknown;
|
|
84
|
+
/**
|
|
85
|
+
* Optional transform applied to the response body before schema decoding.
|
|
86
|
+
* For example, Cloudflare wraps responses in `{ result: <data>, ... }`.
|
|
87
|
+
*/
|
|
88
|
+
transformResponse?: (body: unknown) => unknown;
|
|
89
|
+
/**
|
|
90
|
+
* Optional transform applied to encoded request parts before building the
|
|
91
|
+
* outbound HTTP request.
|
|
92
|
+
*/
|
|
93
|
+
transformRequestParts?: (input: {
|
|
94
|
+
input: Record<string, unknown>;
|
|
95
|
+
method: string;
|
|
96
|
+
pathTemplate: string;
|
|
97
|
+
parts: Traits.RequestParts;
|
|
98
|
+
}) => Traits.RequestParts;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Base API error type - any error class with at least a _tag and message.
|
|
102
|
+
* Uses `new (...args: any[])` to accommodate error classes with extra fields (e.g. `code`).
|
|
103
|
+
*/
|
|
104
|
+
export type ApiErrorClass = {
|
|
105
|
+
new (...args: any[]): {
|
|
106
|
+
readonly _tag: string;
|
|
107
|
+
readonly message: string;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Operation configuration with optional operation-specific errors.
|
|
112
|
+
* Supports both `inputSchema`/`outputSchema` and `input`/`output` aliases.
|
|
113
|
+
*/
|
|
114
|
+
export interface OperationConfig<I extends Schema.Top, O extends Schema.Top, E extends readonly ApiErrorClass[] = readonly ApiErrorClass[]> {
|
|
115
|
+
inputSchema?: I;
|
|
116
|
+
outputSchema?: O;
|
|
117
|
+
/** Alias for inputSchema (used by Cloudflare/GCP generators) */
|
|
118
|
+
input?: I;
|
|
119
|
+
/** Alias for outputSchema (used by Cloudflare/GCP generators) */
|
|
120
|
+
output?: O;
|
|
121
|
+
errors?: E;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Paginated operation configuration.
|
|
125
|
+
*/
|
|
126
|
+
export interface PaginatedOperationConfig<I extends Schema.Top, O extends Schema.Top, E extends readonly ApiErrorClass[] = readonly ApiErrorClass[]> extends OperationConfig<I, O, E> {
|
|
127
|
+
pagination?: PaginatedTrait;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates an API namespace bound to a specific SDK's client configuration.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* // In planetscale-sdk/src/client.ts
|
|
135
|
+
* export const API = makeAPI({
|
|
136
|
+
* credentials: Credentials,
|
|
137
|
+
* getBaseUrl: (c) => c.apiBaseUrl,
|
|
138
|
+
* getAuthHeaders: (c) => ({ Authorization: c.token }),
|
|
139
|
+
* matchError: matchPlanetScaleError,
|
|
140
|
+
* ParseError: PlanetScaleParseError,
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare const makeAPI: <Creds>(config: ClientConfig<Creds>) => {
|
|
145
|
+
make: <I extends Schema.Top, O extends Schema.Top, const E extends readonly ApiErrorClass[] = readonly []>(configFn: () => OperationConfig<I, O, E>) => any;
|
|
146
|
+
makePaginated: <I extends Schema.Top, O extends Schema.Top, const E extends readonly ApiErrorClass[] = readonly []>(configFn: () => PaginatedOperationConfig<I, O, E>, paginateFn?: PaginationStrategy | undefined) => any;
|
|
147
|
+
};
|
|
148
|
+
export {};
|
|
149
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST API Client
|
|
3
|
+
*
|
|
4
|
+
* Provides the core API.make() factory for building typed Effect-based API operations.
|
|
5
|
+
* This is the shared client for REST/OpenAPI-style SDKs (PlanetScale, Neon, GCP).
|
|
6
|
+
*
|
|
7
|
+
* AWS and Cloudflare have their own more specialized client implementations,
|
|
8
|
+
* but they share the same OperationMethod pattern.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { API } from "@distilled.cloud/core/client";
|
|
13
|
+
*
|
|
14
|
+
* const listDatabases = API.make(() => ({
|
|
15
|
+
* inputSchema: ListDatabasesInput,
|
|
16
|
+
* outputSchema: ListDatabasesOutput,
|
|
17
|
+
* errors: [NotFound, Forbidden] as const,
|
|
18
|
+
* }));
|
|
19
|
+
*
|
|
20
|
+
* // Direct call
|
|
21
|
+
* const result = yield* listDatabases({ organization: "my-org" });
|
|
22
|
+
*
|
|
23
|
+
* // Yield first for requirement-free function
|
|
24
|
+
* const fn = yield* listDatabases;
|
|
25
|
+
* const result = yield* fn({ organization: "my-org" });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import * as Effect from "effect/Effect";
|
|
29
|
+
import { pipeArguments } from "effect/Pipeable";
|
|
30
|
+
import * as Schema from "effect/Schema";
|
|
31
|
+
import * as AST from "effect/SchemaAST";
|
|
32
|
+
import * as Stream from "effect/Stream";
|
|
33
|
+
import * as HttpBody from "effect/unstable/http/HttpBody";
|
|
34
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
35
|
+
import * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
36
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
37
|
+
import { SingleShotGen } from "effect/Utils";
|
|
38
|
+
import { extractItems, paginateWithDefaults, } from "./pagination.js";
|
|
39
|
+
import * as Traits from "./traits.js";
|
|
40
|
+
import { getPath } from "./traits.js";
|
|
41
|
+
const isEffectLike = (value) => typeof value === "object" &&
|
|
42
|
+
value !== null &&
|
|
43
|
+
typeof value.pipe === "function" &&
|
|
44
|
+
typeof value[Symbol.iterator] ===
|
|
45
|
+
"function";
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// AST Helpers
|
|
48
|
+
// ============================================================================
|
|
49
|
+
/**
|
|
50
|
+
* Check if a schema AST represents an array type.
|
|
51
|
+
* Follows encoding chains and Suspend wrappers.
|
|
52
|
+
*/
|
|
53
|
+
function isArrayAST(ast) {
|
|
54
|
+
if (ast._tag === "Arrays")
|
|
55
|
+
return true;
|
|
56
|
+
if (ast._tag === "Suspend")
|
|
57
|
+
return isArrayAST(ast.thunk());
|
|
58
|
+
if (ast.encoding && ast.encoding.length > 0)
|
|
59
|
+
return isArrayAST(ast.encoding[0].to);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Form URL-Encoded Builder (Stripe deepObject style)
|
|
64
|
+
// ============================================================================
|
|
65
|
+
/**
|
|
66
|
+
* Recursively flatten a nested object into Stripe-style bracket notation
|
|
67
|
+
* for application/x-www-form-urlencoded encoding.
|
|
68
|
+
*
|
|
69
|
+
* Examples:
|
|
70
|
+
* { amount: 2000 } -> "amount=2000"
|
|
71
|
+
* { shipping: { address: { city: "SF" } } } -> "shipping[address][city]=SF"
|
|
72
|
+
* { expand: ["data"] } -> "expand[0]=data"
|
|
73
|
+
* { metadata: { key: "val" } } -> "metadata[key]=val"
|
|
74
|
+
*/
|
|
75
|
+
function flattenToFormPairs(obj, prefix = "") {
|
|
76
|
+
const pairs = [];
|
|
77
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
78
|
+
if (value === undefined || value === null)
|
|
79
|
+
continue;
|
|
80
|
+
const fullKey = prefix ? `${prefix}[${key}]` : key;
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
for (let i = 0; i < value.length; i++) {
|
|
83
|
+
const item = value[i];
|
|
84
|
+
if (item !== null &&
|
|
85
|
+
item !== undefined &&
|
|
86
|
+
typeof item === "object" &&
|
|
87
|
+
!Array.isArray(item)) {
|
|
88
|
+
pairs.push(...flattenToFormPairs(item, `${fullKey}[${i}]`));
|
|
89
|
+
}
|
|
90
|
+
else if (item !== undefined && item !== null) {
|
|
91
|
+
pairs.push([`${fullKey}[${i}]`, String(item)]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (typeof value === "object") {
|
|
96
|
+
pairs.push(...flattenToFormPairs(value, fullKey));
|
|
97
|
+
}
|
|
98
|
+
else if (typeof value === "boolean") {
|
|
99
|
+
pairs.push([fullKey, value ? "true" : "false"]);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
pairs.push([fullKey, String(value)]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return pairs;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build a URLSearchParams from a nested object using Stripe deepObject encoding.
|
|
109
|
+
*/
|
|
110
|
+
function buildFormUrlEncoded(body) {
|
|
111
|
+
const pairs = flattenToFormPairs(body);
|
|
112
|
+
const params = new URLSearchParams();
|
|
113
|
+
for (const [key, value] of pairs) {
|
|
114
|
+
params.append(key, value);
|
|
115
|
+
}
|
|
116
|
+
return params.toString();
|
|
117
|
+
}
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Multipart FormData Builder
|
|
120
|
+
// ============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Check if a value is a File or Blob.
|
|
123
|
+
*/
|
|
124
|
+
function isFileOrBlob(value) {
|
|
125
|
+
return ((typeof File !== "undefined" && value instanceof File) ||
|
|
126
|
+
(typeof Blob !== "undefined" && value instanceof Blob));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build a FormData from a record of body properties.
|
|
130
|
+
* Handles files/blobs, arrays of files, objects (as JSON blobs), and primitives.
|
|
131
|
+
*
|
|
132
|
+
* This is used for multipart operations (e.g., Cloudflare Workers script uploads)
|
|
133
|
+
* where the body contains a mix of metadata objects and file uploads.
|
|
134
|
+
*/
|
|
135
|
+
function buildFormData(body) {
|
|
136
|
+
const formData = new FormData();
|
|
137
|
+
for (const [key, value] of Object.entries(body)) {
|
|
138
|
+
if (value === undefined || value === null)
|
|
139
|
+
continue;
|
|
140
|
+
if (isFileOrBlob(value)) {
|
|
141
|
+
// Single file/blob
|
|
142
|
+
formData.append(key, value, value instanceof File ? value.name : key);
|
|
143
|
+
}
|
|
144
|
+
else if (Array.isArray(value) &&
|
|
145
|
+
value.length > 0 &&
|
|
146
|
+
isFileOrBlob(value[0])) {
|
|
147
|
+
// Array of files/blobs — append each individually
|
|
148
|
+
for (const file of value) {
|
|
149
|
+
if (isFileOrBlob(file)) {
|
|
150
|
+
formData.append(file instanceof File ? file.name : key, file, file instanceof File ? file.name : undefined);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (typeof value === "object" && value !== null) {
|
|
155
|
+
// Object → append as JSON blob
|
|
156
|
+
formData.append(key, new Blob([JSON.stringify(value)], { type: "application/json" }), key);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Primitive → append as string
|
|
160
|
+
formData.append(key, String(value));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return formData;
|
|
164
|
+
}
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// API Client Factory
|
|
167
|
+
// ============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* Creates an API namespace bound to a specific SDK's client configuration.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* // In planetscale-sdk/src/client.ts
|
|
174
|
+
* export const API = makeAPI({
|
|
175
|
+
* credentials: Credentials,
|
|
176
|
+
* getBaseUrl: (c) => c.apiBaseUrl,
|
|
177
|
+
* getAuthHeaders: (c) => ({ Authorization: c.token }),
|
|
178
|
+
* matchError: matchPlanetScaleError,
|
|
179
|
+
* ParseError: PlanetScaleParseError,
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export const makeAPI = (config) => {
|
|
184
|
+
return {
|
|
185
|
+
make: (configFn) => {
|
|
186
|
+
const opConfig = configFn();
|
|
187
|
+
// Support both input/output and inputSchema/outputSchema aliases
|
|
188
|
+
const inputSchema = (opConfig.inputSchema ?? opConfig.input);
|
|
189
|
+
const outputSchema = (opConfig.outputSchema ?? opConfig.output);
|
|
190
|
+
const responsePath = Traits.getResponsePath(outputSchema.ast);
|
|
191
|
+
// Read HTTP trait from input schema annotations
|
|
192
|
+
const httpTrait = Traits.getHttpTrait(inputSchema.ast);
|
|
193
|
+
if (!httpTrait) {
|
|
194
|
+
throw new Error("Input schema must have Http trait");
|
|
195
|
+
}
|
|
196
|
+
const method = httpTrait.method;
|
|
197
|
+
const fn = (input) => Effect.gen(function* () {
|
|
198
|
+
const credentials = yield* config.credentials;
|
|
199
|
+
const creds = isEffectLike(credentials)
|
|
200
|
+
? yield* credentials
|
|
201
|
+
: credentials;
|
|
202
|
+
const client = yield* HttpClient.HttpClient;
|
|
203
|
+
const baseUrl = config.getBaseUrl(creds);
|
|
204
|
+
const authHeaders = config.getAuthHeaders(creds);
|
|
205
|
+
// Use schema-aware request builder for proper camelCase → wire_name mapping
|
|
206
|
+
let parts = Traits.buildRequestParts(inputSchema.ast, httpTrait, input, inputSchema);
|
|
207
|
+
if (config.transformRequestParts) {
|
|
208
|
+
parts = config.transformRequestParts({
|
|
209
|
+
input: input,
|
|
210
|
+
method,
|
|
211
|
+
pathTemplate: httpTrait.path,
|
|
212
|
+
parts,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
let request = HttpClientRequest.make(method)(baseUrl + parts.path).pipe(HttpClientRequest.setHeaders(authHeaders), HttpClientRequest.setHeaders(parts.headers), HttpClientRequest.setHeader("Accept", "application/json"));
|
|
216
|
+
// Set Content-Type based on body type
|
|
217
|
+
// - Skip for FormData (multipart) — browser sets boundary
|
|
218
|
+
// - Use form-urlencoded for Stripe-style APIs
|
|
219
|
+
// - Default to JSON
|
|
220
|
+
const isFormUrlEncoded = httpTrait.contentType === "form-urlencoded";
|
|
221
|
+
if (parts.isMultipart) {
|
|
222
|
+
// browser/runtime sets Content-Type with boundary
|
|
223
|
+
}
|
|
224
|
+
else if (isFormUrlEncoded) {
|
|
225
|
+
request = HttpClientRequest.setHeader("Content-Type", "application/x-www-form-urlencoded")(request);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
request = HttpClientRequest.setHeader("Content-Type", "application/json")(request);
|
|
229
|
+
}
|
|
230
|
+
if (Object.keys(parts.query).length > 0) {
|
|
231
|
+
request = HttpClientRequest.setUrlParams(request, parts.query);
|
|
232
|
+
}
|
|
233
|
+
if (method !== "GET" && parts.body !== undefined) {
|
|
234
|
+
if (parts.isMultipart) {
|
|
235
|
+
// Build FormData from body properties for multipart operations
|
|
236
|
+
const formData = buildFormData(parts.body);
|
|
237
|
+
request = HttpClientRequest.setBody(HttpBody.formData(formData))(request);
|
|
238
|
+
}
|
|
239
|
+
else if (isFormUrlEncoded) {
|
|
240
|
+
// Encode body as form-urlencoded with deepObject bracket notation
|
|
241
|
+
const encoded = buildFormUrlEncoded(parts.body);
|
|
242
|
+
request = HttpClientRequest.setBody(HttpBody.text(encoded, "application/x-www-form-urlencoded"))(request);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
request = yield* HttpClientRequest.bodyJson(parts.body)(request);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (method === "GET" && parts.body !== undefined) {
|
|
249
|
+
// For GET requests, remaining non-annotated fields go as query params
|
|
250
|
+
const extraQuery = {};
|
|
251
|
+
for (const [key, value] of Object.entries(parts.body)) {
|
|
252
|
+
if (value !== undefined) {
|
|
253
|
+
extraQuery[key] = String(value);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (Object.keys(extraQuery).length > 0) {
|
|
257
|
+
request = HttpClientRequest.setUrlParams(request, extraQuery);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const response = yield* client.execute(request).pipe(Effect.scoped);
|
|
261
|
+
if (response.status >= 400) {
|
|
262
|
+
// Try to parse error body as JSON; fall back to text if not JSON
|
|
263
|
+
const errorBody = yield* response.json.pipe(Effect.catchIf(() => true, () => response.text.pipe(Effect.map((text) => ({ _nonJsonError: true, body: text })), Effect.catchIf(() => true, () => Effect.succeed({
|
|
264
|
+
_nonJsonError: true,
|
|
265
|
+
body: `HTTP ${response.status}`,
|
|
266
|
+
})))));
|
|
267
|
+
return yield* config.matchError(response.status, errorBody, opConfig.errors);
|
|
268
|
+
}
|
|
269
|
+
// For void-returning operations (e.g. DELETE 204 No Content)
|
|
270
|
+
if (AST.isVoid(outputSchema.ast)) {
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
// For 204 No Content: if schema is not Unknown, return undefined.
|
|
274
|
+
// If schema IS Unknown, return empty string (so callers get a defined value).
|
|
275
|
+
if (response.status === 204) {
|
|
276
|
+
if (outputSchema.ast._tag === "Unknown") {
|
|
277
|
+
return "";
|
|
278
|
+
}
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
// Try to parse response as JSON; fall back to text for non-JSON responses
|
|
282
|
+
// (e.g., multipart/form-data worker scripts, raw KV values)
|
|
283
|
+
const rawBody = yield* response.json.pipe(Effect.catchIf(() => true, () => response.text.pipe(Effect.map((text) => text))));
|
|
284
|
+
let responseBody = config.transformResponse
|
|
285
|
+
? config.transformResponse(rawBody)
|
|
286
|
+
: rawBody;
|
|
287
|
+
if (responsePath) {
|
|
288
|
+
const nested = getPath(responseBody, responsePath);
|
|
289
|
+
if (nested !== undefined) {
|
|
290
|
+
responseBody =
|
|
291
|
+
responsePath === "result" && nested === null ? {} : nested;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// Handle Cloudflare-style paginated responses where result is
|
|
295
|
+
// { items: [...] } but the schema expects an array
|
|
296
|
+
if (isArrayAST(outputSchema.ast) &&
|
|
297
|
+
!Array.isArray(responseBody) &&
|
|
298
|
+
typeof responseBody === "object" &&
|
|
299
|
+
responseBody !== null &&
|
|
300
|
+
"items" in responseBody &&
|
|
301
|
+
Array.isArray(responseBody.items)) {
|
|
302
|
+
responseBody = responseBody.items;
|
|
303
|
+
}
|
|
304
|
+
return yield* Schema.decodeUnknownEffect(outputSchema)(responseBody).pipe(Effect.catchTag("SchemaError", (cause) => Effect.fail(new config.ParseError({ body: rawBody, cause }))));
|
|
305
|
+
});
|
|
306
|
+
const Proto = {
|
|
307
|
+
[Symbol.iterator]() {
|
|
308
|
+
return new SingleShotGen(this);
|
|
309
|
+
},
|
|
310
|
+
pipe() {
|
|
311
|
+
return pipeArguments(this.asEffect(), arguments);
|
|
312
|
+
},
|
|
313
|
+
asEffect() {
|
|
314
|
+
return Effect.map(Effect.services(), (sm) => (input) => fn(input).pipe(Effect.provide(sm)));
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
return Object.assign(fn, Proto);
|
|
318
|
+
},
|
|
319
|
+
makePaginated: (configFn, paginateFn) => {
|
|
320
|
+
const opConfig = configFn();
|
|
321
|
+
const pagination = opConfig.pagination;
|
|
322
|
+
// Create the base operation
|
|
323
|
+
const baseFn = makeAPI(config).make(() => ({
|
|
324
|
+
inputSchema: opConfig.inputSchema ?? opConfig.input,
|
|
325
|
+
outputSchema: opConfig.outputSchema ?? opConfig.output,
|
|
326
|
+
errors: opConfig.errors,
|
|
327
|
+
}));
|
|
328
|
+
const paginate = paginateFn ?? paginateWithDefaults;
|
|
329
|
+
// Stream all pages
|
|
330
|
+
const pagesFn = (input) => paginate(baseFn, input, pagination);
|
|
331
|
+
// Stream individual items
|
|
332
|
+
const itemsFn = (input) => pagination.items
|
|
333
|
+
? extractItems(pagesFn(input), pagination.items)
|
|
334
|
+
: pagesFn(input);
|
|
335
|
+
const result = baseFn;
|
|
336
|
+
result.pages = pagesFn;
|
|
337
|
+
result.items = itemsFn;
|
|
338
|
+
return result;
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|