@fragno-dev/api-fragment 0.0.0-stage → 0.0.1
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/LICENSE.md +16 -0
- package/README.md +249 -2
- package/dist/browser/client/client-3ZV9sw3i.js +2580 -0
- package/dist/browser/client/client-3ZV9sw3i.js.map +1 -0
- package/dist/browser/client/client-DPjmoaJQ.d.ts +711 -0
- package/dist/browser/client/client-DPjmoaJQ.d.ts.map +1 -0
- package/dist/browser/client/client.d.ts +1645 -0
- package/dist/browser/client/client.d.ts.map +1 -0
- package/dist/browser/client/client.js +2 -0
- package/dist/browser/client/react.d.ts +1665 -0
- package/dist/browser/client/react.d.ts.map +1 -0
- package/dist/browser/client/react.js +194 -0
- package/dist/browser/client/react.js.map +1 -0
- package/dist/browser/client/solid.d.ts +1668 -0
- package/dist/browser/client/solid.d.ts.map +1 -0
- package/dist/browser/client/solid.js +129 -0
- package/dist/browser/client/solid.js.map +1 -0
- package/dist/browser/client/svelte.d.ts +1668 -0
- package/dist/browser/client/svelte.d.ts.map +1 -0
- package/dist/browser/client/svelte.js +131 -0
- package/dist/browser/client/svelte.js.map +1 -0
- package/dist/browser/client/vanilla.d.ts +1695 -0
- package/dist/browser/client/vanilla.d.ts.map +1 -0
- package/dist/browser/client/vanilla.js +159 -0
- package/dist/browser/client/vanilla.js.map +1 -0
- package/dist/browser/client/vue.d.ts +1668 -0
- package/dist/browser/client/vue.d.ts.map +1 -0
- package/dist/browser/client/vue.js +127 -0
- package/dist/browser/client/vue.js.map +1 -0
- package/dist/browser/client-D4NnY-zV.d.ts +713 -0
- package/dist/browser/client-D4NnY-zV.d.ts.map +1 -0
- package/dist/browser/client-DQE0c7GI.d.ts +711 -0
- package/dist/browser/client-DQE0c7GI.d.ts.map +1 -0
- package/dist/browser/index.d.ts +3130 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +2 -0
- package/dist/browser/src-BrYPVbAN.js +2404 -0
- package/dist/browser/src-BrYPVbAN.js.map +1 -0
- package/dist/browser/src-t-4wp9-f.js +2400 -0
- package/dist/browser/src-t-4wp9-f.js.map +1 -0
- package/dist/node/api-types.d.ts +731 -0
- package/dist/node/api-types.d.ts.map +1 -0
- package/dist/node/api-types.js +281 -0
- package/dist/node/api-types.js.map +1 -0
- package/dist/node/crypto.d.ts +6 -0
- package/dist/node/crypto.d.ts.map +1 -0
- package/dist/node/crypto.js +103 -0
- package/dist/node/crypto.js.map +1 -0
- package/dist/node/definition.d.ts +638 -0
- package/dist/node/definition.d.ts.map +1 -0
- package/dist/node/definition.js +315 -0
- package/dist/node/definition.js.map +1 -0
- package/dist/node/oauth.js +124 -0
- package/dist/node/oauth.js.map +1 -0
- package/dist/node/routes.d.ts +1585 -0
- package/dist/node/routes.d.ts.map +1 -0
- package/dist/node/routes.js +1100 -0
- package/dist/node/routes.js.map +1 -0
- package/dist/node/schema.d.ts +99 -0
- package/dist/node/schema.d.ts.map +1 -0
- package/dist/node/schema.js +16 -0
- package/dist/node/schema.js.map +1 -0
- package/dist/node/server.d.ts +1585 -0
- package/dist/node/server.d.ts.map +1 -0
- package/dist/node/server.js +12 -0
- package/dist/node/server.js.map +1 -0
- package/dist/node/services.d.ts +10 -0
- package/dist/node/services.d.ts.map +1 -0
- package/dist/node/services.js +304 -0
- package/dist/node/services.js.map +1 -0
- package/dist/node/webhooks/auth.d.ts +133 -0
- package/dist/node/webhooks/auth.d.ts.map +1 -0
- package/dist/node/webhooks/auth.js +268 -0
- package/dist/node/webhooks/auth.js.map +1 -0
- package/dist/node/webhooks/verification.d.ts +102 -0
- package/dist/node/webhooks/verification.d.ts.map +1 -0
- package/dist/node/webhooks/verification.js +119 -0
- package/dist/node/webhooks/verification.js.map +1 -0
- package/package.json +136 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-types.d.ts","names":[],"sources":["../../src/api-types.ts"],"mappings":";;UAKiB;;EAEf,mBAAmB,KAAK;;EAExB,4BAA4B,KAAK;;EAEjC,eAAe;;cAKJ,kBAAgB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiChB,yBAAuB,EAAA;cAOvB,gCAA8B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAM9B,2BAAyB,EAAA;;;;;;;;;cAUzB,0BAAwB,EAAA;;;;;;;;;;;;;cAUxB,qBAAmB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgBnB,uBAAqB,EAAA;;;;;;cASrB,sBAAoB,EAAA;;;;cAGpB;cAEA,wBAAsB,EAAA;cAKtB,uBAAqB,EAAA;;;;;cAWrB,sBAAoB,EAAA,uBAAA,EAAA;;;;;;;;;cAMpB,uBAAqB,EAAA;;;;;;;;;;;;;;;;;;;;;;cASrB,uBAAqB,EAAA,uBAAA,EAAA;;;;;;;;;;cAMrB,uBAAqB,EAAA;;;;;;;;;;;;;;;cAOrB,wBAAsB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAyBtB,+BAA6B,EAAA,uBAAA,EAAA;;;;;;;;;;cAS7B,gCAA8B,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqC9B,6BAA2B,EAAA;;;;;;cAG3B,4BAA0B,EAAA;;;;;;;;;;cAW1B,+BAA6B,EAAA;;;;;;;;;;;;;;;;cAe7B,6BAA2B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAa3B,kCAAgC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAQhC,kCAAgC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAQjC,aAAa,EAAE,aAAa;KAC5B,qBAAqB,EAAE,aAAa;KACpC,gBAAgB,EAAE,aAAa;KAC/B,qBAAqB,EAAE,aAAa;KACpC,gBAAgB,EAAE,aAAa;KAC/B,kBAAkB,EAAE,aAAa;KACjC,iBAAiB,EAAE,aAAa;KAChC,kBAAkB,EAAE,aAAa;KACjC,kBAAkB,EAAE,aAAa;KACjC,kBAAkB,EAAE,aAAa;KACjC,mBAAmB,EAAE,aAAa;KAClC,0BAA0B,EAAE,aAAa;KACzC,2BAA2B,EAAE,aAAa;KAC1C,uBAAuB,EAAE,aAAa;KACtC,6BAA6B,EAAE,aAAa;KAC5C,kBAAkB,EAAE,aAAa;KACjC,uBAAuB,EAAE,aAAa;KACtC,0BAA0B,EAAE,aAAa"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { webhookAuthConfigSchema } from "./webhooks/auth.js";
|
|
2
|
+
import { webhookVerificationConfigSchema } from "./webhooks/verification.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/api-types.ts
|
|
5
|
+
const tokenEndpointAuthMethodSchema = z.enum([
|
|
6
|
+
"client_secret_basic",
|
|
7
|
+
"client_secret_post",
|
|
8
|
+
"none"
|
|
9
|
+
]);
|
|
10
|
+
const authConfigSchema = z.discriminatedUnion("type", [
|
|
11
|
+
z.object({ type: z.literal("none") }),
|
|
12
|
+
z.object({
|
|
13
|
+
type: z.literal("bearer"),
|
|
14
|
+
token: z.string().min(1)
|
|
15
|
+
}),
|
|
16
|
+
z.object({
|
|
17
|
+
type: z.literal("basic"),
|
|
18
|
+
username: z.string().min(1),
|
|
19
|
+
password: z.string().min(1)
|
|
20
|
+
}),
|
|
21
|
+
z.object({
|
|
22
|
+
type: z.literal("client_credentials"),
|
|
23
|
+
tokenEndpoint: z.url(),
|
|
24
|
+
clientId: z.string().min(1),
|
|
25
|
+
clientSecret: z.string().min(1),
|
|
26
|
+
scopes: z.array(z.string()).optional(),
|
|
27
|
+
audience: z.string().min(1).optional(),
|
|
28
|
+
tokenEndpointAuthMethod: z.enum(["client_secret_basic", "client_secret_post"]).default("client_secret_basic")
|
|
29
|
+
}),
|
|
30
|
+
z.object({
|
|
31
|
+
type: z.literal("oauth"),
|
|
32
|
+
authorizationEndpoint: z.url(),
|
|
33
|
+
tokenEndpoint: z.url(),
|
|
34
|
+
clientId: z.string().min(1),
|
|
35
|
+
clientSecret: z.string().min(1).optional(),
|
|
36
|
+
scopes: z.array(z.string()).optional(),
|
|
37
|
+
tokenEndpointAuthMethod: tokenEndpointAuthMethodSchema.default("client_secret_basic"),
|
|
38
|
+
extraAuthorizationParams: z.record(z.string(), z.string()).optional(),
|
|
39
|
+
extraTokenParams: z.record(z.string(), z.string()).optional()
|
|
40
|
+
})
|
|
41
|
+
]);
|
|
42
|
+
/** Slugs are URL path segments; whitespace and dot segments would make a connection unaddressable. */
|
|
43
|
+
const apiConnectionSlugSchema = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "API connection slugs start with a letter or digit and contain only letters, digits, '.', '_', or '-'.");
|
|
44
|
+
const createApiConnectionInputSchema = z.object({
|
|
45
|
+
name: z.string().min(1).optional(),
|
|
46
|
+
baseUrl: z.url(),
|
|
47
|
+
auth: authConfigSchema.default({ type: "none" })
|
|
48
|
+
});
|
|
49
|
+
const apiConnectionOutputSchema = z.object({
|
|
50
|
+
slug: z.string(),
|
|
51
|
+
name: z.string().nullable().optional(),
|
|
52
|
+
baseUrl: z.string(),
|
|
53
|
+
authMode: z.string(),
|
|
54
|
+
status: z.string(),
|
|
55
|
+
createdAt: z.union([z.string(), z.date()]).optional(),
|
|
56
|
+
updatedAt: z.union([z.string(), z.date()]).optional()
|
|
57
|
+
});
|
|
58
|
+
const apiConnectionsPageSchema = z.object({
|
|
59
|
+
connections: z.array(apiConnectionOutputSchema),
|
|
60
|
+
cursor: z.string().nullable().describe("Null means every connection has been listed.")
|
|
61
|
+
});
|
|
62
|
+
const apiCredentialsPresenceSchema = z.enum(["present", "missing"]).describe("Whether credentials are stored, not whether the provider accepts them.");
|
|
63
|
+
/** Sanitized auth state derived from stored configuration; it never proves live provider access. */
|
|
64
|
+
const apiAuthStatusSchema = z.discriminatedUnion("mode", [
|
|
65
|
+
z.object({ mode: z.literal("none") }),
|
|
66
|
+
z.object({
|
|
67
|
+
mode: z.literal("bearer"),
|
|
68
|
+
credentials: apiCredentialsPresenceSchema
|
|
69
|
+
}),
|
|
70
|
+
z.object({
|
|
71
|
+
mode: z.literal("basic"),
|
|
72
|
+
credentials: apiCredentialsPresenceSchema
|
|
73
|
+
}),
|
|
74
|
+
z.object({
|
|
75
|
+
mode: z.literal("client_credentials"),
|
|
76
|
+
credentials: apiCredentialsPresenceSchema
|
|
77
|
+
}),
|
|
78
|
+
z.object({
|
|
79
|
+
mode: z.literal("oauth"),
|
|
80
|
+
state: z.enum([
|
|
81
|
+
"client-missing",
|
|
82
|
+
"consent-required",
|
|
83
|
+
"consent-pending",
|
|
84
|
+
"authorized",
|
|
85
|
+
"expired"
|
|
86
|
+
]).describe("Expired means the access token expired and no refresh token is stored; pending means an unexpired authorization link exists.")
|
|
87
|
+
})
|
|
88
|
+
]);
|
|
89
|
+
/** The pending link embeds the callback state, so reading it requires connection-create authority. */
|
|
90
|
+
const apiOAuthPendingSchema = z.object({ pending: z.object({
|
|
91
|
+
authorizationUrl: z.url(),
|
|
92
|
+
expiresAt: z.union([z.string(), z.date()])
|
|
93
|
+
}).nullable().describe("The newest unexpired, unconsumed authorization link; any pending link completes it.") });
|
|
94
|
+
const tokenAuthInputSchema = z.object({ token: z.string().min(1) });
|
|
95
|
+
/** Query parameter carrying the OAuth callback URI for an OAuth start request. */
|
|
96
|
+
const API_OAUTH_REDIRECT_URI_QUERY_PARAMETER = "redirectUri";
|
|
97
|
+
const oauthRedirectUriSchema = z.url().refine((value) => {
|
|
98
|
+
const protocol = new URL(value).protocol;
|
|
99
|
+
return protocol === "https:" || protocol === "http:";
|
|
100
|
+
}, "OAuth redirect URI must use HTTP or HTTPS");
|
|
101
|
+
const oauthStartInputSchema = z.object({
|
|
102
|
+
scopes: z.array(z.string()).optional(),
|
|
103
|
+
extraAuthorizationParams: z.record(z.string(), z.string()).optional(),
|
|
104
|
+
discardTokens: z.boolean().default(false).describe("Drop stored tokens so status reports pending consent until this new consent completes.")
|
|
105
|
+
});
|
|
106
|
+
const apiRequestBodySchema = z.discriminatedUnion("type", [
|
|
107
|
+
z.object({ type: z.literal("empty") }),
|
|
108
|
+
z.object({
|
|
109
|
+
type: z.literal("json"),
|
|
110
|
+
value: z.unknown()
|
|
111
|
+
}),
|
|
112
|
+
z.object({
|
|
113
|
+
type: z.literal("text"),
|
|
114
|
+
value: z.string()
|
|
115
|
+
})
|
|
116
|
+
]);
|
|
117
|
+
const apiRequestInputSchema = z.object({
|
|
118
|
+
method: z.enum([
|
|
119
|
+
"GET",
|
|
120
|
+
"POST",
|
|
121
|
+
"PUT",
|
|
122
|
+
"PATCH",
|
|
123
|
+
"DELETE"
|
|
124
|
+
]),
|
|
125
|
+
path: z.string().min(1),
|
|
126
|
+
query: z.record(z.string(), z.string()).optional(),
|
|
127
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
128
|
+
body: apiRequestBodySchema,
|
|
129
|
+
timeoutMs: z.number().int().positive().max(12e4).optional()
|
|
130
|
+
});
|
|
131
|
+
const apiResponseBodySchema = z.discriminatedUnion("type", [
|
|
132
|
+
z.object({
|
|
133
|
+
type: z.literal("json"),
|
|
134
|
+
value: z.unknown()
|
|
135
|
+
}),
|
|
136
|
+
z.object({
|
|
137
|
+
type: z.literal("text"),
|
|
138
|
+
value: z.string()
|
|
139
|
+
}),
|
|
140
|
+
z.object({
|
|
141
|
+
type: z.literal("empty"),
|
|
142
|
+
value: z.null()
|
|
143
|
+
})
|
|
144
|
+
]);
|
|
145
|
+
const apiHttpResponseSchema = z.object({
|
|
146
|
+
status: z.number().int(),
|
|
147
|
+
statusText: z.string(),
|
|
148
|
+
headers: z.record(z.string(), z.string()),
|
|
149
|
+
body: apiResponseBodySchema
|
|
150
|
+
});
|
|
151
|
+
const apiRequestOutputSchema = z.discriminatedUnion("ok", [z.object({
|
|
152
|
+
ok: z.literal(true),
|
|
153
|
+
response: apiHttpResponseSchema,
|
|
154
|
+
error: z.null()
|
|
155
|
+
}), z.object({
|
|
156
|
+
ok: z.literal(false),
|
|
157
|
+
response: apiHttpResponseSchema.nullable(),
|
|
158
|
+
error: z.object({
|
|
159
|
+
code: z.enum([
|
|
160
|
+
"HTTP_ERROR",
|
|
161
|
+
"REQUEST_ERROR",
|
|
162
|
+
"RESPONSE_DECODING_ERROR",
|
|
163
|
+
"CONNECTION_NOT_FOUND",
|
|
164
|
+
"CONNECTION_DISABLED"
|
|
165
|
+
]),
|
|
166
|
+
message: z.string()
|
|
167
|
+
})
|
|
168
|
+
})]);
|
|
169
|
+
const webhookSecretRefSchema = z.string().trim().min(1);
|
|
170
|
+
const webhookRequestValueNameSchema = z.string().trim().min(1);
|
|
171
|
+
const webhookDeliveryIdentitySchema = z.discriminatedUnion("type", [
|
|
172
|
+
z.object({
|
|
173
|
+
type: z.literal("header"),
|
|
174
|
+
name: webhookRequestValueNameSchema
|
|
175
|
+
}),
|
|
176
|
+
z.object({
|
|
177
|
+
type: z.literal("query"),
|
|
178
|
+
name: webhookRequestValueNameSchema
|
|
179
|
+
}),
|
|
180
|
+
z.object({
|
|
181
|
+
type: z.literal("jsonBodyPath"),
|
|
182
|
+
path: z.array(z.string().trim().min(1)).min(1)
|
|
183
|
+
})
|
|
184
|
+
]);
|
|
185
|
+
const webhookEndpointAuthInputSchema = z.discriminatedUnion("type", [
|
|
186
|
+
z.object({ type: z.literal("none") }),
|
|
187
|
+
z.object({
|
|
188
|
+
type: z.literal("bearer"),
|
|
189
|
+
token: webhookSecretRefSchema
|
|
190
|
+
}),
|
|
191
|
+
z.object({
|
|
192
|
+
type: z.literal("apiKey"),
|
|
193
|
+
location: z.enum(["header", "query"]),
|
|
194
|
+
name: webhookRequestValueNameSchema,
|
|
195
|
+
secret: webhookSecretRefSchema
|
|
196
|
+
}),
|
|
197
|
+
z.object({
|
|
198
|
+
type: z.literal("basic"),
|
|
199
|
+
username: webhookSecretRefSchema,
|
|
200
|
+
password: webhookSecretRefSchema
|
|
201
|
+
}),
|
|
202
|
+
z.object({
|
|
203
|
+
type: z.literal("hmac"),
|
|
204
|
+
secret: webhookSecretRefSchema,
|
|
205
|
+
algorithm: z.enum([
|
|
206
|
+
"sha1",
|
|
207
|
+
"sha256",
|
|
208
|
+
"sha512"
|
|
209
|
+
]),
|
|
210
|
+
signature: z.object({
|
|
211
|
+
location: z.enum(["header", "query"]),
|
|
212
|
+
name: webhookRequestValueNameSchema,
|
|
213
|
+
encoding: z.enum([
|
|
214
|
+
"hex",
|
|
215
|
+
"base64",
|
|
216
|
+
"base64url"
|
|
217
|
+
]),
|
|
218
|
+
prefix: z.string().optional()
|
|
219
|
+
}),
|
|
220
|
+
signedPayload: z.discriminatedUnion("type", [z.object({ type: z.literal("rawBody") }), z.object({
|
|
221
|
+
type: z.literal("timestampedBody"),
|
|
222
|
+
prefix: z.string(),
|
|
223
|
+
timestampHeader: webhookRequestValueNameSchema,
|
|
224
|
+
delimiter: z.string(),
|
|
225
|
+
toleranceSeconds: z.number().int().positive()
|
|
226
|
+
})])
|
|
227
|
+
})
|
|
228
|
+
]);
|
|
229
|
+
const webhookEndpointStatusSchema = z.enum([
|
|
230
|
+
"draft",
|
|
231
|
+
"active",
|
|
232
|
+
"disabled"
|
|
233
|
+
]);
|
|
234
|
+
/** Why the receive routes refused a request for an existing endpoint. */
|
|
235
|
+
const webhookRejectionCodeSchema = z.enum([
|
|
236
|
+
"WEBHOOK_ENDPOINT_DISABLED",
|
|
237
|
+
"WEBHOOK_ENDPOINT_DRAFT",
|
|
238
|
+
"WEBHOOK_AUTH_FAILED",
|
|
239
|
+
"WEBHOOK_VERIFICATION_NOT_MATCHED",
|
|
240
|
+
"WEBHOOK_VERIFICATION_RESPONSE_INVALID",
|
|
241
|
+
"WEBHOOK_BODY_INVALID",
|
|
242
|
+
"WEBHOOK_DELIVERY_ID_MISSING",
|
|
243
|
+
"WEBHOOK_DELIVERY_ID_INVALID"
|
|
244
|
+
]);
|
|
245
|
+
const webhookDeliveryEvidenceSchema = z.object({
|
|
246
|
+
lastAcceptedAt: z.string().nullable().describe("Last accepted delivery or answered verification challenge."),
|
|
247
|
+
lastRejection: z.object({
|
|
248
|
+
receivedAt: z.string(),
|
|
249
|
+
code: webhookRejectionCodeSchema
|
|
250
|
+
}).nullable().describe("Last refused request. Anyone with the URL can cause one, so it is diagnostic, not proof of a provider problem.")
|
|
251
|
+
}).describe("Requests since the endpoint's configuration last changed.");
|
|
252
|
+
const webhookEndpointOutputSchema = z.object({
|
|
253
|
+
id: z.string(),
|
|
254
|
+
name: z.string(),
|
|
255
|
+
status: webhookEndpointStatusSchema,
|
|
256
|
+
authConfig: webhookAuthConfigSchema,
|
|
257
|
+
verification: webhookVerificationConfigSchema,
|
|
258
|
+
deliveryIdentity: webhookDeliveryIdentitySchema,
|
|
259
|
+
secretRefs: z.array(z.string()),
|
|
260
|
+
deliveries: webhookDeliveryEvidenceSchema,
|
|
261
|
+
createdAt: z.union([z.string(), z.date()]).optional(),
|
|
262
|
+
updatedAt: z.union([z.string(), z.date()]).optional()
|
|
263
|
+
});
|
|
264
|
+
const createWebhookEndpointInputSchema = z.object({
|
|
265
|
+
name: z.string().min(1),
|
|
266
|
+
status: webhookEndpointStatusSchema.default("active"),
|
|
267
|
+
verification: webhookVerificationConfigSchema,
|
|
268
|
+
deliveryIdentity: webhookDeliveryIdentitySchema,
|
|
269
|
+
auth: webhookEndpointAuthInputSchema
|
|
270
|
+
});
|
|
271
|
+
const updateWebhookEndpointInputSchema = z.object({
|
|
272
|
+
name: z.string().min(1).optional(),
|
|
273
|
+
status: webhookEndpointStatusSchema.optional(),
|
|
274
|
+
verification: webhookVerificationConfigSchema.optional(),
|
|
275
|
+
deliveryIdentity: webhookDeliveryIdentitySchema.optional(),
|
|
276
|
+
auth: webhookEndpointAuthInputSchema.optional()
|
|
277
|
+
});
|
|
278
|
+
//#endregion
|
|
279
|
+
export { API_OAUTH_REDIRECT_URI_QUERY_PARAMETER, apiAuthStatusSchema, apiConnectionOutputSchema, apiConnectionSlugSchema, apiConnectionsPageSchema, apiHttpResponseSchema, apiOAuthPendingSchema, apiRequestBodySchema, apiRequestInputSchema, apiRequestOutputSchema, apiResponseBodySchema, authConfigSchema, createApiConnectionInputSchema, createWebhookEndpointInputSchema, oauthRedirectUriSchema, oauthStartInputSchema, tokenAuthInputSchema, updateWebhookEndpointInputSchema, webhookDeliveryEvidenceSchema, webhookDeliveryIdentitySchema, webhookEndpointAuthInputSchema, webhookEndpointOutputSchema, webhookEndpointStatusSchema, webhookRejectionCodeSchema };
|
|
280
|
+
|
|
281
|
+
//# sourceMappingURL=api-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-types.js","names":[],"sources":["../../src/api-types.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { webhookAuthConfigSchema } from \"./webhooks/auth\";\nimport { webhookVerificationConfigSchema } from \"./webhooks/verification\";\n\nexport interface ApiFragmentConfig {\n /** Optional URL allow-list. If omitted, only http(s) URL syntax is checked. */\n allowedBaseUrls?: (url: URL) => boolean;\n /** Allows OAuth callback URLs. OAuth start is rejected when this policy is omitted. */\n allowedOAuthRedirectUris?: (url: URL) => boolean;\n /** Optional fetch implementation for tests/custom runtimes. */\n fetch?: typeof fetch;\n}\n\nconst tokenEndpointAuthMethodSchema = z.enum([\"client_secret_basic\", \"client_secret_post\", \"none\"]);\n\nexport const authConfigSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), token: z.string().min(1) }),\n z.object({\n type: z.literal(\"basic\"),\n username: z.string().min(1),\n password: z.string().min(1),\n }),\n z.object({\n type: z.literal(\"client_credentials\"),\n tokenEndpoint: z.url(),\n clientId: z.string().min(1),\n clientSecret: z.string().min(1),\n scopes: z.array(z.string()).optional(),\n audience: z.string().min(1).optional(),\n tokenEndpointAuthMethod: z\n .enum([\"client_secret_basic\", \"client_secret_post\"])\n .default(\"client_secret_basic\"),\n }),\n z.object({\n type: z.literal(\"oauth\"),\n authorizationEndpoint: z.url(),\n tokenEndpoint: z.url(),\n clientId: z.string().min(1),\n clientSecret: z.string().min(1).optional(),\n scopes: z.array(z.string()).optional(),\n tokenEndpointAuthMethod: tokenEndpointAuthMethodSchema.default(\"client_secret_basic\"),\n extraAuthorizationParams: z.record(z.string(), z.string()).optional(),\n extraTokenParams: z.record(z.string(), z.string()).optional(),\n }),\n]);\n\n/** Slugs are URL path segments; whitespace and dot segments would make a connection unaddressable. */\nexport const apiConnectionSlugSchema = z\n .string()\n .regex(\n /^[A-Za-z0-9][A-Za-z0-9._-]*$/,\n \"API connection slugs start with a letter or digit and contain only letters, digits, '.', '_', or '-'.\",\n );\n\nexport const createApiConnectionInputSchema = z.object({\n name: z.string().min(1).optional(),\n baseUrl: z.url(),\n auth: authConfigSchema.default({ type: \"none\" }),\n});\n\nexport const apiConnectionOutputSchema = z.object({\n slug: z.string(),\n name: z.string().nullable().optional(),\n baseUrl: z.string(),\n authMode: z.string(),\n status: z.string(),\n createdAt: z.union([z.string(), z.date()]).optional(),\n updatedAt: z.union([z.string(), z.date()]).optional(),\n});\n\nexport const apiConnectionsPageSchema = z.object({\n connections: z.array(apiConnectionOutputSchema),\n cursor: z.string().nullable().describe(\"Null means every connection has been listed.\"),\n});\n\nconst apiCredentialsPresenceSchema = z\n .enum([\"present\", \"missing\"])\n .describe(\"Whether credentials are stored, not whether the provider accepts them.\");\n\n/** Sanitized auth state derived from stored configuration; it never proves live provider access. */\nexport const apiAuthStatusSchema = z.discriminatedUnion(\"mode\", [\n z.object({ mode: z.literal(\"none\") }),\n z.object({ mode: z.literal(\"bearer\"), credentials: apiCredentialsPresenceSchema }),\n z.object({ mode: z.literal(\"basic\"), credentials: apiCredentialsPresenceSchema }),\n z.object({ mode: z.literal(\"client_credentials\"), credentials: apiCredentialsPresenceSchema }),\n z.object({\n mode: z.literal(\"oauth\"),\n state: z\n .enum([\"client-missing\", \"consent-required\", \"consent-pending\", \"authorized\", \"expired\"])\n .describe(\n \"Expired means the access token expired and no refresh token is stored; pending means an unexpired authorization link exists.\",\n ),\n }),\n]);\n\n/** The pending link embeds the callback state, so reading it requires connection-create authority. */\nexport const apiOAuthPendingSchema = z.object({\n pending: z\n .object({ authorizationUrl: z.url(), expiresAt: z.union([z.string(), z.date()]) })\n .nullable()\n .describe(\n \"The newest unexpired, unconsumed authorization link; any pending link completes it.\",\n ),\n});\n\nexport const tokenAuthInputSchema = z.object({ token: z.string().min(1) });\n\n/** Query parameter carrying the OAuth callback URI for an OAuth start request. */\nexport const API_OAUTH_REDIRECT_URI_QUERY_PARAMETER = \"redirectUri\";\n\nexport const oauthRedirectUriSchema = z.url().refine((value) => {\n const protocol = new URL(value).protocol;\n return protocol === \"https:\" || protocol === \"http:\";\n}, \"OAuth redirect URI must use HTTP or HTTPS\");\n\nexport const oauthStartInputSchema = z.object({\n scopes: z.array(z.string()).optional(),\n extraAuthorizationParams: z.record(z.string(), z.string()).optional(),\n discardTokens: z\n .boolean()\n .default(false)\n .describe(\n \"Drop stored tokens so status reports pending consent until this new consent completes.\",\n ),\n});\n\nexport const apiRequestBodySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"empty\") }),\n z.object({ type: z.literal(\"json\"), value: z.unknown() }),\n z.object({ type: z.literal(\"text\"), value: z.string() }),\n]);\n\nexport const apiRequestInputSchema = z.object({\n method: z.enum([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"]),\n path: z.string().min(1),\n query: z.record(z.string(), z.string()).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n body: apiRequestBodySchema,\n timeoutMs: z.number().int().positive().max(120_000).optional(),\n});\n\nexport const apiResponseBodySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"json\"), value: z.unknown() }),\n z.object({ type: z.literal(\"text\"), value: z.string() }),\n z.object({ type: z.literal(\"empty\"), value: z.null() }),\n]);\n\nexport const apiHttpResponseSchema = z.object({\n status: z.number().int(),\n statusText: z.string(),\n headers: z.record(z.string(), z.string()),\n body: apiResponseBodySchema,\n});\n\nexport const apiRequestOutputSchema = z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n response: apiHttpResponseSchema,\n error: z.null(),\n }),\n z.object({\n ok: z.literal(false),\n response: apiHttpResponseSchema.nullable(),\n error: z.object({\n code: z.enum([\n \"HTTP_ERROR\",\n \"REQUEST_ERROR\",\n \"RESPONSE_DECODING_ERROR\",\n \"CONNECTION_NOT_FOUND\",\n \"CONNECTION_DISABLED\",\n ]),\n message: z.string(),\n }),\n }),\n]);\n\nconst webhookSecretRefSchema = z.string().trim().min(1);\nconst webhookRequestValueNameSchema = z.string().trim().min(1);\n\nexport const webhookDeliveryIdentitySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"header\"), name: webhookRequestValueNameSchema }),\n z.object({ type: z.literal(\"query\"), name: webhookRequestValueNameSchema }),\n z.object({\n type: z.literal(\"jsonBodyPath\"),\n path: z.array(z.string().trim().min(1)).min(1),\n }),\n]);\n\nexport const webhookEndpointAuthInputSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), token: webhookSecretRefSchema }),\n z.object({\n type: z.literal(\"apiKey\"),\n location: z.enum([\"header\", \"query\"]),\n name: webhookRequestValueNameSchema,\n secret: webhookSecretRefSchema,\n }),\n z.object({\n type: z.literal(\"basic\"),\n username: webhookSecretRefSchema,\n password: webhookSecretRefSchema,\n }),\n z.object({\n type: z.literal(\"hmac\"),\n secret: webhookSecretRefSchema,\n algorithm: z.enum([\"sha1\", \"sha256\", \"sha512\"]),\n signature: z.object({\n location: z.enum([\"header\", \"query\"]),\n name: webhookRequestValueNameSchema,\n encoding: z.enum([\"hex\", \"base64\", \"base64url\"]),\n prefix: z.string().optional(),\n }),\n signedPayload: z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"rawBody\") }),\n z.object({\n type: z.literal(\"timestampedBody\"),\n prefix: z.string(),\n timestampHeader: webhookRequestValueNameSchema,\n delimiter: z.string(),\n toleranceSeconds: z.number().int().positive(),\n }),\n ]),\n }),\n]);\n\nexport const webhookEndpointStatusSchema = z.enum([\"draft\", \"active\", \"disabled\"]);\n\n/** Why the receive routes refused a request for an existing endpoint. */\nexport const webhookRejectionCodeSchema = z.enum([\n \"WEBHOOK_ENDPOINT_DISABLED\",\n \"WEBHOOK_ENDPOINT_DRAFT\",\n \"WEBHOOK_AUTH_FAILED\",\n \"WEBHOOK_VERIFICATION_NOT_MATCHED\",\n \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\",\n \"WEBHOOK_BODY_INVALID\",\n \"WEBHOOK_DELIVERY_ID_MISSING\",\n \"WEBHOOK_DELIVERY_ID_INVALID\",\n]);\n\nexport const webhookDeliveryEvidenceSchema = z\n .object({\n lastAcceptedAt: z\n .string()\n .nullable()\n .describe(\"Last accepted delivery or answered verification challenge.\"),\n lastRejection: z\n .object({ receivedAt: z.string(), code: webhookRejectionCodeSchema })\n .nullable()\n .describe(\n \"Last refused request. Anyone with the URL can cause one, so it is diagnostic, not proof of a provider problem.\",\n ),\n })\n .describe(\"Requests since the endpoint's configuration last changed.\");\n\nexport const webhookEndpointOutputSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: webhookEndpointStatusSchema,\n authConfig: webhookAuthConfigSchema,\n verification: webhookVerificationConfigSchema,\n deliveryIdentity: webhookDeliveryIdentitySchema,\n secretRefs: z.array(z.string()),\n deliveries: webhookDeliveryEvidenceSchema,\n createdAt: z.union([z.string(), z.date()]).optional(),\n updatedAt: z.union([z.string(), z.date()]).optional(),\n});\n\nexport const createWebhookEndpointInputSchema = z.object({\n name: z.string().min(1),\n status: webhookEndpointStatusSchema.default(\"active\"),\n verification: webhookVerificationConfigSchema,\n deliveryIdentity: webhookDeliveryIdentitySchema,\n auth: webhookEndpointAuthInputSchema,\n});\n\nexport const updateWebhookEndpointInputSchema = z.object({\n name: z.string().min(1).optional(),\n status: webhookEndpointStatusSchema.optional(),\n verification: webhookVerificationConfigSchema.optional(),\n deliveryIdentity: webhookDeliveryIdentitySchema.optional(),\n auth: webhookEndpointAuthInputSchema.optional(),\n});\n\nexport type AuthConfig = z.infer<typeof authConfigSchema>;\nexport type ApiConnectionInput = z.infer<typeof createApiConnectionInputSchema>;\nexport type ApiConnection = z.infer<typeof apiConnectionOutputSchema>;\nexport type ApiConnectionsPage = z.infer<typeof apiConnectionsPageSchema>;\nexport type ApiAuthStatus = z.infer<typeof apiAuthStatusSchema>;\nexport type ApiOAuthPending = z.infer<typeof apiOAuthPendingSchema>;\nexport type ApiRequestBody = z.infer<typeof apiRequestBodySchema>;\nexport type ApiRequestInput = z.infer<typeof apiRequestInputSchema>;\nexport type ApiResponseBody = z.infer<typeof apiResponseBodySchema>;\nexport type ApiHttpResponse = z.infer<typeof apiHttpResponseSchema>;\nexport type ApiRequestOutput = z.infer<typeof apiRequestOutputSchema>;\nexport type WebhookDeliveryIdentity = z.infer<typeof webhookDeliveryIdentitySchema>;\nexport type WebhookEndpointAuthInput = z.infer<typeof webhookEndpointAuthInputSchema>;\nexport type WebhookEndpointInput = z.infer<typeof createWebhookEndpointInputSchema>;\nexport type UpdateWebhookEndpointInput = z.infer<typeof updateWebhookEndpointInputSchema>;\nexport type WebhookEndpoint = z.infer<typeof webhookEndpointOutputSchema>;\nexport type WebhookRejectionCode = z.infer<typeof webhookRejectionCodeSchema>;\nexport type WebhookDeliveryEvidence = z.infer<typeof webhookDeliveryEvidenceSchema>;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/crypto.d.ts
|
|
2
|
+
declare function timingSafeEqualText(first: string, second: string): Promise<boolean>;
|
|
3
|
+
declare function timingSafeEqualBytes(first: Uint8Array, second: Uint8Array): Promise<boolean>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { timingSafeEqualBytes, timingSafeEqualText };
|
|
6
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","names":[],"sources":["../../src/crypto.ts"],"mappings":";iBA0KsB,oBAAoB,eAAe,iBAAc;iBAIjD,qBAAqB,OAAO,YAAY,QAAQ,aAAU"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//#region src/crypto.ts
|
|
2
|
+
const textEncoder = new TextEncoder();
|
|
3
|
+
const textDecoder = new TextDecoder();
|
|
4
|
+
const hmacHashName = (algorithm) => ({
|
|
5
|
+
sha1: "SHA-1",
|
|
6
|
+
sha256: "SHA-256",
|
|
7
|
+
sha512: "SHA-512"
|
|
8
|
+
})[algorithm];
|
|
9
|
+
function toArrayBuffer(bytes) {
|
|
10
|
+
const copy = new Uint8Array(bytes.byteLength);
|
|
11
|
+
copy.set(bytes);
|
|
12
|
+
return copy.buffer;
|
|
13
|
+
}
|
|
14
|
+
function utf8Bytes(value) {
|
|
15
|
+
return textEncoder.encode(value);
|
|
16
|
+
}
|
|
17
|
+
function assertAscii(value, label) {
|
|
18
|
+
for (let index = 0; index < value.length; index += 1) if (value.charCodeAt(index) > 127) throw new Error(`${label} must contain ASCII characters only`);
|
|
19
|
+
}
|
|
20
|
+
function asciiToBase64(value, label) {
|
|
21
|
+
assertAscii(value, label);
|
|
22
|
+
return btoa(value);
|
|
23
|
+
}
|
|
24
|
+
function bytesToBase64(bytes) {
|
|
25
|
+
let binary = "";
|
|
26
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
27
|
+
return btoa(binary);
|
|
28
|
+
}
|
|
29
|
+
function bytesToBase64Url(bytes) {
|
|
30
|
+
return bytesToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
31
|
+
}
|
|
32
|
+
function decodeHex(value) {
|
|
33
|
+
const normalized = value.trim();
|
|
34
|
+
if (normalized.length === 0 || normalized.length % 2 !== 0 || /[^0-9a-f]/i.test(normalized)) return null;
|
|
35
|
+
const bytes = new Uint8Array(normalized.length / 2);
|
|
36
|
+
for (let index = 0; index < normalized.length; index += 2) bytes[index / 2] = Number.parseInt(normalized.slice(index, index + 2), 16);
|
|
37
|
+
return bytes;
|
|
38
|
+
}
|
|
39
|
+
function decodeBase64(value, encoding) {
|
|
40
|
+
const normalized = normalizeBase64(value, encoding);
|
|
41
|
+
if (!normalized) return null;
|
|
42
|
+
try {
|
|
43
|
+
const binary = atob(normalized);
|
|
44
|
+
const bytes = new Uint8Array(binary.length);
|
|
45
|
+
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
46
|
+
return bytes;
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function decodeBase64ToText(value, encoding) {
|
|
52
|
+
const bytes = decodeBase64(value, encoding);
|
|
53
|
+
if (!bytes) return null;
|
|
54
|
+
return textDecoder.decode(bytes);
|
|
55
|
+
}
|
|
56
|
+
function normalizeBase64(value, encoding) {
|
|
57
|
+
let normalized = value.trim();
|
|
58
|
+
if (!normalized) return null;
|
|
59
|
+
if (encoding === "base64url") normalized = normalized.replace(/-/g, "+").replace(/_/g, "/");
|
|
60
|
+
const paddingLength = (4 - normalized.length % 4) % 4;
|
|
61
|
+
return `${normalized}${"=".repeat(paddingLength)}`;
|
|
62
|
+
}
|
|
63
|
+
function randomBase64Url(bytes = 32) {
|
|
64
|
+
const data = new Uint8Array(bytes);
|
|
65
|
+
crypto.getRandomValues(data);
|
|
66
|
+
return bytesToBase64Url(data);
|
|
67
|
+
}
|
|
68
|
+
async function sha256Bytes(bytes) {
|
|
69
|
+
return new Uint8Array(await crypto.subtle.digest("SHA-256", toArrayBuffer(bytes)));
|
|
70
|
+
}
|
|
71
|
+
async function sha256Base64Url(value) {
|
|
72
|
+
return bytesToBase64Url(await sha256Bytes(utf8Bytes(value)));
|
|
73
|
+
}
|
|
74
|
+
async function importHmacKey(input) {
|
|
75
|
+
return await crypto.subtle.importKey("raw", toArrayBuffer(utf8Bytes(input.secret)), {
|
|
76
|
+
name: "HMAC",
|
|
77
|
+
hash: hmacHashName(input.algorithm)
|
|
78
|
+
}, false, ["sign", "verify"]);
|
|
79
|
+
}
|
|
80
|
+
async function verifyHmacSignature(input) {
|
|
81
|
+
const key = await importHmacKey(input);
|
|
82
|
+
return await crypto.subtle.verify("HMAC", key, toArrayBuffer(input.signature), toArrayBuffer(input.payload));
|
|
83
|
+
}
|
|
84
|
+
async function digestEqual(first, second) {
|
|
85
|
+
const [firstDigest, secondDigest] = await Promise.all([sha256Bytes(first), sha256Bytes(second)]);
|
|
86
|
+
return equalLengthBytes(firstDigest, secondDigest);
|
|
87
|
+
}
|
|
88
|
+
function equalLengthBytes(first, second) {
|
|
89
|
+
if (first.length !== second.length) return false;
|
|
90
|
+
let diff = 0;
|
|
91
|
+
for (let index = 0; index < first.length; index += 1) diff |= first[index] ^ second[index];
|
|
92
|
+
return diff === 0;
|
|
93
|
+
}
|
|
94
|
+
async function timingSafeEqualText(first, second) {
|
|
95
|
+
return await digestEqual(utf8Bytes(first), utf8Bytes(second));
|
|
96
|
+
}
|
|
97
|
+
async function timingSafeEqualBytes(first, second) {
|
|
98
|
+
return await digestEqual(first, second);
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { asciiToBase64, assertAscii, bytesToBase64, bytesToBase64Url, decodeBase64, decodeBase64ToText, decodeHex, digestEqual, importHmacKey, normalizeBase64, randomBase64Url, sha256Base64Url, sha256Bytes, timingSafeEqualBytes, timingSafeEqualText, toArrayBuffer, utf8Bytes, verifyHmacSignature };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","names":[],"sources":["../../src/crypto.ts"],"sourcesContent":["const textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\nexport type HmacAlgorithm = \"sha1\" | \"sha256\" | \"sha512\";\n\nconst hmacHashName = (algorithm: HmacAlgorithm) =>\n ({\n sha1: \"SHA-1\",\n sha256: \"SHA-256\",\n sha512: \"SHA-512\",\n })[algorithm];\n\nexport function toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nexport function utf8Bytes(value: string) {\n return textEncoder.encode(value);\n}\n\nexport function assertAscii(value: string, label: string) {\n for (let index = 0; index < value.length; index += 1) {\n if (value.charCodeAt(index) > 0x7f) {\n throw new Error(`${label} must contain ASCII characters only`);\n }\n }\n}\n\nexport function asciiToBase64(value: string, label: string) {\n assertAscii(value, label);\n return btoa(value);\n}\n\nexport function bytesToBase64(bytes: Uint8Array) {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToBase64Url(bytes: Uint8Array) {\n return bytesToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport function bytesToHex(bytes: Uint8Array) {\n return [...bytes].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function decodeHex(value: string) {\n const normalized = value.trim();\n if (normalized.length === 0 || normalized.length % 2 !== 0 || /[^0-9a-f]/i.test(normalized)) {\n return null;\n }\n\n const bytes = new Uint8Array(normalized.length / 2);\n for (let index = 0; index < normalized.length; index += 2) {\n bytes[index / 2] = Number.parseInt(normalized.slice(index, index + 2), 16);\n }\n return bytes;\n}\n\nexport function decodeBase64(value: string, encoding: \"base64\" | \"base64url\") {\n const normalized = normalizeBase64(value, encoding);\n if (!normalized) {\n return null;\n }\n\n try {\n const binary = atob(normalized);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n } catch {\n return null;\n }\n}\n\nexport function decodeBase64ToText(value: string, encoding: \"base64\" | \"base64url\") {\n const bytes = decodeBase64(value, encoding);\n if (!bytes) {\n return null;\n }\n\n return textDecoder.decode(bytes);\n}\n\nexport function normalizeBase64(value: string, encoding: \"base64\" | \"base64url\") {\n let normalized = value.trim();\n if (!normalized) {\n return null;\n }\n\n if (encoding === \"base64url\") {\n normalized = normalized.replace(/-/g, \"+\").replace(/_/g, \"/\");\n }\n\n const paddingLength = (4 - (normalized.length % 4)) % 4;\n return `${normalized}${\"=\".repeat(paddingLength)}`;\n}\n\nexport function randomBase64Url(bytes = 32) {\n const data = new Uint8Array(bytes);\n crypto.getRandomValues(data);\n return bytesToBase64Url(data);\n}\n\nexport async function sha256Bytes(bytes: Uint8Array) {\n return new Uint8Array(await crypto.subtle.digest(\"SHA-256\", toArrayBuffer(bytes)));\n}\n\nexport async function sha256Base64Url(value: string) {\n return bytesToBase64Url(await sha256Bytes(utf8Bytes(value)));\n}\n\nexport async function importHmacKey(input: { algorithm: HmacAlgorithm; secret: string }) {\n return await crypto.subtle.importKey(\n \"raw\",\n toArrayBuffer(utf8Bytes(input.secret)),\n { name: \"HMAC\", hash: hmacHashName(input.algorithm) },\n false,\n [\"sign\", \"verify\"],\n );\n}\n\nexport async function signHmacBytes(input: {\n algorithm: HmacAlgorithm;\n secret: string;\n payload: Uint8Array;\n}) {\n const key = await importHmacKey(input);\n return new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, toArrayBuffer(input.payload)));\n}\n\nexport async function verifyHmacSignature(input: {\n algorithm: HmacAlgorithm;\n secret: string;\n payload: Uint8Array;\n signature: Uint8Array;\n}) {\n const key = await importHmacKey(input);\n return await crypto.subtle.verify(\n \"HMAC\",\n key,\n toArrayBuffer(input.signature),\n toArrayBuffer(input.payload),\n );\n}\n\nexport async function digestEqual(first: Uint8Array, second: Uint8Array) {\n const [firstDigest, secondDigest] = await Promise.all([sha256Bytes(first), sha256Bytes(second)]);\n return equalLengthBytes(firstDigest, secondDigest);\n}\n\nfunction equalLengthBytes(first: Uint8Array, second: Uint8Array) {\n if (first.length !== second.length) {\n return false;\n }\n\n let diff = 0;\n for (let index = 0; index < first.length; index += 1) {\n diff |= first[index] ^ second[index];\n }\n return diff === 0;\n}\n\nexport async function timingSafeEqualText(first: string, second: string) {\n return await digestEqual(utf8Bytes(first), utf8Bytes(second));\n}\n\nexport async function timingSafeEqualBytes(first: Uint8Array, second: Uint8Array) {\n return await digestEqual(first, second);\n}\n"],"mappings":"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"}
|