@settlemint/dalp-sdk 3.1.18 → 3.1.19-main.34482536277
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 +156 -169
- package/dist/auth/client.d.ts +113 -0
- package/dist/auth/live.d.ts +4366 -0
- package/dist/{auth-permissions.d.ts → auth/permissions.d.ts} +1 -2
- package/dist/{auth-wallet-plugins.d.ts → auth/wallet-plugins.d.ts} +69 -5
- package/dist/auth.d.ts +22 -115
- package/dist/auth.js +329 -0
- package/dist/bundler.d.ts +21 -205
- package/dist/bundler.js +97 -0
- package/dist/chunk-09prmw53.js +4 -0
- package/dist/chunk-d0295j58.js +33 -0
- package/dist/chunk-j4sxrfzz.js +54 -0
- package/dist/chunk-qvtjb3dz.js +102 -0
- package/dist/chunk-rb8k4w3q.js +67 -0
- package/dist/chunk-shp8v4ws.js +913 -0
- package/dist/chunk-sk9nc2q3.js +10 -0
- package/dist/chunk-xp3fx2yt.js +63 -0
- package/dist/chunk-ybqqdgrd.js +260 -0
- package/dist/client/conditional-request.d.ts +30 -0
- package/dist/client/factory.d.ts +14 -0
- package/dist/client/query-serializer.d.ts +2 -0
- package/dist/client/request-compression.d.ts +47 -0
- package/dist/client/ssr-fetch.d.ts +12 -0
- package/dist/effect.d.ts +78 -0
- package/dist/effect.js +87 -0
- package/dist/errors/api-error.d.ts +33 -0
- package/dist/errors/find-current-error.d.ts +8 -0
- package/dist/errors/sdk-error.d.ts +52 -0
- package/dist/errors/sdk-error.js +8 -0
- package/dist/generated/api-types.d.ts +56950 -0
- package/dist/generated/response-scalars.d.ts +9 -0
- package/dist/generated/routes.d.ts +12 -0
- package/dist/index.d.ts +28 -40
- package/dist/index.js +127 -96109
- package/dist/proxy/builder.d.ts +47 -0
- package/dist/proxy/client.d.ts +32 -0
- package/dist/proxy/fetch-executor.d.ts +30 -0
- package/dist/proxy/flat-args.d.ts +52 -0
- package/dist/proxy/sse.d.ts +75 -0
- package/dist/proxy/tanstack.d.ts +27 -0
- package/dist/proxy/transport.d.ts +74 -0
- package/dist/react-query.d.ts +16 -0
- package/dist/react-query.js +12 -0
- package/dist/readonly-deep.d.ts +12 -0
- package/dist/reads-as-funding-paused.d.ts +20 -0
- package/dist/reads-as-indexer-rebuild.d.ts +14 -0
- package/dist/routes/index.d.ts +20 -0
- package/dist/routes/index.js +10 -0
- package/dist/routes/types.d.ts +57 -0
- package/dist/runtime-exports.d.ts +20 -0
- package/dist/runtime-exports.js +16 -0
- package/dist/scalars/big-decimal.d.ts +16 -0
- package/dist/scalars/ethereum-address.d.ts +20 -0
- package/dist/scalars/exchange-rates.d.ts +27 -0
- package/dist/scalars/index.d.ts +18 -0
- package/dist/scalars/index.js +86 -0
- package/dist/scalars/organization-id.d.ts +20 -0
- package/dist/secret.d.ts +14 -0
- package/dist/sign-webhook-receipt.d.ts +76 -0
- package/dist/sign-webhook-receipt.js +26 -0
- package/dist/transport/cookie-store.d.ts +9 -0
- package/dist/transport/sse-lifecycle.d.ts +44 -0
- package/dist/types.d.ts +69 -102
- package/dist/url.d.ts +0 -1
- package/dist/verify-webhook.d.ts +17 -28
- package/dist/verify-webhook.js +8 -0
- package/dist/version.d.ts +0 -1
- package/dist/wait-for-transaction.d.ts +66 -79
- package/dist/wait-for-transaction.js +142 -0
- package/dist/webhook-events.d.ts +44 -27
- package/package.json +103 -30
- package/dist/auth-permissions.d.ts.map +0 -1
- package/dist/auth-wallet-plugins.d.ts.map +0 -1
- package/dist/auth.d.ts.map +0 -1
- package/dist/bundler.d.ts.map +0 -1
- package/dist/chunk-xm8h1dzh.js +0 -33
- package/dist/client.d.ts +0 -19
- package/dist/client.d.ts.map +0 -1
- package/dist/contract-errors.d.ts +0 -4156
- package/dist/contract-errors.d.ts.map +0 -1
- package/dist/contract.d.ts +0 -17
- package/dist/contract.d.ts.map +0 -1
- package/dist/cookie-store.d.ts +0 -10
- package/dist/cookie-store.d.ts.map +0 -1
- package/dist/dapi-errors.d.ts +0 -650
- package/dist/dapi-errors.d.ts.map +0 -1
- package/dist/errors.d.ts +0 -633
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/platform.d.ts +0 -41
- package/dist/platform.d.ts.map +0 -1
- package/dist/plugins/index.d.ts +0 -13
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/index.js +0 -10
- package/dist/sdk-error.d.ts +0 -74
- package/dist/sdk-error.d.ts.map +0 -1
- package/dist/serializers.d.ts +0 -41
- package/dist/serializers.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/url.d.ts.map +0 -1
- package/dist/verify-webhook.d.ts.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/wait-for-transaction.d.ts.map +0 -1
- package/dist/webhook-events.d.ts.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/reads-as-indexer-rebuild.ts
|
|
2
|
+
function readsAsIndexerRebuild2(status) {
|
|
3
|
+
if (status === null || typeof status !== "object") {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
const rebuild = Reflect.get(status, "indexerRebuild");
|
|
7
|
+
return rebuild !== undefined && rebuild !== null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { readsAsIndexerRebuild2 };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createDalpSdkConfigurationError2
|
|
3
|
+
} from "./chunk-j4sxrfzz.js";
|
|
4
|
+
|
|
5
|
+
// src/secret.ts
|
|
6
|
+
var SECRET_REDACTION_MARKER2 = "[REDACTED]";
|
|
7
|
+
var inspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
8
|
+
var secretValue = new WeakMap;
|
|
9
|
+
|
|
10
|
+
class Secret2 {
|
|
11
|
+
constructor(value) {
|
|
12
|
+
secretValue.set(this, value);
|
|
13
|
+
Object.freeze(this);
|
|
14
|
+
}
|
|
15
|
+
static from(value) {
|
|
16
|
+
if (value.trim().length === 0) {
|
|
17
|
+
throw new TypeError("DALP SDK: a secret value must not be empty.");
|
|
18
|
+
}
|
|
19
|
+
return new Secret2(value);
|
|
20
|
+
}
|
|
21
|
+
toString() {
|
|
22
|
+
return SECRET_REDACTION_MARKER2;
|
|
23
|
+
}
|
|
24
|
+
toJSON() {
|
|
25
|
+
return SECRET_REDACTION_MARKER2;
|
|
26
|
+
}
|
|
27
|
+
[inspectSymbol]() {
|
|
28
|
+
return SECRET_REDACTION_MARKER2;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
var secret2 = (value) => Secret2.from(value);
|
|
32
|
+
var unwrapSecret = (value) => {
|
|
33
|
+
const raw = secretValue.get(value);
|
|
34
|
+
if (raw === undefined) {
|
|
35
|
+
throw new TypeError("DALP SDK: cannot unwrap an invalid secret value.");
|
|
36
|
+
}
|
|
37
|
+
return raw;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/url.ts
|
|
41
|
+
function normalizeDalpBaseUrl(url) {
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = new URL(url);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw createDalpSdkConfigurationError2({
|
|
47
|
+
message: `DALP SDK: invalid url "${url}". Provide a full URL including the protocol (e.g., "https://dalp.example.com").`,
|
|
48
|
+
why: "The SDK could not parse the configured DALP API URL.",
|
|
49
|
+
fix: 'Provide a full http:// or https:// URL, for example "https://dalp.example.com".',
|
|
50
|
+
cause: error
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
54
|
+
throw createDalpSdkConfigurationError2({
|
|
55
|
+
message: `DALP SDK: url must use https:// or http:// protocol, got "${parsed.protocol}".`,
|
|
56
|
+
why: `The SDK received a URL with the unsupported "${parsed.protocol}" protocol.`,
|
|
57
|
+
fix: 'Use a DALP API base URL that starts with "https://" or "http://".'
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return `${parsed.origin}${parsed.pathname.replace(/\/+$/, "")}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { SECRET_REDACTION_MARKER2, Secret2, secret2, unwrapSecret, normalizeDalpBaseUrl };
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// src/transport/cookie-store.ts
|
|
2
|
+
var parseCookieHeader = (header) => {
|
|
3
|
+
const cookies = new Map;
|
|
4
|
+
for (const part of header.split(";")) {
|
|
5
|
+
const pair = part.trim();
|
|
6
|
+
const separator = pair.indexOf("=");
|
|
7
|
+
if (separator > 0) {
|
|
8
|
+
cookies.set(pair.slice(0, separator), pair);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return cookies;
|
|
12
|
+
};
|
|
13
|
+
var isCookieDeletion = (setCookie, now = Date.now()) => {
|
|
14
|
+
if (/\bmax-age\s*=\s*-?0+\b/iu.test(setCookie) || /\bmax-age\s*=\s*-\d+\b/iu.test(setCookie)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
const expires = /\bexpires\s*=\s*([^;]+)/iu.exec(setCookie)?.[1];
|
|
18
|
+
if (expires === undefined) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const parsed = Date.parse(expires.trim());
|
|
22
|
+
return !Number.isNaN(parsed) && parsed <= now;
|
|
23
|
+
};
|
|
24
|
+
function makeCookieStore2(initialHeader = "") {
|
|
25
|
+
const cookies = parseCookieHeader(initialHeader);
|
|
26
|
+
return {
|
|
27
|
+
header: () => [...cookies.values()].join("; "),
|
|
28
|
+
isEmpty: () => cookies.size === 0,
|
|
29
|
+
setCookieHeader: (header) => {
|
|
30
|
+
cookies.clear();
|
|
31
|
+
for (const [name, pair] of parseCookieHeader(header)) {
|
|
32
|
+
cookies.set(name, pair);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
storeSetCookieHeaders: (headers) => {
|
|
36
|
+
for (const setCookie of headers) {
|
|
37
|
+
const pair = setCookie.split(";", 1)[0]?.trim() ?? "";
|
|
38
|
+
const separator = pair.indexOf("=");
|
|
39
|
+
if (separator <= 0) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const name = pair.slice(0, separator);
|
|
43
|
+
if (isCookieDeletion(setCookie)) {
|
|
44
|
+
cookies.delete(name);
|
|
45
|
+
} else {
|
|
46
|
+
cookies.set(name, pair);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
var getSetCookieHeaders = (headers) => {
|
|
53
|
+
const { getSetCookie } = headers;
|
|
54
|
+
if (getSetCookie !== undefined) {
|
|
55
|
+
return getSetCookie.call(headers);
|
|
56
|
+
}
|
|
57
|
+
const value = headers.get("set-cookie");
|
|
58
|
+
return value === null ? [] : splitCombinedSetCookie(value);
|
|
59
|
+
};
|
|
60
|
+
var splitCombinedSetCookie = (value) => {
|
|
61
|
+
const cookies = [];
|
|
62
|
+
const lowered = value.toLowerCase();
|
|
63
|
+
let start = 0;
|
|
64
|
+
let inExpires = false;
|
|
65
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
66
|
+
if (lowered.startsWith("expires=", index)) {
|
|
67
|
+
inExpires = true;
|
|
68
|
+
}
|
|
69
|
+
const character = value[index];
|
|
70
|
+
if (character === ";") {
|
|
71
|
+
inExpires = false;
|
|
72
|
+
}
|
|
73
|
+
if (character !== "," || inExpires) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const next = value.slice(index + 1);
|
|
77
|
+
if (!/^\s*[\w!#$%&'*+\-.^`|~]+=/u.test(next)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
cookies.push(value.slice(start, index).trim());
|
|
81
|
+
start = index + 1;
|
|
82
|
+
}
|
|
83
|
+
const finalCookie = value.slice(start).trim();
|
|
84
|
+
if (finalCookie.length > 0) {
|
|
85
|
+
cookies.push(finalCookie);
|
|
86
|
+
}
|
|
87
|
+
return cookies;
|
|
88
|
+
};
|
|
89
|
+
function createCookieStoreFetch2(cookieStore, fetchImpl = globalThis.fetch) {
|
|
90
|
+
return async (input, init) => {
|
|
91
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
|
|
92
|
+
if (!cookieStore.isEmpty() && !headers.has("cookie")) {
|
|
93
|
+
headers.set("cookie", cookieStore.header());
|
|
94
|
+
}
|
|
95
|
+
const response = await fetchImpl(input, { ...init, headers });
|
|
96
|
+
if (response.status < 500) {
|
|
97
|
+
cookieStore.storeSetCookieHeaders(getSetCookieHeaders(response.headers));
|
|
98
|
+
}
|
|
99
|
+
return response;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// package.json
|
|
103
|
+
var package_default = {
|
|
104
|
+
name: "@settlemint/dalp-sdk",
|
|
105
|
+
version: "3.1.19-main.34482536277",
|
|
106
|
+
private: false,
|
|
107
|
+
description: "Fully typed SDK for the DALP tokenization platform API",
|
|
108
|
+
homepage: "https://settlemint.com",
|
|
109
|
+
bugs: {
|
|
110
|
+
email: "support@settlemint.com"
|
|
111
|
+
},
|
|
112
|
+
license: "SEE LICENSE IN LICENSE",
|
|
113
|
+
author: {
|
|
114
|
+
name: "SettleMint",
|
|
115
|
+
email: "support@settlemint.com",
|
|
116
|
+
url: "https://settlemint.com"
|
|
117
|
+
},
|
|
118
|
+
files: [
|
|
119
|
+
"dist",
|
|
120
|
+
"README.md",
|
|
121
|
+
"LICENSE"
|
|
122
|
+
],
|
|
123
|
+
type: "module",
|
|
124
|
+
sideEffects: [
|
|
125
|
+
"./src/**"
|
|
126
|
+
],
|
|
127
|
+
exports: {
|
|
128
|
+
"./package.json": "./package.json",
|
|
129
|
+
"./runtime-exports": {
|
|
130
|
+
types: "./dist/runtime-exports.d.ts",
|
|
131
|
+
import: "./dist/runtime-exports.js",
|
|
132
|
+
default: "./dist/runtime-exports.js"
|
|
133
|
+
},
|
|
134
|
+
".": {
|
|
135
|
+
types: "./dist/index.d.ts",
|
|
136
|
+
import: "./dist/index.js",
|
|
137
|
+
default: "./dist/index.js"
|
|
138
|
+
},
|
|
139
|
+
"./types": {
|
|
140
|
+
types: "./dist/types.d.ts",
|
|
141
|
+
import: "./dist/types.js",
|
|
142
|
+
default: "./dist/types.js"
|
|
143
|
+
},
|
|
144
|
+
"./scalars": {
|
|
145
|
+
types: "./dist/scalars/index.d.ts",
|
|
146
|
+
import: "./dist/scalars/index.js",
|
|
147
|
+
default: "./dist/scalars/index.js"
|
|
148
|
+
},
|
|
149
|
+
"./react-query": {
|
|
150
|
+
types: "./dist/react-query.d.ts",
|
|
151
|
+
import: "./dist/react-query.js",
|
|
152
|
+
default: "./dist/react-query.js"
|
|
153
|
+
},
|
|
154
|
+
"./auth": {
|
|
155
|
+
types: "./dist/auth.d.ts",
|
|
156
|
+
import: "./dist/auth.js",
|
|
157
|
+
default: "./dist/auth.js"
|
|
158
|
+
},
|
|
159
|
+
"./bundler": {
|
|
160
|
+
types: "./dist/bundler.d.ts",
|
|
161
|
+
import: "./dist/bundler.js",
|
|
162
|
+
default: "./dist/bundler.js"
|
|
163
|
+
},
|
|
164
|
+
"./verify-webhook": {
|
|
165
|
+
types: "./dist/verify-webhook.d.ts",
|
|
166
|
+
import: "./dist/verify-webhook.js",
|
|
167
|
+
default: "./dist/verify-webhook.js"
|
|
168
|
+
},
|
|
169
|
+
"./wait-for-transaction": {
|
|
170
|
+
types: "./dist/wait-for-transaction.d.ts",
|
|
171
|
+
import: "./dist/wait-for-transaction.js",
|
|
172
|
+
default: "./dist/wait-for-transaction.js"
|
|
173
|
+
},
|
|
174
|
+
"./sdk-error": {
|
|
175
|
+
types: "./dist/errors/sdk-error.d.ts",
|
|
176
|
+
import: "./dist/errors/sdk-error.js",
|
|
177
|
+
default: "./dist/errors/sdk-error.js"
|
|
178
|
+
},
|
|
179
|
+
"./sign-webhook-receipt": {
|
|
180
|
+
types: "./dist/sign-webhook-receipt.d.ts",
|
|
181
|
+
import: "./dist/sign-webhook-receipt.js",
|
|
182
|
+
default: "./dist/sign-webhook-receipt.js"
|
|
183
|
+
},
|
|
184
|
+
"./effect": {
|
|
185
|
+
types: "./dist/effect.d.ts",
|
|
186
|
+
import: "./dist/effect.js",
|
|
187
|
+
default: "./dist/effect.js"
|
|
188
|
+
},
|
|
189
|
+
"./routes": {
|
|
190
|
+
types: "./dist/routes/index.d.ts",
|
|
191
|
+
import: "./dist/routes/index.js",
|
|
192
|
+
default: "./dist/routes/index.js"
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
publishConfig: {
|
|
196
|
+
access: "public"
|
|
197
|
+
},
|
|
198
|
+
scripts: {
|
|
199
|
+
build: "bun scripts/build.ts && bun scripts/check-dts-portability.ts",
|
|
200
|
+
codegen: "bun scripts/codegen.ts",
|
|
201
|
+
publint: "publint run --strict --pack bun",
|
|
202
|
+
attw: 'archive=$(bun pm pack --destination "$PWD" --quiet | tail -n 1) && attw "$archive" --profile esm-only; code=$?; rm -f "$archive"; exit $code',
|
|
203
|
+
publish: 'cp ../../LICENSE . && bun run --cwd ../.. publish-if-absent "$PWD"',
|
|
204
|
+
prepack: "cp ../../LICENSE .",
|
|
205
|
+
test: "bun --bun vitest run --config node_modules/@tools/vitest-config/vitest.config.mjs --configLoader native --project unit --project browser --testTimeout 30000 tests/unit",
|
|
206
|
+
"test:coverage": "bun --bun vitest run --config node_modules/@tools/vitest-config/vitest.config.mjs --configLoader native --project unit --project browser --testTimeout 30000 tests/unit --coverage",
|
|
207
|
+
lint: "oxlint --deny-warnings .",
|
|
208
|
+
typecheck: "tsc -p . && tsc --noEmit -p scripts/tsconfig.json",
|
|
209
|
+
"check:dts-portability": "bun scripts/check-dts-portability.ts",
|
|
210
|
+
"check:auth-coverage": "bun scripts/check-auth-coverage.ts",
|
|
211
|
+
"codegen:webhook-events-sdk": "bun scripts/generate-webhook-events-sdk.ts"
|
|
212
|
+
},
|
|
213
|
+
dependencies: {
|
|
214
|
+
"@better-auth/api-key": "1.7.2",
|
|
215
|
+
"@better-auth/passkey": "1.7.2",
|
|
216
|
+
"better-auth": "1.7.2",
|
|
217
|
+
"better-call": "1.4.0",
|
|
218
|
+
dnum: "2.17.0",
|
|
219
|
+
standardwebhooks: "1.1.1",
|
|
220
|
+
viem: "2.56.3"
|
|
221
|
+
},
|
|
222
|
+
devDependencies: {
|
|
223
|
+
"@arethetypeswrong/cli": "0.18.5",
|
|
224
|
+
"@core/schema": "workspace:*",
|
|
225
|
+
"@tanstack/react-query": "5.102.8",
|
|
226
|
+
"@tools/typescript-config": "workspace:*",
|
|
227
|
+
"@tools/vitest-config": "workspace:*",
|
|
228
|
+
"@types/bun": "catalog:toolchain",
|
|
229
|
+
effect: "catalog:effect",
|
|
230
|
+
publint: "0.3.24",
|
|
231
|
+
typescript: "7.0.2",
|
|
232
|
+
vitest: "catalog:toolchain",
|
|
233
|
+
zod: "4.5.4"
|
|
234
|
+
},
|
|
235
|
+
peerDependencies: {
|
|
236
|
+
"@tanstack/react-query": "^5.101.4",
|
|
237
|
+
effect: "^4.0.0-rc.112",
|
|
238
|
+
zod: "^4.5.4"
|
|
239
|
+
},
|
|
240
|
+
peerDependenciesMeta: {
|
|
241
|
+
"@tanstack/react-query": {
|
|
242
|
+
optional: true
|
|
243
|
+
},
|
|
244
|
+
effect: {
|
|
245
|
+
optional: true
|
|
246
|
+
},
|
|
247
|
+
zod: {
|
|
248
|
+
optional: true
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
engines: {
|
|
252
|
+
node: ">=20"
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// src/version.ts
|
|
257
|
+
var SDK_VERSION2 = package_default.version;
|
|
258
|
+
var SDK_USER_AGENT2 = `DALP SDK v${SDK_VERSION2}`;
|
|
259
|
+
|
|
260
|
+
export { makeCookieStore2, createCookieStoreFetch2, SDK_VERSION2, SDK_USER_AGENT2 };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conditional GET, as a fetch decorator.
|
|
3
|
+
*
|
|
4
|
+
* The policy is unchanged from the interceptor pair this replaces: hold the
|
|
5
|
+
* ETag and body of a successful GET, send `If-None-Match` on the next one, and
|
|
6
|
+
* serve the held body on a 304. Only the attachment point moved, from a
|
|
7
|
+
* generated client's interceptor list to the fetch the transport already wraps
|
|
8
|
+
* for compression and SSR.
|
|
9
|
+
*/
|
|
10
|
+
import type { DalpFetch } from "./ssr-fetch.ts";
|
|
11
|
+
/** Handle a caller holds so it can clear the store on sign-out or org switch. */
|
|
12
|
+
export interface ConditionalRequestStore {
|
|
13
|
+
readonly clear: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wrap `fetch` with the If-None-Match / 304 rewrite pair for conditional GET.
|
|
17
|
+
*
|
|
18
|
+
* Server ETags must be strong content digests computed after authorization
|
|
19
|
+
* inside the requester's partition. The dapi response cache guarantees this:
|
|
20
|
+
* `encodeResponseCacheEntry` sets `etag` to the SHA-256 of the serialized
|
|
21
|
+
* body after the request-context middleware has authenticated the session.
|
|
22
|
+
* Version-stamp ETags (generation counters, watermarks, table versions) are
|
|
23
|
+
* forbidden for conditional-request adopters: a stamp can collide across
|
|
24
|
+
* tenants or lag a body change and would let this store serve another
|
|
25
|
+
* partition's bytes as a 200.
|
|
26
|
+
*/
|
|
27
|
+
export declare function withConditionalRequests(base: DalpFetch): {
|
|
28
|
+
fetch: DalpFetch;
|
|
29
|
+
store: ConditionalRequestStore;
|
|
30
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client factory.
|
|
3
|
+
*
|
|
4
|
+
* The transport policy this used to assemble around the generated client now
|
|
5
|
+
* lives in `../proxy/transport.ts`, which both interpreters share. This module
|
|
6
|
+
* stays as the published entry point's seam so a consumer's import path did not
|
|
7
|
+
* move with the internals.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export { createDalpClient, type DalpClient } from "../proxy/client.ts";
|
|
12
|
+
export { createDalpContextHeaders } from "../proxy/transport.ts";
|
|
13
|
+
export type { CreateDalpClientOptions, DalpClientContext, DalpSsrOptions, Transport } from "../proxy/transport.ts";
|
|
14
|
+
export type { DalpFetch } from "./ssr-fetch.ts";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { DalpFetch } from "./ssr-fetch.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Request-body compression for DALP server/CLI clients.
|
|
4
|
+
*
|
|
5
|
+
* Bun 1.4 added a `compress` fetch option: it compresses a buffered body
|
|
6
|
+
* before sending and sets `Content-Encoding` on the wire. This wrapper opts
|
|
7
|
+
* eligible outgoing bodies into gzip so big JSON payloads shrink in transit;
|
|
8
|
+
* the receiving DAPI host decodes them at its boundary
|
|
9
|
+
* (`@dapi/server/request-body-decoding`), so callers need no per-route work.
|
|
10
|
+
*
|
|
11
|
+
* Eligibility mirrors what the transport can actually do:
|
|
12
|
+
*
|
|
13
|
+
* - Only body-bearing methods (`GET`/`HEAD` never).
|
|
14
|
+
* - Bodies already carrying `Content-Encoding`, or an explicit caller
|
|
15
|
+
* `compress`, pass through untouched.
|
|
16
|
+
* - With `(url, init)` the body must be one of Bun's buffered types
|
|
17
|
+
* (string, ArrayBuffer, TypedArray/DataView, Blob) and fall inside the
|
|
18
|
+
* size window — gzip framing dominates tiny payloads, and huge explicitly
|
|
19
|
+
* sized bodies stay uncompressed (the DAPI decode cap mirrors this bound).
|
|
20
|
+
* - Streams, `FormData`, and `URLSearchParams` pass through: the transport
|
|
21
|
+
* forwards streaming bodies unchanged.
|
|
22
|
+
* - A `Request` instance is measured through a bounded clone before compression.
|
|
23
|
+
*/
|
|
24
|
+
/** Bodies smaller than this stay uncompressed; gzip framing dominates tiny JSON. */
|
|
25
|
+
export declare const DALP_SDK_REQUEST_COMPRESSION_MIN_BODY_BYTES = 1024;
|
|
26
|
+
/** Explicitly-sized bodies larger than this are sent uncompressed. */
|
|
27
|
+
export declare const DALP_SDK_REQUEST_COMPRESSION_MAX_BODY_BYTES = 16777216;
|
|
28
|
+
/**
|
|
29
|
+
* Bun's `compress` fetch option. bun-types still types `RequestInit`
|
|
30
|
+
* from lib.dom without it, so the field is declared here and set through one
|
|
31
|
+
* narrow cast at the transport seam.
|
|
32
|
+
*/
|
|
33
|
+
export type FetchRequestCompression = true | "gzip" | "deflate" | "br" | "zstd";
|
|
34
|
+
export interface CompressionRequestInit extends RequestInit {
|
|
35
|
+
readonly compress?: FetchRequestCompression;
|
|
36
|
+
}
|
|
37
|
+
export interface RequestBodyCompressionOptions {
|
|
38
|
+
/** Test seam overriding DALP_SDK_REQUEST_COMPRESSION_MIN_BODY_BYTES. */
|
|
39
|
+
readonly minBodyBytes?: number;
|
|
40
|
+
/** Test seam overriding DALP_SDK_REQUEST_COMPRESSION_MAX_BODY_BYTES. */
|
|
41
|
+
readonly maxBodyBytes?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Wrap a fetch seam so eligible request bodies travel gzip-compressed.
|
|
45
|
+
* Ineligible calls forward the original arguments untouched.
|
|
46
|
+
*/
|
|
47
|
+
export declare function withRequestBodyCompression(fetchImpl: DalpFetch, options?: RequestBodyCompressionOptions): DalpFetch;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Minimal fetch shape — Bun's `typeof fetch` also requires `preconnect`. */
|
|
2
|
+
export type DalpFetch = ((input: RequestInfo | URL, init?: RequestInit) => Promise<Response>) & {
|
|
3
|
+
readonly preconnect?: typeof fetch.preconnect;
|
|
4
|
+
};
|
|
5
|
+
export interface CreateSsrFetchOptions {
|
|
6
|
+
readonly allowedOrigins?: ReadonlyArray<string | URL>;
|
|
7
|
+
readonly baseUrl: string | URL;
|
|
8
|
+
readonly fetch: DalpFetch;
|
|
9
|
+
readonly requestHeaders: HeadersInit;
|
|
10
|
+
}
|
|
11
|
+
/** Direct destinations must be approved; unapproved redirects lose all caller credentials and context. */
|
|
12
|
+
export declare function createSsrFetch(options: CreateSsrFetchOptions): DalpFetch;
|
package/dist/effect.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Effect call surface.
|
|
3
|
+
*
|
|
4
|
+
* The same namespaced tree as the root entry, returning `Effect` values instead
|
|
5
|
+
* of promises. It exists because the CLI and other code under our control want
|
|
6
|
+
* Effect, and hiding it behind promises there would mean unwrapping and
|
|
7
|
+
* rewrapping at every boundary.
|
|
8
|
+
*
|
|
9
|
+
* This is the only SDK export that exposes Effect values. The root export
|
|
10
|
+
* remains Promise-based.
|
|
11
|
+
*
|
|
12
|
+
* Errors are tagged from the wire envelope rather than decoded from per-route
|
|
13
|
+
* schemas. The envelope is identical across every route (`code`, `status`,
|
|
14
|
+
* `message`, and a `data` carrying the stable DALP id), so one reader covers
|
|
15
|
+
* 759 routes, and no runtime schema ships.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import * as Effect from "effect/Effect";
|
|
20
|
+
import type { DalpApi, DalpRouteId, DalpRouteTypes } from "./generated/api-types.d.ts";
|
|
21
|
+
import { type CallOptions } from "./proxy/builder.ts";
|
|
22
|
+
import { type CreateDalpClientOptions } from "./proxy/transport.ts";
|
|
23
|
+
import { DalpApiError } from "./errors/api-error.ts";
|
|
24
|
+
/** The failure channel every route call carries. */
|
|
25
|
+
export declare class DalpRequestError extends Error {
|
|
26
|
+
readonly _tag = "DalpRequestError";
|
|
27
|
+
/** Stable DALP error id when the platform supplied one, else the SDK code. */
|
|
28
|
+
readonly id: string;
|
|
29
|
+
/** The DALP error code, mirroring `DalpApiError.code`. */
|
|
30
|
+
readonly code: string;
|
|
31
|
+
readonly status: number | undefined;
|
|
32
|
+
readonly retryable: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The server's requested delay before a retry, when it sent `Retry-After`.
|
|
35
|
+
*
|
|
36
|
+
* A retryable failure without this is a caller guessing at a backoff the
|
|
37
|
+
* server already named, so it travels with `retryable` rather than staying
|
|
38
|
+
* behind on the promise client's `DalpApiError`.
|
|
39
|
+
*/
|
|
40
|
+
readonly retryAfterSeconds: number | undefined;
|
|
41
|
+
readonly routeId: string;
|
|
42
|
+
/** The wire envelope's route-specific `data`, e.g. `requiredRoles` on a role-gated 403. */
|
|
43
|
+
readonly data: DalpApiError["data"];
|
|
44
|
+
constructor(routeId: string, cause: unknown);
|
|
45
|
+
}
|
|
46
|
+
/** The Effect-shaped mirror of `DalpApi`. */
|
|
47
|
+
export type DalpEffectApi = DalpEffectApiNode<DalpApi>;
|
|
48
|
+
/**
|
|
49
|
+
* A stream leaf answers with its frame sequence rather than one body, so it is
|
|
50
|
+
* matched before the promise leaf: its call signature returns an `AsyncIterable`
|
|
51
|
+
* and would otherwise fall through to the recursive branch, which maps a call
|
|
52
|
+
* signature to an object with no keys and leaves the route uncallable.
|
|
53
|
+
*/
|
|
54
|
+
type DalpEffectApiNode<T> = {
|
|
55
|
+
readonly [K in keyof T]: T[K] extends (...args: infer Args) => AsyncIterable<infer Frame> ? (...args: Args) => Effect.Effect<AsyncIterable<Frame>, DalpRequestError> : T[K] extends (...args: infer Args) => Promise<infer A> ? (...args: Args) => Effect.Effect<A, DalpRequestError> : DalpEffectApiNode<T[K]>;
|
|
56
|
+
};
|
|
57
|
+
/** The routes that answer with `text/event-stream`, named by the route table. */
|
|
58
|
+
export type DalpStreamingRouteId = {
|
|
59
|
+
[Id in DalpRouteId]: DalpRouteTypes[Id]["streaming"] extends true ? Id : never;
|
|
60
|
+
}[DalpRouteId];
|
|
61
|
+
export interface DalpEffectClient {
|
|
62
|
+
readonly api: DalpEffectApi;
|
|
63
|
+
/**
|
|
64
|
+
* Two signatures rather than one conditional return type. A caller generic over
|
|
65
|
+
* the streaming routes has to resolve the frame sequence from its own
|
|
66
|
+
* constraint, and a conditional keyed on `Id` stays unresolved until `Id` is a
|
|
67
|
+
* single route, which is what pushed every such caller into an assertion.
|
|
68
|
+
*/
|
|
69
|
+
readonly execute: {
|
|
70
|
+
<Id extends DalpStreamingRouteId>(routeId: Id, input?: DalpRouteTypes[Id]["request"], options?: CallOptions): Effect.Effect<AsyncIterable<DalpRouteTypes[Id]["response"]>, DalpRequestError>;
|
|
71
|
+
<Id extends DalpRouteId>(routeId: Id, input?: DalpRouteTypes[Id]["request"], options?: CallOptions): Effect.Effect<DalpRouteTypes[Id]["response"], DalpRequestError>;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Create the Effect client. Same routes, same transport, different channel. */
|
|
75
|
+
export declare function createDalpEffectClient(options: CreateDalpClientOptions): DalpEffectClient;
|
|
76
|
+
export type { CallOptions } from "./proxy/builder.ts";
|
|
77
|
+
export type { CreateDalpClientOptions } from "./proxy/transport.ts";
|
|
78
|
+
export type { DalpRouteId, DalpRouteTypes } from "./generated/api-types.d.ts";
|
package/dist/effect.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
data
|
|
3
|
+
} from "./chunk-09prmw53.js";
|
|
4
|
+
import"./chunk-j4sxrfzz.js";
|
|
5
|
+
import {
|
|
6
|
+
DalpApiError2,
|
|
7
|
+
createTransport,
|
|
8
|
+
streamRequest,
|
|
9
|
+
sendRequest,
|
|
10
|
+
queryKeyFor2
|
|
11
|
+
} from "./chunk-shp8v4ws.js";
|
|
12
|
+
import"./chunk-xp3fx2yt.js";
|
|
13
|
+
import {
|
|
14
|
+
buildProxy,
|
|
15
|
+
findRoute
|
|
16
|
+
} from "./chunk-rb8k4w3q.js";
|
|
17
|
+
|
|
18
|
+
// src/effect.ts
|
|
19
|
+
import * as Effect from "effect/Effect";
|
|
20
|
+
class DalpRequestError extends Error {
|
|
21
|
+
_tag = "DalpRequestError";
|
|
22
|
+
id;
|
|
23
|
+
code;
|
|
24
|
+
status;
|
|
25
|
+
retryable;
|
|
26
|
+
retryAfterSeconds;
|
|
27
|
+
routeId;
|
|
28
|
+
data;
|
|
29
|
+
constructor(routeId, cause) {
|
|
30
|
+
const api = cause instanceof DalpApiError2 ? cause : undefined;
|
|
31
|
+
super(api?.message ?? `DALP request failed for ${routeId}`, { cause });
|
|
32
|
+
this.name = "DalpRequestError";
|
|
33
|
+
this._tag = "DalpRequestError";
|
|
34
|
+
this.routeId = routeId;
|
|
35
|
+
this.code = api?.code ?? "sdk.transport.REQUEST_FAILED";
|
|
36
|
+
this.id = api?.id ?? this.code;
|
|
37
|
+
this.status = api?.status;
|
|
38
|
+
this.retryable = api?.retryable ?? true;
|
|
39
|
+
this.retryAfterSeconds = api?.retryAfterSeconds;
|
|
40
|
+
this.data = api?.data;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function runRoute(transport, route, id, input, options) {
|
|
44
|
+
return Effect.callback((resume) => {
|
|
45
|
+
const controller = new AbortController;
|
|
46
|
+
const signal = options?.signal ?? controller.signal;
|
|
47
|
+
const run = async () => {
|
|
48
|
+
try {
|
|
49
|
+
resume(Effect.succeed(route.serializer === "sse" ? streamRequest(transport, route, input, { ...options, signal }) : await sendRequest(transport, route, input, { ...options, signal })));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
resume(Effect.fail(new DalpRequestError(id, error)));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
run();
|
|
55
|
+
return Effect.sync(() => {
|
|
56
|
+
controller.abort();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function createDalpEffectClient(options) {
|
|
61
|
+
const transport = createTransport(options);
|
|
62
|
+
const executor = (route, id, input, callOptions) => runRoute(transport, route, id, input, callOptions);
|
|
63
|
+
const factories = {
|
|
64
|
+
queryOptions: (route, id, input, callOptions) => ({
|
|
65
|
+
queryKey: queryKeyFor2(id, input),
|
|
66
|
+
queryFn: () => runRoute(transport, route, id, input, callOptions)
|
|
67
|
+
}),
|
|
68
|
+
mutationOptions: (route, id, callOptions) => ({
|
|
69
|
+
mutationKey: ["dalp", id],
|
|
70
|
+
mutationFn: (input) => runRoute(transport, route, id, input, callOptions)
|
|
71
|
+
})
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
api: buildProxy(data, executor, factories),
|
|
75
|
+
execute: (routeId, input, callOptions) => {
|
|
76
|
+
const route = findRoute(data, routeId);
|
|
77
|
+
if (route === undefined) {
|
|
78
|
+
return Effect.fail(new DalpRequestError(routeId, new TypeError(`Unknown DALP route \`${routeId}\``)));
|
|
79
|
+
}
|
|
80
|
+
return runRoute(transport, route, routeId, input, callOptions);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
DalpRequestError,
|
|
86
|
+
createDalpEffectClient
|
|
87
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { findCurrentError } from "./find-current-error.ts";
|
|
2
|
+
import type { DalpSdkErrorDetails } from "./sdk-error.ts";
|
|
3
|
+
export type DalpApiErrorCategory = "client" | "auth" | "permission" | "domain" | "contract" | "dependency" | "operational" | "config" | "unknown";
|
|
4
|
+
export interface DalpApiErrorOptions {
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly cause?: unknown;
|
|
7
|
+
readonly id?: string;
|
|
8
|
+
readonly code: string;
|
|
9
|
+
readonly category: DalpApiErrorCategory;
|
|
10
|
+
readonly status?: number;
|
|
11
|
+
readonly retryable: boolean;
|
|
12
|
+
readonly why: string;
|
|
13
|
+
readonly fix: string;
|
|
14
|
+
readonly retryAfterSeconds?: number;
|
|
15
|
+
readonly data?: DalpSdkErrorDetails;
|
|
16
|
+
}
|
|
17
|
+
export declare class DalpApiError extends Error {
|
|
18
|
+
readonly id?: string;
|
|
19
|
+
readonly code: string;
|
|
20
|
+
readonly category: DalpApiErrorCategory;
|
|
21
|
+
readonly status?: number;
|
|
22
|
+
readonly retryable: boolean;
|
|
23
|
+
readonly why: string;
|
|
24
|
+
readonly fix: string;
|
|
25
|
+
readonly retryAfterSeconds?: number;
|
|
26
|
+
/** The wire envelope's route-specific `data`, e.g. `requiredRoles` on a role-gated 403. */
|
|
27
|
+
readonly data?: DalpSdkErrorDetails;
|
|
28
|
+
constructor(options: DalpApiErrorOptions);
|
|
29
|
+
static make(options: DalpApiErrorOptions): DalpApiError;
|
|
30
|
+
}
|
|
31
|
+
export declare const isDalpApiError: (error: unknown) => error is DalpApiError;
|
|
32
|
+
export declare const findDalpSdkError: typeof findCurrentError;
|
|
33
|
+
export declare const makeDalpApiError: (error: unknown) => DalpApiError;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DalpSdkError } from "./sdk-error.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Walk a nested SDK error graph and return the first DalpSdkError.
|
|
4
|
+
*
|
|
5
|
+
* Follows `cause` and `reasons[].error` / `reasons[].defect`. Stops after
|
|
6
|
+
* `maxNodes` so a cyclic wrapper cannot loop forever.
|
|
7
|
+
*/
|
|
8
|
+
export declare const findCurrentError: (error: unknown, maxNodes?: number) => DalpSdkError | undefined;
|