samva 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -0
- package/README.md +18 -3
- package/dist/{rolldown-runtime-D7D4PA-g.js → _virtual/_rolldown/runtime.js} +1 -1
- package/dist/client/client/client.gen.js +174 -0
- package/dist/client/client/utils.gen.js +177 -0
- package/dist/client/client.gen.js +8 -0
- package/dist/client/core/auth.gen.js +12 -0
- package/dist/client/core/bodySerializer.gen.js +6 -0
- package/dist/client/core/params.gen.js +77 -0
- package/dist/client/core/pathSerializer.gen.js +82 -0
- package/dist/client/core/serverSentEvents.gen.js +96 -0
- package/dist/client/core/utils.gen.js +78 -0
- package/dist/client/sdk.gen.d.ts +39 -23
- package/dist/{promises---Kbh-7z.js → client/sdk.gen.js} +87 -2314
- package/dist/client/types.gen.d.ts +175 -44
- package/dist/client-attribution.js +9 -0
- package/dist/effect/analytics.d.ts +6 -6
- package/dist/effect/analytics.js +23 -2
- package/dist/effect/api-keys.d.ts +12 -12
- package/dist/effect/api-keys.js +29 -2
- package/dist/effect/attachments.d.ts +4 -4
- package/dist/effect/attachments.js +19 -2
- package/dist/effect/brands.d.ts +6 -6
- package/dist/effect/brands.js +26 -3
- package/dist/effect/campaigns.d.ts +18 -18
- package/dist/effect/campaigns.js +35 -2
- package/dist/effect/categories.d.ts +2 -2
- package/dist/effect/categories.js +95 -1
- package/dist/effect/client.js +3 -3
- package/dist/effect/contact-groups.d.ts +53 -17
- package/dist/effect/contact-groups.js +31 -2
- package/dist/effect/contacts.d.ts +244 -41
- package/dist/effect/contacts.js +54 -2
- package/dist/effect/conversations.d.ts +28 -28
- package/dist/effect/conversations.js +37 -2
- package/dist/effect/custom-fields.d.ts +4 -4
- package/dist/effect/custom-fields.js +19 -2
- package/dist/effect/email.d.ts +75 -75
- package/dist/effect/email.js +140 -2
- package/dist/effect/errors.d.ts +2 -0
- package/dist/effect/errors.js +3 -0
- package/dist/effect/events.d.ts +2 -2
- package/dist/effect/events.js +17 -3
- package/dist/effect/extension-installations.d.ts +23 -23
- package/dist/effect/extension-installations.js +29 -2
- package/dist/effect/extensions.d.ts +12 -12
- package/dist/effect/extensions.js +21 -2
- package/dist/effect/feedback.d.ts +1 -1
- package/dist/effect/feedback.js +14 -3
- package/dist/{analytics-CaqPRsry.js → effect/generated/analytics.js} +4 -23
- package/dist/{api-keys-Ce1Y4_Ip.js → effect/generated/api-keys.js} +4 -29
- package/dist/{attachments-DYqVIraC.js → effect/generated/attachments.js} +3 -18
- package/dist/{brands-ZwuOGIWO.js → effect/generated/brands.js} +5 -25
- package/dist/{campaigns-DZlz1E9E.js → effect/generated/campaigns.js} +4 -35
- package/dist/effect/generated/contact-events.js +37 -0
- package/dist/effect/generated/contact-groups.d.ts +33 -3
- package/dist/{contact-groups-BLbFXnjq.js → effect/generated/contact-groups.js} +3 -30
- package/dist/effect/generated/contacts.d.ts +477 -54
- package/dist/{contacts-BbsoXXB4.js → effect/generated/contacts.js} +41 -89
- package/dist/effect/generated/conversations.d.ts +25 -25
- package/dist/{conversations-_sRHueML.js → effect/generated/conversations.js} +4 -37
- package/dist/{custom-fields-BHWbwlKn.js → effect/generated/custom-fields.js} +5 -19
- package/dist/{email-R0NAA9PW.js → effect/generated/email.js} +995 -1146
- package/dist/{events-CxbTUHYT.js → effect/generated/events.js} +3 -15
- package/dist/effect/generated/extension-installations.d.ts +44 -44
- package/dist/{extension-installations-CD94LPmk.js → effect/generated/extension-installations.js} +10 -29
- package/dist/effect/generated/extensions.d.ts +10 -10
- package/dist/{extensions-BKyNQLvu.js → effect/generated/extensions.js} +5 -20
- package/dist/{feedback-Bpa09JOS.js → effect/generated/feedback.js} +3 -12
- package/dist/{journeys-CARo_BJT.js → effect/generated/journeys.js} +3 -38
- package/dist/effect/generated/mailboxes.d.ts +310 -0
- package/dist/{mailboxes-BRDn7BIK.js → effect/generated/mailboxes.js} +829 -954
- package/dist/{media-VrrtNnft.js → effect/generated/media.js} +3 -3
- package/dist/effect/generated/messages.d.ts +31 -0
- package/dist/effect/generated/messages.js +677 -0
- package/dist/{namespaces-CcvEbG-y.js → effect/generated/namespaces.js} +3 -20
- package/dist/{operations-CmB3FHwf.js → effect/generated/operations.js} +3 -16
- package/dist/effect/generated/organizations.d.ts +13 -11
- package/dist/{organizations-A-plufWc.js → effect/generated/organizations.js} +9 -26
- package/dist/{scheduled-messages-DkKZRRaN.js → effect/generated/scheduled-messages.js} +4 -21
- package/dist/effect/generated/shared.d.ts +70 -20
- package/dist/effect/generated/shared.js +1073 -0
- package/dist/{subscriptions-DEXYtMXg.js → effect/generated/subscriptions.js} +3 -9
- package/dist/{templates-DZomxsG7.js → effect/generated/templates.js} +3 -78
- package/dist/effect/generated/unsubscribe-groups.d.ts +173 -78
- package/dist/{unsubscribe-groups-Iqk4Isf9.js → effect/generated/unsubscribe-groups.js} +77 -84
- package/dist/effect/generated/webhooks.d.ts +19 -19
- package/dist/{webhooks-CPXuu8Xf.js → effect/generated/webhooks.js} +12 -34
- package/dist/{whoami-Ccz0jwlt.js → effect/generated/whoami.js} +5 -10
- package/dist/effect/generated-metadata.d.ts +7 -2
- package/dist/effect/generated-metadata.js +925 -0
- package/dist/effect/index.d.ts +1 -2
- package/dist/effect/index.js +32 -32
- package/dist/effect/internal/client.js +69 -0
- package/dist/effect/internal/email-sender.js +21 -0
- package/dist/effect/internal/mailbox-events.js +33 -0
- package/dist/effect/internal/operation.js +116 -0
- package/dist/effect/internal/send.js +56 -0
- package/dist/effect/journeys.d.ts +18 -18
- package/dist/effect/journeys.js +39 -2
- package/dist/effect/mailboxes.d.ts +314 -182
- package/dist/effect/mailboxes.js +135 -3
- package/dist/effect/media.d.ts +5 -5
- package/dist/effect/media.js +10 -10
- package/dist/effect/messages.d.ts +19 -14
- package/dist/effect/messages.js +15 -14
- package/dist/effect/namespaces.d.ts +7 -7
- package/dist/effect/namespaces.js +21 -2
- package/dist/effect/operations.d.ts +5 -5
- package/dist/effect/operations.js +17 -2
- package/dist/effect/organizations.d.ts +11 -11
- package/dist/effect/organizations.js +25 -2
- package/dist/effect/pagination.js +39 -0
- package/dist/effect/retry.js +3 -3
- package/dist/{runtime-P0l1_2-C.js → effect/runtime.js} +2 -2
- package/dist/effect/scheduled-messages.d.ts +7 -7
- package/dist/effect/scheduled-messages.js +21 -2
- package/dist/effect/subscriptions.d.ts +1 -1
- package/dist/effect/subscriptions.js +10 -2
- package/dist/effect/templates.d.ts +39 -39
- package/dist/effect/templates.js +80 -3
- package/dist/effect/unsubscribe-groups.d.ts +39 -28
- package/dist/effect/unsubscribe-groups.js +29 -2
- package/dist/effect/webhooks.d.ts +22 -22
- package/dist/effect/webhooks.js +35 -3
- package/dist/effect/whoami.d.ts +9 -9
- package/dist/effect/whoami.js +10 -2
- package/dist/index.js +4 -3
- package/dist/{inline-attachments-Bi1hDltp.js → inline-attachments.js} +13 -7
- package/dist/mailbox-events.d.ts +31 -4
- package/dist/{mailbox-events-VKR4f3qq.js → mailbox-events.js} +41 -13
- package/dist/{normalize-B79uJIeb.js → normalize.js} +2 -2
- package/dist/package.js +6 -0
- package/dist/promises/errors.gen.js +1340 -0
- package/dist/promises/index.d.ts +1 -1
- package/dist/promises/index.js +288 -3
- package/dist/promises/types.gen.d.ts +1 -1
- package/dist/service-map.d.ts +9 -4
- package/dist/{operation-n_IYgNVK.js → service-map.js} +12 -150
- package/package.json +6 -2
- package/dist/categories-CA4XIQAb.js +0 -1011
- package/dist/client-DOzUrdTE.js +0 -1115
- package/dist/send-Bxc0XfGE.js +0 -722
package/AGENTS.md
CHANGED
|
@@ -13,6 +13,11 @@ import focused entrypoints rather than the `samva/effect` barrel, which loads ev
|
|
|
13
13
|
Worker, provide the client Layer per request with the request's abort signal; in Lambda or another
|
|
14
14
|
long-lived process, build it once in a module-scope `ManagedRuntime`.
|
|
15
15
|
|
|
16
|
+
Import error constructors from `samva/effect/errors` for `instanceof` or schema decoding; they are
|
|
17
|
+
the same constructors the operations use. This entry avoids domain modules, though native imports
|
|
18
|
+
still initialize shared schemas. Bundlers can discard unused operation wrappers and their exclusive
|
|
19
|
+
API groups; operations within a retained group still share its schemas.
|
|
20
|
+
|
|
16
21
|
Treat exported request and response types as the API contract. Do not import package-internal files
|
|
17
22
|
or generated implementation paths; use only the subpaths declared in `package.json`.
|
|
18
23
|
|
package/README.md
CHANGED
|
@@ -86,9 +86,11 @@ const message = await Effect.runPromise(program);
|
|
|
86
86
|
### Serverless Runtimes
|
|
87
87
|
|
|
88
88
|
Each `samva/effect/<domain>` entrypoint loads only that domain's part of the API, so a Cloudflare
|
|
89
|
-
Worker or Lambda function pays at startup only for the domains it imports.
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
Worker or Lambda function pays at startup only for the domains it imports. A bundler can discard
|
|
90
|
+
unused operations and their exclusive API groups: importing only `Email.send` retains Messages
|
|
91
|
+
and Media, without email administration operations. Media handles oversized inline attachments.
|
|
92
|
+
Operations within a retained group still share that group's schemas. The `samva/effect` barrel
|
|
93
|
+
loads every domain on a native import; prefer focused entrypoints in serverless code.
|
|
92
94
|
|
|
93
95
|
`Client.layerFetch` does no work until the first call, and the first call to a domain prepares only
|
|
94
96
|
that domain, so providing the Layer costs little. In a Cloudflare Worker, provide it per request and
|
|
@@ -251,6 +253,17 @@ by `mediaId`; a failed upload throws `MediaUploadError` before the send request.
|
|
|
251
253
|
|
|
252
254
|
Effect failures carry Samva's real tagged errors (`RateLimitedError`, `ValidationError`, `PaymentRequiredError`, …) directly in the error channel, so `Effect.catchTag("RateLimitedError", …)` works against any operation without enumerating status codes, and each error exposes its own fields (no wrapper `cause`). The SDK also exports category helpers such as `isRetryable`, `isTransient`, `catchAuthError`, and `catchTransient`. Success values decode to domain types: annotated absolute instants become `Date`, sensitive fields become `Redacted`, and unannotated wire timestamps remain strings.
|
|
253
255
|
|
|
256
|
+
Import error constructors from `samva/effect/errors` when you need `instanceof`, schema decoding,
|
|
257
|
+
or to construct a failure in a test:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { InternalError, MediaUploadError } from "samva/effect/errors";
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
These are the same constructors the operations and `samva/effect` barrel use. The focused entry
|
|
264
|
+
avoids loading domain modules; a native import still initializes the shared schemas. Handling an
|
|
265
|
+
error with `Effect.catchTag` does not require importing its constructor.
|
|
266
|
+
|
|
254
267
|
### Default-on retry
|
|
255
268
|
|
|
256
269
|
The Effect client retries safe operations out of the box, so you do not wrap calls in `Effect.retry`:
|
|
@@ -474,6 +487,8 @@ caller has to act. Its `_tag` is the API error tag the host refused with (`Unaut
|
|
|
474
487
|
`ForbiddenError`, `ResourceNotFoundError`, `CursorExpiredError`, `ValidationError`, and the
|
|
475
488
|
rest), with the host's `message`, `status`, `fields`, and `retryAfterSeconds`. A `429`, `5xx`, or
|
|
476
489
|
`408` refusal is retried after the delay the host asked for; every other refusal ends the stream.
|
|
490
|
+
Pass `onReconnect` to see each retry before it waits. A connection that goes silent for 90 seconds
|
|
491
|
+
is closed by the client, and its error carries `reason: "idleTimeout"` instead of a `closeCode`.
|
|
477
492
|
It needs a runtime whose `WebSocket` accepts request headers, such as Node or Bun, or one passed
|
|
478
493
|
as the `WebSocket` option.
|
|
479
494
|
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { createSseClient } from "../core/serverSentEvents.gen.js";
|
|
2
|
+
import { getValidRequestBody } from "../core/utils.gen.js";
|
|
3
|
+
import { buildUrl, createConfig, createInterceptors, getParseAs, mergeConfigs, mergeHeaders, setAuthParams } from "./utils.gen.js";
|
|
4
|
+
//#region src/client/client/client.gen.ts
|
|
5
|
+
const createClient = (config = {}) => {
|
|
6
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
7
|
+
const getConfig = () => ({ ..._config });
|
|
8
|
+
const setConfig = (config) => {
|
|
9
|
+
_config = mergeConfigs(_config, config);
|
|
10
|
+
return getConfig();
|
|
11
|
+
};
|
|
12
|
+
const interceptors = createInterceptors();
|
|
13
|
+
const beforeRequest = async (options) => {
|
|
14
|
+
const opts = {
|
|
15
|
+
..._config,
|
|
16
|
+
...options,
|
|
17
|
+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
18
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
19
|
+
serializedBody: void 0
|
|
20
|
+
};
|
|
21
|
+
if (opts.security) await setAuthParams(opts);
|
|
22
|
+
if (opts.requestValidator) await opts.requestValidator(opts);
|
|
23
|
+
if (opts.body !== void 0 && opts.bodySerializer) opts.serializedBody = opts.bodySerializer(opts.body);
|
|
24
|
+
if (opts.body === void 0 || opts.serializedBody === "") opts.headers.delete("Content-Type");
|
|
25
|
+
const resolvedOpts = opts;
|
|
26
|
+
return {
|
|
27
|
+
opts: resolvedOpts,
|
|
28
|
+
url: buildUrl(resolvedOpts)
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const request = async (options) => {
|
|
32
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
33
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
34
|
+
let request;
|
|
35
|
+
let response;
|
|
36
|
+
try {
|
|
37
|
+
const { opts, url } = await beforeRequest(options);
|
|
38
|
+
const requestInit = {
|
|
39
|
+
redirect: "follow",
|
|
40
|
+
...opts,
|
|
41
|
+
body: getValidRequestBody(opts)
|
|
42
|
+
};
|
|
43
|
+
request = new Request(url, requestInit);
|
|
44
|
+
for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
|
|
45
|
+
const _fetch = opts.fetch;
|
|
46
|
+
response = await _fetch(request);
|
|
47
|
+
for (const fn of interceptors.response.fns) if (fn) response = await fn(response, request, opts);
|
|
48
|
+
const result = {
|
|
49
|
+
request,
|
|
50
|
+
response
|
|
51
|
+
};
|
|
52
|
+
if (response.ok) {
|
|
53
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
54
|
+
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
55
|
+
let emptyData;
|
|
56
|
+
switch (parseAs) {
|
|
57
|
+
case "arrayBuffer":
|
|
58
|
+
case "blob":
|
|
59
|
+
case "text":
|
|
60
|
+
emptyData = await response[parseAs]();
|
|
61
|
+
break;
|
|
62
|
+
case "formData":
|
|
63
|
+
emptyData = new FormData();
|
|
64
|
+
break;
|
|
65
|
+
case "stream":
|
|
66
|
+
emptyData = response.body;
|
|
67
|
+
break;
|
|
68
|
+
default: emptyData = {};
|
|
69
|
+
}
|
|
70
|
+
return opts.responseStyle === "data" ? emptyData : {
|
|
71
|
+
data: emptyData,
|
|
72
|
+
...result
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
let data;
|
|
76
|
+
switch (parseAs) {
|
|
77
|
+
case "arrayBuffer":
|
|
78
|
+
case "blob":
|
|
79
|
+
case "formData":
|
|
80
|
+
case "text":
|
|
81
|
+
data = await response[parseAs]();
|
|
82
|
+
break;
|
|
83
|
+
case "json": {
|
|
84
|
+
const text = await response.text();
|
|
85
|
+
data = text ? JSON.parse(text) : {};
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "stream": return opts.responseStyle === "data" ? response.body : {
|
|
89
|
+
data: response.body,
|
|
90
|
+
...result
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (parseAs === "json") {
|
|
94
|
+
if (opts.responseValidator) await opts.responseValidator(data);
|
|
95
|
+
if (opts.responseTransformer) data = await opts.responseTransformer(data);
|
|
96
|
+
}
|
|
97
|
+
return opts.responseStyle === "data" ? data : {
|
|
98
|
+
data,
|
|
99
|
+
...result
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const textError = await response.text();
|
|
103
|
+
let jsonError;
|
|
104
|
+
try {
|
|
105
|
+
jsonError = JSON.parse(textError);
|
|
106
|
+
} catch {}
|
|
107
|
+
throw jsonError ?? textError;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
let finalError = error;
|
|
110
|
+
for (const fn of interceptors.error.fns) if (fn) finalError = await fn(finalError, response, request, options);
|
|
111
|
+
finalError = finalError || {};
|
|
112
|
+
if (throwOnError) throw finalError;
|
|
113
|
+
return responseStyle === "data" ? void 0 : {
|
|
114
|
+
error: finalError,
|
|
115
|
+
request,
|
|
116
|
+
response
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const makeMethodFn = (method) => (options) => request({
|
|
121
|
+
...options,
|
|
122
|
+
method
|
|
123
|
+
});
|
|
124
|
+
const makeSseFn = (method) => async (options) => {
|
|
125
|
+
const { opts, url } = await beforeRequest(options);
|
|
126
|
+
return createSseClient({
|
|
127
|
+
...opts,
|
|
128
|
+
body: opts.body,
|
|
129
|
+
method,
|
|
130
|
+
onRequest: async (url, init) => {
|
|
131
|
+
let request = new Request(url, init);
|
|
132
|
+
for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
|
|
133
|
+
return request;
|
|
134
|
+
},
|
|
135
|
+
serializedBody: getValidRequestBody(opts),
|
|
136
|
+
url
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
const _buildUrl = (options) => buildUrl({
|
|
140
|
+
..._config,
|
|
141
|
+
...options
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
buildUrl: _buildUrl,
|
|
145
|
+
connect: makeMethodFn("CONNECT"),
|
|
146
|
+
delete: makeMethodFn("DELETE"),
|
|
147
|
+
get: makeMethodFn("GET"),
|
|
148
|
+
getConfig,
|
|
149
|
+
head: makeMethodFn("HEAD"),
|
|
150
|
+
interceptors,
|
|
151
|
+
options: makeMethodFn("OPTIONS"),
|
|
152
|
+
patch: makeMethodFn("PATCH"),
|
|
153
|
+
post: makeMethodFn("POST"),
|
|
154
|
+
put: makeMethodFn("PUT"),
|
|
155
|
+
request,
|
|
156
|
+
setConfig,
|
|
157
|
+
sse: {
|
|
158
|
+
connect: makeSseFn("CONNECT"),
|
|
159
|
+
delete: makeSseFn("DELETE"),
|
|
160
|
+
get: makeSseFn("GET"),
|
|
161
|
+
head: makeSseFn("HEAD"),
|
|
162
|
+
options: makeSseFn("OPTIONS"),
|
|
163
|
+
patch: makeSseFn("PATCH"),
|
|
164
|
+
post: makeSseFn("POST"),
|
|
165
|
+
put: makeSseFn("PUT"),
|
|
166
|
+
trace: makeSseFn("TRACE")
|
|
167
|
+
},
|
|
168
|
+
trace: makeMethodFn("TRACE")
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
//#endregion
|
|
172
|
+
export { createClient };
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=client.gen.js.map
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsonBodySerializer } from "../core/bodySerializer.gen.js";
|
|
2
|
+
import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam } from "../core/pathSerializer.gen.js";
|
|
3
|
+
import { getUrl } from "../core/utils.gen.js";
|
|
4
|
+
import { getAuthToken } from "../core/auth.gen.js";
|
|
5
|
+
//#region src/client/client/utils.gen.ts
|
|
6
|
+
const createQuerySerializer = ({ parameters = {}, ...args } = {}) => {
|
|
7
|
+
const querySerializer = (queryParams) => {
|
|
8
|
+
const search = [];
|
|
9
|
+
if (queryParams && typeof queryParams === "object") for (const name in queryParams) {
|
|
10
|
+
const value = queryParams[name];
|
|
11
|
+
if (value === void 0 || value === null) continue;
|
|
12
|
+
const options = parameters[name] || args;
|
|
13
|
+
if (Array.isArray(value)) {
|
|
14
|
+
const serializedArray = serializeArrayParam({
|
|
15
|
+
allowReserved: options.allowReserved,
|
|
16
|
+
explode: true,
|
|
17
|
+
name,
|
|
18
|
+
style: "form",
|
|
19
|
+
value,
|
|
20
|
+
...options.array
|
|
21
|
+
});
|
|
22
|
+
if (serializedArray) search.push(serializedArray);
|
|
23
|
+
} else if (typeof value === "object") {
|
|
24
|
+
const serializedObject = serializeObjectParam({
|
|
25
|
+
allowReserved: options.allowReserved,
|
|
26
|
+
explode: true,
|
|
27
|
+
name,
|
|
28
|
+
style: "deepObject",
|
|
29
|
+
value,
|
|
30
|
+
...options.object
|
|
31
|
+
});
|
|
32
|
+
if (serializedObject) search.push(serializedObject);
|
|
33
|
+
} else {
|
|
34
|
+
const serializedPrimitive = serializePrimitiveParam({
|
|
35
|
+
allowReserved: options.allowReserved,
|
|
36
|
+
name,
|
|
37
|
+
value
|
|
38
|
+
});
|
|
39
|
+
if (serializedPrimitive) search.push(serializedPrimitive);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return search.join("&");
|
|
43
|
+
};
|
|
44
|
+
return querySerializer;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Infers parseAs value from provided Content-Type header.
|
|
48
|
+
*/
|
|
49
|
+
const getParseAs = (contentType) => {
|
|
50
|
+
if (!contentType) return "stream";
|
|
51
|
+
const cleanContent = contentType.split(";")[0]?.trim();
|
|
52
|
+
if (!cleanContent) return;
|
|
53
|
+
if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) return "json";
|
|
54
|
+
if (cleanContent === "multipart/form-data") return "formData";
|
|
55
|
+
if ([
|
|
56
|
+
"application/",
|
|
57
|
+
"audio/",
|
|
58
|
+
"image/",
|
|
59
|
+
"video/"
|
|
60
|
+
].some((type) => cleanContent.startsWith(type))) return "blob";
|
|
61
|
+
if (cleanContent.startsWith("text/")) return "text";
|
|
62
|
+
};
|
|
63
|
+
const checkForExistence = (options, name) => {
|
|
64
|
+
if (!name) return false;
|
|
65
|
+
if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) return true;
|
|
66
|
+
return false;
|
|
67
|
+
};
|
|
68
|
+
async function setAuthParams(options) {
|
|
69
|
+
for (const auth of options.security ?? []) {
|
|
70
|
+
if (checkForExistence(options, auth.name)) continue;
|
|
71
|
+
const token = await getAuthToken(auth, options.auth);
|
|
72
|
+
if (!token) continue;
|
|
73
|
+
const name = auth.name ?? "Authorization";
|
|
74
|
+
switch (auth.in) {
|
|
75
|
+
case "query":
|
|
76
|
+
if (!options.query) options.query = {};
|
|
77
|
+
options.query[name] = token;
|
|
78
|
+
break;
|
|
79
|
+
case "cookie":
|
|
80
|
+
options.headers.append("Cookie", `${name}=${token}`);
|
|
81
|
+
break;
|
|
82
|
+
default: options.headers.set(name, token);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const buildUrl = (options) => getUrl({
|
|
87
|
+
baseUrl: options.baseUrl,
|
|
88
|
+
path: options.path,
|
|
89
|
+
query: options.query,
|
|
90
|
+
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
|
|
91
|
+
url: options.url
|
|
92
|
+
});
|
|
93
|
+
const mergeConfigs = (a, b) => {
|
|
94
|
+
const config = {
|
|
95
|
+
...a,
|
|
96
|
+
...b
|
|
97
|
+
};
|
|
98
|
+
if (config.baseUrl?.endsWith("/")) config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
99
|
+
config.headers = mergeHeaders(a.headers, b.headers);
|
|
100
|
+
return config;
|
|
101
|
+
};
|
|
102
|
+
const headersEntries = (headers) => {
|
|
103
|
+
const entries = [];
|
|
104
|
+
headers.forEach((value, key) => {
|
|
105
|
+
entries.push([key, value]);
|
|
106
|
+
});
|
|
107
|
+
return entries;
|
|
108
|
+
};
|
|
109
|
+
const mergeHeaders = (...headers) => {
|
|
110
|
+
const mergedHeaders = new Headers();
|
|
111
|
+
for (const header of headers) {
|
|
112
|
+
if (!header) continue;
|
|
113
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
114
|
+
for (const [key, value] of iterator) if (value === null) mergedHeaders.delete(key);
|
|
115
|
+
else if (Array.isArray(value)) for (const v of value) mergedHeaders.append(key, v);
|
|
116
|
+
else if (value !== void 0) mergedHeaders.set(key, typeof value === "object" ? JSON.stringify(value) : value);
|
|
117
|
+
}
|
|
118
|
+
return mergedHeaders;
|
|
119
|
+
};
|
|
120
|
+
var Interceptors = class {
|
|
121
|
+
fns = [];
|
|
122
|
+
clear() {
|
|
123
|
+
this.fns = [];
|
|
124
|
+
}
|
|
125
|
+
eject(id) {
|
|
126
|
+
const index = this.getInterceptorIndex(id);
|
|
127
|
+
if (this.fns[index]) this.fns[index] = null;
|
|
128
|
+
}
|
|
129
|
+
exists(id) {
|
|
130
|
+
const index = this.getInterceptorIndex(id);
|
|
131
|
+
return Boolean(this.fns[index]);
|
|
132
|
+
}
|
|
133
|
+
getInterceptorIndex(id) {
|
|
134
|
+
if (typeof id === "number") return this.fns[id] ? id : -1;
|
|
135
|
+
return this.fns.indexOf(id);
|
|
136
|
+
}
|
|
137
|
+
update(id, fn) {
|
|
138
|
+
const index = this.getInterceptorIndex(id);
|
|
139
|
+
if (this.fns[index]) {
|
|
140
|
+
this.fns[index] = fn;
|
|
141
|
+
return id;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
use(fn) {
|
|
146
|
+
this.fns.push(fn);
|
|
147
|
+
return this.fns.length - 1;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const createInterceptors = () => ({
|
|
151
|
+
error: new Interceptors(),
|
|
152
|
+
request: new Interceptors(),
|
|
153
|
+
response: new Interceptors()
|
|
154
|
+
});
|
|
155
|
+
const defaultQuerySerializer = createQuerySerializer({
|
|
156
|
+
allowReserved: false,
|
|
157
|
+
array: {
|
|
158
|
+
explode: true,
|
|
159
|
+
style: "form"
|
|
160
|
+
},
|
|
161
|
+
object: {
|
|
162
|
+
explode: true,
|
|
163
|
+
style: "deepObject"
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
const defaultHeaders = { "Content-Type": "application/json" };
|
|
167
|
+
const createConfig = (override = {}) => ({
|
|
168
|
+
...jsonBodySerializer,
|
|
169
|
+
headers: defaultHeaders,
|
|
170
|
+
parseAs: "auto",
|
|
171
|
+
querySerializer: defaultQuerySerializer,
|
|
172
|
+
...override
|
|
173
|
+
});
|
|
174
|
+
//#endregion
|
|
175
|
+
export { buildUrl, createConfig, createInterceptors, createQuerySerializer, getParseAs, mergeConfigs, mergeHeaders, setAuthParams };
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=utils.gen.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createConfig } from "./client/utils.gen.js";
|
|
2
|
+
import { createClient } from "./client/client.gen.js";
|
|
3
|
+
//#region src/client/client.gen.ts
|
|
4
|
+
const client = createClient(createConfig({ baseUrl: "https://api.samva.dev" }));
|
|
5
|
+
//#endregion
|
|
6
|
+
export { client };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=client.gen.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/client/core/auth.gen.ts
|
|
2
|
+
const getAuthToken = async (auth, callback) => {
|
|
3
|
+
const token = typeof callback === "function" ? await callback(auth) : callback;
|
|
4
|
+
if (!token) return;
|
|
5
|
+
if (auth.scheme === "bearer") return `Bearer ${token}`;
|
|
6
|
+
if (auth.scheme === "basic") return `Basic ${btoa(token)}`;
|
|
7
|
+
return token;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getAuthToken };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=auth.gen.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/client/core/bodySerializer.gen.ts
|
|
2
|
+
const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
|
|
3
|
+
//#endregion
|
|
4
|
+
export { jsonBodySerializer };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=bodySerializer.gen.js.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/client/core/params.gen.ts
|
|
2
|
+
const extraPrefixes = Object.entries({
|
|
3
|
+
$body_: "body",
|
|
4
|
+
$headers_: "headers",
|
|
5
|
+
$path_: "path",
|
|
6
|
+
$query_: "query"
|
|
7
|
+
});
|
|
8
|
+
function buildKeyMap(fields, map) {
|
|
9
|
+
if (!map) map = /* @__PURE__ */ new Map();
|
|
10
|
+
for (const config of fields) if ("in" in config) {
|
|
11
|
+
if (config.key) map.set(config.key, {
|
|
12
|
+
in: config.in,
|
|
13
|
+
map: config.map
|
|
14
|
+
});
|
|
15
|
+
} else if ("key" in config) map.set(config.key, { map: config.map });
|
|
16
|
+
else if (config.args) buildKeyMap(config.args, map);
|
|
17
|
+
return map;
|
|
18
|
+
}
|
|
19
|
+
function stripEmptySlots(params) {
|
|
20
|
+
for (const [slot, value] of Object.entries(params)) {
|
|
21
|
+
if (slot === "body") continue;
|
|
22
|
+
if (value && typeof value === "object" && !Array.isArray(value) && !Object.keys(value).length) delete params[slot];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function buildClientParams(args, fields) {
|
|
26
|
+
const params = {
|
|
27
|
+
headers: Object.create(null),
|
|
28
|
+
path: Object.create(null),
|
|
29
|
+
query: Object.create(null)
|
|
30
|
+
};
|
|
31
|
+
const map = buildKeyMap(fields);
|
|
32
|
+
function writeSlot(slot, key, value) {
|
|
33
|
+
let record = params[slot];
|
|
34
|
+
if (record === void 0) {
|
|
35
|
+
record = Object.create(null);
|
|
36
|
+
params[slot] = record;
|
|
37
|
+
}
|
|
38
|
+
record[key] = value;
|
|
39
|
+
}
|
|
40
|
+
let config;
|
|
41
|
+
for (const [index, arg] of args.entries()) {
|
|
42
|
+
if (fields[index]) config = fields[index];
|
|
43
|
+
if (!config) continue;
|
|
44
|
+
if ("in" in config) {
|
|
45
|
+
if (config.key) {
|
|
46
|
+
const field = map.get(config.key);
|
|
47
|
+
const name = field.map || config.key;
|
|
48
|
+
if (field.in) writeSlot(field.in, name, arg);
|
|
49
|
+
} else params.body = arg;
|
|
50
|
+
} else for (const [key, value] of Object.entries(arg ?? {})) {
|
|
51
|
+
const field = map.get(key);
|
|
52
|
+
if (field) {
|
|
53
|
+
if (field.in) {
|
|
54
|
+
const name = field.map || key;
|
|
55
|
+
writeSlot(field.in, name, value);
|
|
56
|
+
} else params[field.map] = value;
|
|
57
|
+
} else {
|
|
58
|
+
const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix));
|
|
59
|
+
if (extra) {
|
|
60
|
+
const [prefix, slot] = extra;
|
|
61
|
+
writeSlot(slot, key.slice(prefix.length), value);
|
|
62
|
+
} else if ("allowExtra" in config && config.allowExtra) {
|
|
63
|
+
for (const [slot, allowed] of Object.entries(config.allowExtra)) if (allowed) {
|
|
64
|
+
writeSlot(slot, key, value);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
stripEmptySlots(params);
|
|
72
|
+
return params;
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { buildClientParams };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=params.gen.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//#region src/client/core/pathSerializer.gen.ts
|
|
2
|
+
const separatorArrayExplode = (style) => {
|
|
3
|
+
switch (style) {
|
|
4
|
+
case "label": return ".";
|
|
5
|
+
case "matrix": return ";";
|
|
6
|
+
case "simple": return ",";
|
|
7
|
+
default: return "&";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
const separatorArrayNoExplode = (style) => {
|
|
11
|
+
switch (style) {
|
|
12
|
+
case "form": return ",";
|
|
13
|
+
case "pipeDelimited": return "|";
|
|
14
|
+
case "spaceDelimited": return "%20";
|
|
15
|
+
default: return ",";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const separatorObjectExplode = (style) => {
|
|
19
|
+
switch (style) {
|
|
20
|
+
case "label": return ".";
|
|
21
|
+
case "matrix": return ";";
|
|
22
|
+
case "simple": return ",";
|
|
23
|
+
default: return "&";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const serializeArrayParam = ({ allowReserved, explode, name, style, value }) => {
|
|
27
|
+
if (!explode) {
|
|
28
|
+
const joinedValues = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
29
|
+
switch (style) {
|
|
30
|
+
case "label": return `.${joinedValues}`;
|
|
31
|
+
case "matrix": return `;${name}=${joinedValues}`;
|
|
32
|
+
case "simple": return joinedValues;
|
|
33
|
+
default: return `${name}=${joinedValues}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const separator = separatorArrayExplode(style);
|
|
37
|
+
const joinedValues = value.map((v) => {
|
|
38
|
+
if (style === "label" || style === "simple") return allowReserved ? v : encodeURIComponent(v);
|
|
39
|
+
return serializePrimitiveParam({
|
|
40
|
+
allowReserved,
|
|
41
|
+
name,
|
|
42
|
+
value: v
|
|
43
|
+
});
|
|
44
|
+
}).join(separator);
|
|
45
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
46
|
+
};
|
|
47
|
+
const serializePrimitiveParam = ({ allowReserved, name, value }) => {
|
|
48
|
+
if (value === void 0 || value === null) return "";
|
|
49
|
+
if (typeof value === "object") throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");
|
|
50
|
+
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
51
|
+
};
|
|
52
|
+
const serializeObjectParam = ({ allowReserved, explode, name, style, value, valueOnly }) => {
|
|
53
|
+
if (value instanceof Date) return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
54
|
+
if (style !== "deepObject" && !explode) {
|
|
55
|
+
let values = [];
|
|
56
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
57
|
+
values = [
|
|
58
|
+
...values,
|
|
59
|
+
key,
|
|
60
|
+
allowReserved ? v : encodeURIComponent(v)
|
|
61
|
+
];
|
|
62
|
+
});
|
|
63
|
+
const joinedValues = values.join(",");
|
|
64
|
+
switch (style) {
|
|
65
|
+
case "form": return `${name}=${joinedValues}`;
|
|
66
|
+
case "label": return `.${joinedValues}`;
|
|
67
|
+
case "matrix": return `;${name}=${joinedValues}`;
|
|
68
|
+
default: return joinedValues;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const separator = separatorObjectExplode(style);
|
|
72
|
+
const joinedValues = Object.entries(value).map(([key, v]) => serializePrimitiveParam({
|
|
73
|
+
allowReserved,
|
|
74
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
75
|
+
value: v
|
|
76
|
+
})).join(separator);
|
|
77
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { separatorArrayExplode, separatorArrayNoExplode, separatorObjectExplode, serializeArrayParam, serializeObjectParam, serializePrimitiveParam };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=pathSerializer.gen.js.map
|