@pymthouse/builder-sdk 0.1.0 → 0.3.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.
Files changed (77) hide show
  1. package/README.md +66 -0
  2. package/dist/{client-BroVFyIy.d.ts → client-BHfjDvIe.d.ts} +49 -1
  3. package/dist/{client-BhC1YhB1.d.cts → client-CvhJEhjV.d.cts} +49 -1
  4. package/dist/config.cjs +59 -3
  5. package/dist/config.cjs.map +1 -1
  6. package/dist/config.d.cts +8 -1
  7. package/dist/config.d.ts +8 -1
  8. package/dist/config.js +57 -4
  9. package/dist/config.js.map +1 -1
  10. package/dist/device-initiate.cjs +1 -1
  11. package/dist/device-initiate.cjs.map +1 -1
  12. package/dist/device-initiate.js +1 -1
  13. package/dist/device-initiate.js.map +1 -1
  14. package/dist/device.cjs +1 -1
  15. package/dist/device.cjs.map +1 -1
  16. package/dist/device.d.cts +1 -1
  17. package/dist/device.d.ts +1 -1
  18. package/dist/device.js +1 -1
  19. package/dist/device.js.map +1 -1
  20. package/dist/env.cjs +794 -36
  21. package/dist/env.cjs.map +1 -1
  22. package/dist/env.d.cts +2 -2
  23. package/dist/env.d.ts +2 -2
  24. package/dist/env.js +794 -36
  25. package/dist/env.js.map +1 -1
  26. package/dist/gateway/client/index.cjs +492 -0
  27. package/dist/gateway/client/index.cjs.map +1 -0
  28. package/dist/gateway/client/index.d.cts +63 -0
  29. package/dist/gateway/client/index.d.ts +63 -0
  30. package/dist/gateway/client/index.js +489 -0
  31. package/dist/gateway/client/index.js.map +1 -0
  32. package/dist/gateway/index.cjs +16 -0
  33. package/dist/gateway/index.cjs.map +1 -0
  34. package/dist/gateway/index.d.cts +52 -0
  35. package/dist/gateway/index.d.ts +52 -0
  36. package/dist/gateway/index.js +10 -0
  37. package/dist/gateway/index.js.map +1 -0
  38. package/dist/gateway/server/index.cjs +1248 -0
  39. package/dist/gateway/server/index.cjs.map +1 -0
  40. package/dist/gateway/server/index.d.cts +31 -0
  41. package/dist/gateway/server/index.d.ts +31 -0
  42. package/dist/gateway/server/index.js +1233 -0
  43. package/dist/gateway/server/index.js.map +1 -0
  44. package/dist/index.cjs +1075 -186
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +6 -4
  47. package/dist/index.d.ts +6 -4
  48. package/dist/index.js +1042 -163
  49. package/dist/index.js.map +1 -1
  50. package/dist/ingest-B3Yi8Tb1.d.cts +271 -0
  51. package/dist/ingest-DoKJTWU9.d.ts +271 -0
  52. package/dist/plan-pricing.cjs +108 -0
  53. package/dist/plan-pricing.cjs.map +1 -0
  54. package/dist/plan-pricing.d.cts +15 -0
  55. package/dist/plan-pricing.d.ts +15 -0
  56. package/dist/plan-pricing.js +98 -0
  57. package/dist/plan-pricing.js.map +1 -0
  58. package/dist/signer/server.cjs +1366 -0
  59. package/dist/signer/server.cjs.map +1 -0
  60. package/dist/signer/server.d.cts +73 -0
  61. package/dist/signer/server.d.ts +73 -0
  62. package/dist/signer/server.js +1331 -0
  63. package/dist/signer/server.js.map +1 -0
  64. package/dist/tokens.d.cts +1 -1
  65. package/dist/tokens.d.ts +1 -1
  66. package/dist/types-_R1AwEZp.d.cts +343 -0
  67. package/dist/types-_R1AwEZp.d.ts +343 -0
  68. package/dist/verify.cjs +1 -1
  69. package/dist/verify.cjs.map +1 -1
  70. package/dist/verify.d.cts +1 -1
  71. package/dist/verify.d.ts +1 -1
  72. package/dist/verify.js +1 -1
  73. package/dist/verify.js.map +1 -1
  74. package/gateway/proto/lp_rpc.proto +542 -0
  75. package/package.json +42 -1
  76. package/dist/types-rKzVXvMu.d.cts +0 -196
  77. package/dist/types-rKzVXvMu.d.ts +0 -196
package/dist/env.js CHANGED
@@ -1,7 +1,15 @@
1
1
  import { genericTokenEndpointRequest, processGenericTokenEndpointResponse, clientCredentialsGrantRequest, processClientCredentialsResponse, customFetch, allowInsecureRequests, discoveryRequest, processDiscoveryResponse, ResponseBodyError, OperationProcessingError } from 'oauth4webapi';
2
2
  import 'crypto';
3
3
 
4
- // src/client.ts
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
5
13
 
6
14
  // src/encoding.ts
7
15
  function encodeClientSecretBasic(clientId, clientSecret) {
@@ -9,35 +17,69 @@ function encodeClientSecretBasic(clientId, clientSecret) {
9
17
  const b64 = typeof Buffer !== "undefined" ? Buffer.from(raw, "utf8").toString("base64") : btoa(Array.from(new TextEncoder().encode(raw), (c) => String.fromCharCode(c)).join(""));
10
18
  return `Basic ${b64}`;
11
19
  }
20
+ var init_encoding = __esm({
21
+ "src/encoding.ts"() {
22
+ }
23
+ });
12
24
 
13
25
  // src/errors.ts
14
- var PmtHouseError = class extends Error {
15
- status;
16
- code;
17
- details;
18
- constructor(message, {
19
- status = 500,
20
- code = "pymthouse_error",
21
- details
22
- } = {}) {
23
- super(message);
24
- this.name = "PmtHouseError";
25
- this.status = status;
26
- this.code = code;
27
- this.details = details;
26
+ var PmtHouseError;
27
+ var init_errors = __esm({
28
+ "src/errors.ts"() {
29
+ PmtHouseError = class extends Error {
30
+ status;
31
+ code;
32
+ details;
33
+ constructor(message, {
34
+ status = 500,
35
+ code = "pymthouse_error",
36
+ details
37
+ } = {}) {
38
+ super(message);
39
+ this.name = "PmtHouseError";
40
+ this.status = status;
41
+ this.code = code;
42
+ this.details = details;
43
+ }
44
+ };
28
45
  }
29
- };
46
+ });
30
47
 
31
48
  // src/string-utils.ts
32
49
  function stripTrailingSlashes(value) {
33
50
  let end = value.length;
34
- while (end > 0 && value.charCodeAt(end - 1) === 47) {
51
+ while (end > 0 && (value.codePointAt(end - 1) ?? 0) === 47) {
35
52
  end--;
36
53
  }
37
54
  return value.slice(0, end);
38
55
  }
39
-
40
- // src/discovery.ts
56
+ function endsWithIgnoreCase(value, suffix) {
57
+ if (suffix.length > value.length) {
58
+ return false;
59
+ }
60
+ const start = value.length - suffix.length;
61
+ for (let i = 0; i < suffix.length; i++) {
62
+ const a = value.codePointAt(start + i) ?? 0;
63
+ const b = suffix.codePointAt(i) ?? 0;
64
+ if (a !== b && (a | 32) !== (b | 32)) {
65
+ return false;
66
+ }
67
+ }
68
+ return true;
69
+ }
70
+ function stripSuffixIgnoreCase(value, suffix) {
71
+ return endsWithIgnoreCase(value, suffix) ? value.slice(0, value.length - suffix.length) : value;
72
+ }
73
+ function stripIssuerOriginFromOidcUrl(issuerUrl) {
74
+ let base = stripTrailingSlashes(issuerUrl.trim());
75
+ base = stripSuffixIgnoreCase(base, "/api/v1/oidc");
76
+ base = stripSuffixIgnoreCase(base, "/oidc");
77
+ return stripTrailingSlashes(base);
78
+ }
79
+ var init_string_utils = __esm({
80
+ "src/string-utils.ts"() {
81
+ }
82
+ });
41
83
  function authorizationServerToOidcDocument(as) {
42
84
  const tokenEndpoint = as.token_endpoint;
43
85
  const jwksUri = as.jwks_uri;
@@ -56,8 +98,6 @@ function authorizationServerToOidcDocument(as) {
56
98
  device_authorization_endpoint: as.device_authorization_endpoint
57
99
  };
58
100
  }
59
- var CACHE_TTL_MS = 5 * 60 * 1e3;
60
- var discoveryCache = /* @__PURE__ */ new Map();
61
101
  function normalizedIssuerKey(issuerUrl) {
62
102
  return stripTrailingSlashes(issuerUrl);
63
103
  }
@@ -122,6 +162,447 @@ function mapDiscoveryNetworkError(error) {
122
162
  code: "oidc_discovery_failed"
123
163
  });
124
164
  }
165
+ var CACHE_TTL_MS, discoveryCache;
166
+ var init_discovery = __esm({
167
+ "src/discovery.ts"() {
168
+ init_errors();
169
+ init_string_utils();
170
+ CACHE_TTL_MS = 5 * 60 * 1e3;
171
+ discoveryCache = /* @__PURE__ */ new Map();
172
+ }
173
+ });
174
+
175
+ // src/signer/fetch-json.ts
176
+ function oauthFailureDescription(parsed, failureLabel, status) {
177
+ if (typeof parsed.error_description === "string") {
178
+ return parsed.error_description;
179
+ }
180
+ if (typeof parsed.error === "string") {
181
+ return parsed.error;
182
+ }
183
+ return `${failureLabel} (${status})`;
184
+ }
185
+ async function readJsonObjectFromResponse(response, options) {
186
+ const text = await response.text();
187
+ let parsed;
188
+ try {
189
+ parsed = text ? JSON.parse(text) : {};
190
+ } catch {
191
+ throw new PmtHouseError(options.invalidJsonMessage, {
192
+ status: 502,
193
+ code: options.invalidJsonCode,
194
+ details: { status: response.status }
195
+ });
196
+ }
197
+ if (!response.ok) {
198
+ const description = oauthFailureDescription(parsed, options.failureLabel, response.status);
199
+ throw new PmtHouseError(description, {
200
+ status: response.status,
201
+ code: typeof parsed.error === "string" ? parsed.error : options.defaultErrorCode,
202
+ details: parsed
203
+ });
204
+ }
205
+ return parsed;
206
+ }
207
+ var init_fetch_json = __esm({
208
+ "src/signer/fetch-json.ts"() {
209
+ init_errors();
210
+ }
211
+ });
212
+
213
+ // src/signer/handler-errors.ts
214
+ function signerHandlerErrorResponse(error) {
215
+ if (error instanceof PmtHouseError) {
216
+ return new Response(
217
+ JSON.stringify({
218
+ error: error.code,
219
+ error_description: error.message,
220
+ details: error.details
221
+ }),
222
+ {
223
+ status: error.status,
224
+ headers: { "Content-Type": "application/json" }
225
+ }
226
+ );
227
+ }
228
+ const message = error instanceof Error ? error.message : "Internal error";
229
+ return new Response(JSON.stringify({ error: "internal_error", error_description: message }), {
230
+ status: 500,
231
+ headers: { "Content-Type": "application/json" }
232
+ });
233
+ }
234
+ var init_handler_errors = __esm({
235
+ "src/signer/handler-errors.ts"() {
236
+ init_errors();
237
+ }
238
+ });
239
+
240
+ // src/signer/json-fields.ts
241
+ function readStringField(body, key, errorCode, messagePrefix = "Response") {
242
+ const value = body[key];
243
+ if (typeof value !== "string" || !value.trim()) {
244
+ throw new PmtHouseError(`${messagePrefix} missing ${key}`, {
245
+ status: 502,
246
+ code: errorCode
247
+ });
248
+ }
249
+ return value.trim();
250
+ }
251
+ function readExpiresIn(body, errorCode) {
252
+ const expiresIn = body.expires_in;
253
+ if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
254
+ throw new PmtHouseError("Response missing expires_in", {
255
+ status: 502,
256
+ code: errorCode
257
+ });
258
+ }
259
+ return Math.floor(expiresIn);
260
+ }
261
+ var init_json_fields = __esm({
262
+ "src/signer/json-fields.ts"() {
263
+ init_errors();
264
+ }
265
+ });
266
+
267
+ // src/signer/mint-token.ts
268
+ function parseMintUserSignerTokenResponse(body, ttlRefreshRatio = DEFAULT_TTL_REFRESH_RATIO) {
269
+ const accessToken = readStringField(body, "access_token", TOKEN_RESPONSE_ERROR, "Token response");
270
+ const expiresIn = readExpiresIn(body, TOKEN_RESPONSE_ERROR);
271
+ const balanceUsdMicros = readStringField(
272
+ body,
273
+ "balanceUsdMicros",
274
+ TOKEN_RESPONSE_ERROR,
275
+ "Token response"
276
+ );
277
+ const lifetimeGrantedUsdMicros = readStringField(
278
+ body,
279
+ "lifetimeGrantedUsdMicros",
280
+ TOKEN_RESPONSE_ERROR,
281
+ "Token response"
282
+ );
283
+ const now = Date.now();
284
+ const expiresAt = now + expiresIn * 1e3;
285
+ const refreshAt = now + Math.floor(expiresIn * 1e3 * ttlRefreshRatio);
286
+ return {
287
+ jwt: accessToken,
288
+ expiresAt,
289
+ refreshAt,
290
+ balanceUsdMicros,
291
+ lifetimeGrantedUsdMicros
292
+ };
293
+ }
294
+ var LIVEPEER_REMOTE_SIGNER_AUDIENCE, DEFAULT_TTL_REFRESH_RATIO, TOKEN_RESPONSE_ERROR;
295
+ var init_mint_token = __esm({
296
+ "src/signer/mint-token.ts"() {
297
+ init_json_fields();
298
+ LIVEPEER_REMOTE_SIGNER_AUDIENCE = "livepeer-remote-signer";
299
+ DEFAULT_TTL_REFRESH_RATIO = 0.8;
300
+ TOKEN_RESPONSE_ERROR = "invalid_token_response";
301
+ }
302
+ });
303
+
304
+ // src/signer/device-exchange.ts
305
+ function extractSignerAccessTokenFromExchangeBody(body) {
306
+ const tokenObj = body.token;
307
+ if (tokenObj !== null && typeof tokenObj === "object" && !Array.isArray(tokenObj)) {
308
+ const nested = tokenObj;
309
+ for (const key of ["accessToken", "access_token"]) {
310
+ const value = nested[key];
311
+ if (typeof value === "string" && value.trim()) {
312
+ return value.trim();
313
+ }
314
+ }
315
+ }
316
+ for (const key of ["accessToken", "access_token"]) {
317
+ const value = body[key];
318
+ if (typeof value === "string" && value.trim()) {
319
+ return value.trim();
320
+ }
321
+ }
322
+ throw new PmtHouseError("Device exchange response missing signer access token", {
323
+ status: 502,
324
+ code: "invalid_exchange_response"
325
+ });
326
+ }
327
+ function normalizeDeviceExchangeResponse(minted, options) {
328
+ const scope = minted.scope.trim() || "sign:job";
329
+ const body = {
330
+ access_token: minted.access_token,
331
+ token_type: "Bearer",
332
+ expires_in: minted.expires_in,
333
+ scope,
334
+ balanceUsdMicros: minted.balanceUsdMicros,
335
+ lifetimeGrantedUsdMicros: minted.lifetimeGrantedUsdMicros,
336
+ token: {
337
+ accessToken: minted.access_token,
338
+ access_token: minted.access_token,
339
+ expiresIn: minted.expires_in,
340
+ expires_in: minted.expires_in,
341
+ scope,
342
+ balanceUsdMicros: minted.balanceUsdMicros,
343
+ lifetimeGrantedUsdMicros: minted.lifetimeGrantedUsdMicros
344
+ }
345
+ };
346
+ const signerUrl = options?.signerUrl?.trim();
347
+ if (signerUrl) {
348
+ body.signerUrl = signerUrl;
349
+ }
350
+ return body;
351
+ }
352
+ async function mintSignerTokenFromDeviceToken(options) {
353
+ const fetchImpl = options.fetch ?? fetch;
354
+ const issuerUrl = stripTrailingSlashes(options.issuerUrl);
355
+ const as = await loadAuthorizationServer(issuerUrl, fetchImpl, {
356
+ allowInsecureHttp: options.allowInsecureHttp
357
+ });
358
+ const tokenEndpoint = as.token_endpoint;
359
+ if (!tokenEndpoint) {
360
+ throw new PmtHouseError("OIDC discovery document is missing token_endpoint", {
361
+ status: 500,
362
+ code: "oidc_discovery_invalid"
363
+ });
364
+ }
365
+ const audience = options.audience?.trim() || LIVEPEER_REMOTE_SIGNER_AUDIENCE;
366
+ const params = new URLSearchParams({
367
+ grant_type: TOKEN_EXCHANGE_GRANT,
368
+ subject_token: options.deviceToken,
369
+ subject_token_type: SUBJECT_ACCESS_TOKEN_TYPE,
370
+ audience,
371
+ resource: audience
372
+ });
373
+ if (options.scope?.trim()) {
374
+ params.set("scope", options.scope.trim());
375
+ }
376
+ const response = await fetchImpl(tokenEndpoint, {
377
+ method: "POST",
378
+ headers: {
379
+ Authorization: encodeClientSecretBasic(options.m2mClientId, options.m2mClientSecret),
380
+ "Content-Type": "application/x-www-form-urlencoded",
381
+ Accept: "application/json"
382
+ },
383
+ body: params.toString(),
384
+ cache: "no-store"
385
+ });
386
+ const parsed = await readJsonObjectFromResponse(response, {
387
+ invalidJsonMessage: "Token endpoint returned invalid JSON",
388
+ invalidJsonCode: "invalid_token_response",
389
+ failureLabel: "Signer JWT exchange failed",
390
+ defaultErrorCode: "token_exchange_failed"
391
+ });
392
+ const cached = parseMintUserSignerTokenResponse(parsed);
393
+ return {
394
+ access_token: cached.jwt,
395
+ expires_in: readExpiresIn(parsed, EXCHANGE_RESPONSE_ERROR),
396
+ scope: readStringField(parsed, "scope", EXCHANGE_RESPONSE_ERROR),
397
+ balanceUsdMicros: cached.balanceUsdMicros,
398
+ lifetimeGrantedUsdMicros: cached.lifetimeGrantedUsdMicros
399
+ };
400
+ }
401
+ var TOKEN_EXCHANGE_GRANT, SUBJECT_ACCESS_TOKEN_TYPE, EXCHANGE_RESPONSE_ERROR;
402
+ var init_device_exchange = __esm({
403
+ "src/signer/device-exchange.ts"() {
404
+ init_discovery();
405
+ init_encoding();
406
+ init_errors();
407
+ init_string_utils();
408
+ init_fetch_json();
409
+ init_json_fields();
410
+ init_mint_token();
411
+ TOKEN_EXCHANGE_GRANT = "urn:ietf:params:oauth:grant-type:token-exchange";
412
+ SUBJECT_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
413
+ EXCHANGE_RESPONSE_ERROR = "invalid_exchange_response";
414
+ }
415
+ });
416
+
417
+ // src/signer/api-key-exchange.ts
418
+ var api_key_exchange_exports = {};
419
+ __export(api_key_exchange_exports, {
420
+ createApiKeyExchangeHandler: () => createApiKeyExchangeHandler,
421
+ exchangeApiKeyForSigner: () => exchangeApiKeyForSigner,
422
+ mintSignerSessionFromApiKey: () => mintSignerSessionFromApiKey,
423
+ mintUserAccessTokenFromApiKey: () => mintUserAccessTokenFromApiKey,
424
+ parseApiKeyExchangeRequestBody: () => parseApiKeyExchangeRequestBody
425
+ });
426
+ async function parseApiKeyExchangeRequestBody(request) {
427
+ let body;
428
+ try {
429
+ body = await request.json();
430
+ } catch {
431
+ throw new PmtHouseError("Request body must be JSON", {
432
+ status: 400,
433
+ code: "invalid_request"
434
+ });
435
+ }
436
+ if (body === null || typeof body !== "object" || Array.isArray(body)) {
437
+ throw new PmtHouseError("Request body must be a JSON object", {
438
+ status: 400,
439
+ code: "invalid_request"
440
+ });
441
+ }
442
+ const record = body;
443
+ const apiKeyRaw = record.apiKey;
444
+ if (typeof apiKeyRaw !== "string" || !apiKeyRaw.trim()) {
445
+ throw new PmtHouseError("Request body must include apiKey", {
446
+ status: 400,
447
+ code: "invalid_request"
448
+ });
449
+ }
450
+ const scope = typeof record.scope === "string" && record.scope.trim() ? record.scope.trim() : void 0;
451
+ const clientId = typeof record.clientId === "string" && record.clientId.trim() ? record.clientId.trim() : void 0;
452
+ return { apiKey: apiKeyRaw.trim(), scope, clientId };
453
+ }
454
+ async function mintUserAccessTokenFromApiKey(input) {
455
+ const fetchImpl = input.fetch ?? fetch;
456
+ const issuerOrigin = stripIssuerOriginFromOidcUrl(input.issuerUrl);
457
+ const url = `${issuerOrigin}/api/v1/apps/${encodeURIComponent(input.publicClientId)}/auth/api-key/token`;
458
+ const response = await fetchImpl(url, {
459
+ method: "POST",
460
+ headers: {
461
+ Authorization: `Bearer ${input.apiKey}`,
462
+ "Content-Type": "application/json",
463
+ Accept: "application/json"
464
+ },
465
+ body: JSON.stringify(input.scope ? { scope: input.scope } : {}),
466
+ cache: "no-store"
467
+ });
468
+ const parsed = await readJsonObjectFromResponse(response, {
469
+ invalidJsonMessage: "API key token exchange returned invalid JSON",
470
+ invalidJsonCode: "invalid_token_response",
471
+ failureLabel: "API key token exchange failed",
472
+ defaultErrorCode: "api_key_token_exchange_failed"
473
+ });
474
+ const accessToken = parsed.access_token;
475
+ if (typeof accessToken !== "string" || !accessToken.trim()) {
476
+ throw new PmtHouseError("API key token exchange missing access_token", {
477
+ status: 502,
478
+ code: EXCHANGE_RESPONSE_ERROR2
479
+ });
480
+ }
481
+ const expiresIn = typeof parsed.expires_in === "number" && Number.isFinite(parsed.expires_in) ? parsed.expires_in : 900;
482
+ const scope = typeof parsed.scope === "string" && parsed.scope.trim() ? parsed.scope.trim() : input.scope?.trim() || "sign:job";
483
+ return {
484
+ access_token: accessToken.trim(),
485
+ expires_in: expiresIn,
486
+ scope
487
+ };
488
+ }
489
+ async function mintSignerSessionFromApiKey(input) {
490
+ const userToken = await mintUserAccessTokenFromApiKey({
491
+ issuerUrl: input.issuerUrl,
492
+ publicClientId: input.publicClientId,
493
+ apiKey: input.apiKey,
494
+ scope: input.scope,
495
+ fetch: input.fetch
496
+ });
497
+ return mintSignerTokenFromDeviceToken({
498
+ issuerUrl: input.issuerUrl,
499
+ m2mClientId: input.m2mClientId,
500
+ m2mClientSecret: input.m2mClientSecret,
501
+ deviceToken: userToken.access_token,
502
+ scope: userToken.scope,
503
+ audience: input.audience,
504
+ fetch: input.fetch,
505
+ allowInsecureHttp: input.allowInsecureHttp
506
+ });
507
+ }
508
+ async function exchangeApiKeyForSigner(options) {
509
+ const fetchImpl = options.fetch ?? fetch;
510
+ const url = `${stripTrailingSlashes(options.facadeUrl)}/api/pymthouse/keys/exchange`;
511
+ const body = { apiKey: options.apiKey };
512
+ if (options.scope?.trim()) {
513
+ body.scope = options.scope.trim();
514
+ }
515
+ if (options.clientId?.trim()) {
516
+ body.clientId = options.clientId.trim();
517
+ }
518
+ const response = await fetchImpl(url, {
519
+ method: "POST",
520
+ headers: {
521
+ "Content-Type": "application/json",
522
+ Accept: "application/json"
523
+ },
524
+ body: JSON.stringify(body),
525
+ cache: "no-store"
526
+ });
527
+ const parsed = await readJsonObjectFromResponse(response, {
528
+ invalidJsonMessage: "API key exchange returned invalid JSON",
529
+ invalidJsonCode: EXCHANGE_RESPONSE_ERROR2,
530
+ failureLabel: "API key exchange failed",
531
+ defaultErrorCode: "api_key_exchange_failed"
532
+ });
533
+ const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
534
+ const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
535
+ const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
536
+ return normalizeDeviceExchangeResponse(
537
+ {
538
+ access_token: accessToken,
539
+ expires_in: typeof parsed.expires_in === "number" && Number.isFinite(parsed.expires_in) ? parsed.expires_in : 3600,
540
+ scope: typeof parsed.scope === "string" && parsed.scope.trim() ? parsed.scope.trim() : "sign:job",
541
+ balanceUsdMicros: typeof parsed.balanceUsdMicros === "string" ? parsed.balanceUsdMicros : "0",
542
+ lifetimeGrantedUsdMicros: typeof parsed.lifetimeGrantedUsdMicros === "string" ? parsed.lifetimeGrantedUsdMicros : "0"
543
+ },
544
+ { signerUrl }
545
+ );
546
+ }
547
+ function createApiKeyExchangeHandler(config) {
548
+ const publicClientId = config.publicClientId.trim();
549
+ return async function apiKeyExchangeHandler(request) {
550
+ try {
551
+ if (request.method !== "POST") {
552
+ return new Response(JSON.stringify({ error: "method_not_allowed" }), {
553
+ status: 405,
554
+ headers: { "Content-Type": "application/json" }
555
+ });
556
+ }
557
+ const parsed = await parseApiKeyExchangeRequestBody(request);
558
+ const effectiveClientId = parsed.clientId?.trim() || publicClientId;
559
+ if (effectiveClientId !== publicClientId) {
560
+ throw new PmtHouseError("clientId does not match configured public client", {
561
+ status: 400,
562
+ code: "invalid_request"
563
+ });
564
+ }
565
+ const minted = await mintSignerSessionFromApiKey({
566
+ issuerUrl: config.issuerUrl,
567
+ publicClientId,
568
+ m2mClientId: config.m2mClientId,
569
+ m2mClientSecret: config.m2mClientSecret,
570
+ apiKey: parsed.apiKey,
571
+ scope: parsed.scope,
572
+ audience: config.audience,
573
+ fetch: config.fetch,
574
+ allowInsecureHttp: config.allowInsecureHttp
575
+ });
576
+ const signerUrlValue = typeof config.signerUrl === "string" && config.signerUrl.trim() ? config.signerUrl.trim() : void 0;
577
+ const body = normalizeDeviceExchangeResponse(minted, { signerUrl: signerUrlValue });
578
+ return new Response(JSON.stringify(body), {
579
+ status: 200,
580
+ headers: {
581
+ "Content-Type": "application/json",
582
+ "Cache-Control": "no-store"
583
+ }
584
+ });
585
+ } catch (error) {
586
+ return signerHandlerErrorResponse(error);
587
+ }
588
+ };
589
+ }
590
+ var EXCHANGE_RESPONSE_ERROR2;
591
+ var init_api_key_exchange = __esm({
592
+ "src/signer/api-key-exchange.ts"() {
593
+ init_string_utils();
594
+ init_errors();
595
+ init_fetch_json();
596
+ init_handler_errors();
597
+ init_device_exchange();
598
+ EXCHANGE_RESPONSE_ERROR2 = "invalid_exchange_response";
599
+ }
600
+ });
601
+
602
+ // src/client.ts
603
+ init_encoding();
604
+ init_discovery();
605
+ init_errors();
125
606
  function parseAppManifestResponse(json) {
126
607
  if (!json || typeof json !== "object" || Array.isArray(json)) {
127
608
  return { capabilities: [], excludedCapabilities: [] };
@@ -139,6 +620,9 @@ function parseCapabilityArray(raw) {
139
620
  );
140
621
  }
141
622
 
623
+ // src/client.ts
624
+ init_string_utils();
625
+
142
626
  // src/tokens.ts
143
627
  var SIGNER_SESSION_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
144
628
  var SIGNER_SESSION_EXPIRES_IN_SEC = Math.floor(SIGNER_SESSION_TTL_MS / 1e3);
@@ -232,24 +716,27 @@ function mergeUsageByPipelineModel(usagePipelineModels) {
232
716
  const key = JSON.stringify([pipeline, modelId]);
233
717
  const existing = byKey.get(key);
234
718
  const rowCurrency = row.currency ?? "USD";
719
+ const networkFee = row.networkFeeUsdMicros ?? "0";
720
+ const ownerCharge = row.ownerChargeUsdMicros ?? "0";
721
+ const endUserBillable = row.endUserBillableUsdMicros ?? "0";
235
722
  if (!existing) {
236
723
  byKey.set(key, {
237
724
  pipeline,
238
725
  modelId,
239
726
  requestCount: row.requestCount,
240
727
  currency: rowCurrency,
241
- networkFeeUsdMicros: row.networkFeeUsdMicros,
242
- ownerChargeUsdMicros: row.ownerChargeUsdMicros,
243
- endUserBillableUsdMicros: row.endUserBillableUsdMicros
728
+ networkFeeUsdMicros: networkFee,
729
+ ownerChargeUsdMicros: ownerCharge,
730
+ endUserBillableUsdMicros: endUserBillable
244
731
  });
245
732
  continue;
246
733
  }
247
734
  byKey.set(key, {
248
735
  ...existing,
249
736
  requestCount: existing.requestCount + row.requestCount,
250
- networkFeeUsdMicros: (parseSafeBigInt(existing.networkFeeUsdMicros) + parseSafeBigInt(row.networkFeeUsdMicros)).toString(),
251
- ownerChargeUsdMicros: (parseSafeBigInt(existing.ownerChargeUsdMicros) + parseSafeBigInt(row.ownerChargeUsdMicros)).toString(),
252
- endUserBillableUsdMicros: (parseSafeBigInt(existing.endUserBillableUsdMicros) + parseSafeBigInt(row.endUserBillableUsdMicros)).toString()
737
+ networkFeeUsdMicros: (parseSafeBigInt(existing.networkFeeUsdMicros) + parseSafeBigInt(networkFee)).toString(),
738
+ ownerChargeUsdMicros: (parseSafeBigInt(existing.ownerChargeUsdMicros) + parseSafeBigInt(ownerCharge)).toString(),
739
+ endUserBillableUsdMicros: (parseSafeBigInt(existing.endUserBillableUsdMicros) + parseSafeBigInt(endUserBillable)).toString()
253
740
  });
254
741
  }
255
742
  }
@@ -258,9 +745,10 @@ function mergeUsageByPipelineModel(usagePipelineModels) {
258
745
  return a.pipeline.localeCompare(b.pipeline);
259
746
  });
260
747
  }
261
- function buildMeScopeUsagePayload(usageByUser, externalUserId, usagePipelineModel) {
748
+ function buildMeScopeUsagePayload(usageByUser, externalUserId, usagePipelineModel, usageDaily) {
262
749
  const summary = summarizeUsageFiatForExternalUser(usageByUser, externalUserId);
263
750
  const pipelineModels = mergeUsageByPipelineModel(usagePipelineModel);
751
+ const dailyByPipeline = usageDaily?.byDailyPipeline ?? [];
264
752
  return {
265
753
  clientId: usageByUser.clientId,
266
754
  period: usageByUser.period,
@@ -271,11 +759,15 @@ function buildMeScopeUsagePayload(usageByUser, externalUserId, usagePipelineMode
271
759
  networkFeeUsdMicros: summary.networkFeeUsdMicros,
272
760
  ownerChargeUsdMicros: summary.ownerChargeUsdMicros,
273
761
  endUserBillableUsdMicros: summary.endUserBillableUsdMicros,
274
- pipelineModels
762
+ pipelineModels,
763
+ dailyByPipeline
275
764
  }
276
765
  };
277
766
  }
278
767
  var DEFAULT_MAX_END_USER_IDS = 25;
768
+
769
+ // src/oauth-map.ts
770
+ init_errors();
279
771
  var ACCEPTED_ISSUED_TOKEN_TYPES = /* @__PURE__ */ new Set([
280
772
  "urn:ietf:params:oauth:token-type:access_token",
281
773
  "urn:pmth:token-type:remote-signer-session"
@@ -368,9 +860,94 @@ function m2mClient(clientId) {
368
860
  return { client_id: clientId };
369
861
  }
370
862
 
863
+ // src/ingest.ts
864
+ init_encoding();
865
+ init_errors();
866
+ init_string_utils();
867
+ function ingestUrl(issuerUrl, publicClientId) {
868
+ const origin = new URL(stripTrailingSlashes(issuerUrl)).origin;
869
+ return `${origin}/api/v1/apps/${encodeURIComponent(publicClientId)}/usage/signed-tickets`;
870
+ }
871
+ async function readJsonResponse(response) {
872
+ const text = await response.text();
873
+ if (!text.trim()) {
874
+ return {};
875
+ }
876
+ try {
877
+ const parsed = JSON.parse(text);
878
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
879
+ } catch {
880
+ return {};
881
+ }
882
+ }
883
+ async function ingestSignedTicket(options) {
884
+ const fetchImpl = options.fetch ?? fetch;
885
+ const url = ingestUrl(options.issuerUrl, options.publicClientId);
886
+ const response = await fetchImpl(url, {
887
+ method: "POST",
888
+ headers: {
889
+ Authorization: encodeClientSecretBasic(options.m2mClientId, options.m2mClientSecret),
890
+ "Content-Type": "application/json",
891
+ Accept: "application/json"
892
+ },
893
+ body: JSON.stringify(options.ticket),
894
+ cache: "no-store"
895
+ });
896
+ const body = await readJsonResponse(response);
897
+ if (!response.ok) {
898
+ const message = typeof body.error === "string" ? body.error : `Signed-ticket ingest failed (${response.status})`;
899
+ throw new PmtHouseError(message, {
900
+ status: response.status,
901
+ code: "ingest_failed",
902
+ details: body
903
+ });
904
+ }
905
+ return {
906
+ ingested: Boolean(body.ingested),
907
+ duplicate: Boolean(body.duplicate),
908
+ source: body.source === "openmeter" ? "openmeter" : "disabled"
909
+ };
910
+ }
911
+ async function ingestSignedTicketsBatch(options) {
912
+ const fetchImpl = options.fetch ?? fetch;
913
+ const url = ingestUrl(options.issuerUrl, options.publicClientId);
914
+ const response = await fetchImpl(url, {
915
+ method: "POST",
916
+ headers: {
917
+ Authorization: encodeClientSecretBasic(options.m2mClientId, options.m2mClientSecret),
918
+ "Content-Type": "application/json",
919
+ Accept: "application/json"
920
+ },
921
+ body: JSON.stringify({ tickets: options.tickets }),
922
+ cache: "no-store"
923
+ });
924
+ const body = await readJsonResponse(response);
925
+ if (!response.ok) {
926
+ const message = typeof body.error === "string" ? body.error : `Signed-ticket batch ingest failed (${response.status})`;
927
+ throw new PmtHouseError(message, {
928
+ status: response.status,
929
+ code: "ingest_failed",
930
+ details: body
931
+ });
932
+ }
933
+ const rawResults = Array.isArray(body.results) ? body.results : [];
934
+ return {
935
+ results: rawResults.map((entry) => {
936
+ const row = entry ?? {};
937
+ return {
938
+ requestId: typeof row.requestId === "string" ? row.requestId : void 0,
939
+ ok: row.ok === true,
940
+ ingested: Boolean(row.ingested),
941
+ duplicate: Boolean(row.duplicate),
942
+ source: row.source === "openmeter" ? "openmeter" : "disabled"
943
+ };
944
+ })
945
+ };
946
+ }
947
+
371
948
  // src/client.ts
372
- var TOKEN_EXCHANGE_GRANT = "urn:ietf:params:oauth:grant-type:token-exchange";
373
- var SUBJECT_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
949
+ var TOKEN_EXCHANGE_GRANT2 = "urn:ietf:params:oauth:grant-type:token-exchange";
950
+ var SUBJECT_ACCESS_TOKEN_TYPE2 = "urn:ietf:params:oauth:token-type:access_token";
374
951
  var REQUESTED_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
375
952
  var DEVICE_RESOURCE_PREFIX = "urn:pmth:device_code:";
376
953
  function normalizeUserCode(value) {
@@ -497,6 +1074,50 @@ var PmtHouseClient = class {
497
1074
  cache: "no-store"
498
1075
  });
499
1076
  }
1077
+ /**
1078
+ * Exchange a long-lived dashboard API key (`pmth_*`) for a short-lived user JWT.
1079
+ */
1080
+ async exchangeApiKeyForUserAccessToken(input) {
1081
+ const url = `${this.getAppsBaseUrl()}/auth/api-key/token`;
1082
+ return this.requestJson(url, {
1083
+ method: "POST",
1084
+ headers: {
1085
+ Authorization: `Bearer ${input.apiKey.trim()}`,
1086
+ "Content-Type": "application/json",
1087
+ Accept: "application/json"
1088
+ },
1089
+ body: JSON.stringify(input.scope ? { scope: input.scope } : {}),
1090
+ cache: "no-store"
1091
+ });
1092
+ }
1093
+ /**
1094
+ * Exchange a dashboard API key for a signer session via a trusted facade (recommended)
1095
+ * or directly when M2M credentials are available on this client.
1096
+ */
1097
+ async exchangeApiKeyForSignerSession(input) {
1098
+ if (input.facadeUrl?.trim()) {
1099
+ const { exchangeApiKeyForSigner: exchangeApiKeyForSigner2 } = await Promise.resolve().then(() => (init_api_key_exchange(), api_key_exchange_exports));
1100
+ const exchanged = await exchangeApiKeyForSigner2({
1101
+ facadeUrl: input.facadeUrl.trim(),
1102
+ apiKey: input.apiKey,
1103
+ scope: input.scope,
1104
+ clientId: this.publicClientId,
1105
+ fetch: this.fetchImpl
1106
+ });
1107
+ return {
1108
+ access_token: exchanged.access_token,
1109
+ token_type: exchanged.token_type,
1110
+ expires_in: exchanged.expires_in,
1111
+ scope: exchanged.scope,
1112
+ issued_token_type: "urn:ietf:params:oauth:token-type:access_token"
1113
+ };
1114
+ }
1115
+ const userToken = await this.exchangeApiKeyForUserAccessToken({
1116
+ apiKey: input.apiKey,
1117
+ scope: input.scope
1118
+ });
1119
+ return this.exchangeForSignerSession({ userJwt: userToken.access_token });
1120
+ }
500
1121
  async completeDeviceApproval(input) {
501
1122
  const as = await loadAuthorizationServer(this.issuerUrl, this.fetchImpl, {
502
1123
  allowInsecureHttp: this.allowInsecureHttp
@@ -505,14 +1126,14 @@ var PmtHouseClient = class {
505
1126
  const clientAuth = this.m2mClientAuth();
506
1127
  const params = new URLSearchParams();
507
1128
  params.set("subject_token", input.userJwt);
508
- params.set("subject_token_type", SUBJECT_ACCESS_TOKEN_TYPE);
1129
+ params.set("subject_token_type", SUBJECT_ACCESS_TOKEN_TYPE2);
509
1130
  params.set("resource", buildDeviceCodeResource(input.userCode));
510
1131
  try {
511
1132
  const response = await genericTokenEndpointRequest(
512
1133
  as,
513
1134
  client,
514
1135
  clientAuth,
515
- TOKEN_EXCHANGE_GRANT,
1136
+ TOKEN_EXCHANGE_GRANT2,
516
1137
  params,
517
1138
  this.tokenEndpointFetchOptions()
518
1139
  );
@@ -560,7 +1181,7 @@ var PmtHouseClient = class {
560
1181
  const clientAuth = this.m2mClientAuth();
561
1182
  const params = new URLSearchParams();
562
1183
  params.set("subject_token", input.userJwt);
563
- params.set("subject_token_type", SUBJECT_ACCESS_TOKEN_TYPE);
1184
+ params.set("subject_token_type", SUBJECT_ACCESS_TOKEN_TYPE2);
564
1185
  params.set("requested_token_type", REQUESTED_ACCESS_TOKEN_TYPE);
565
1186
  const resourceCandidate = typeof input.resource === "string" && input.resource.trim() !== "" ? input.resource.trim() : this.issuerUrl;
566
1187
  params.set("resource", stripTrailingSlashes(resourceCandidate));
@@ -569,7 +1190,7 @@ var PmtHouseClient = class {
569
1190
  as,
570
1191
  client,
571
1192
  clientAuth,
572
- TOKEN_EXCHANGE_GRANT,
1193
+ TOKEN_EXCHANGE_GRANT2,
573
1194
  params,
574
1195
  this.tokenEndpointFetchOptions()
575
1196
  );
@@ -625,6 +1246,7 @@ var PmtHouseClient = class {
625
1246
  if (input.groupBy) url.searchParams.set("groupBy", input.groupBy);
626
1247
  if (input.userId) url.searchParams.set("userId", input.userId);
627
1248
  if (input.gatewayRequestId) url.searchParams.set("gatewayRequestId", input.gatewayRequestId);
1249
+ if (input.includeRetail) url.searchParams.set("include", "retail");
628
1250
  return this.requestJson(url.toString(), {
629
1251
  method: "GET",
630
1252
  headers: this.builderHeaders(),
@@ -634,6 +1256,129 @@ var PmtHouseClient = class {
634
1256
  /**
635
1257
  * Session-scoped usage for one `externalUserId`: user rollup plus merged pipeline/model breakdown.
636
1258
  */
1259
+ async ingestSignedTicket(ticket) {
1260
+ return ingestSignedTicket({
1261
+ issuerUrl: this.issuerUrl,
1262
+ publicClientId: this.publicClientId,
1263
+ m2mClientId: this.m2mClientId,
1264
+ m2mClientSecret: this.m2mClientSecret,
1265
+ ticket,
1266
+ fetch: this.fetchImpl
1267
+ });
1268
+ }
1269
+ async ingestSignedTickets(tickets) {
1270
+ return ingestSignedTicketsBatch({
1271
+ issuerUrl: this.issuerUrl,
1272
+ publicClientId: this.publicClientId,
1273
+ m2mClientId: this.m2mClientId,
1274
+ m2mClientSecret: this.m2mClientSecret,
1275
+ tickets,
1276
+ fetch: this.fetchImpl
1277
+ });
1278
+ }
1279
+ async getSignerRouting() {
1280
+ return this.requestJson(
1281
+ `${this.getAppsBaseUrl()}/signer/routing`,
1282
+ {
1283
+ method: "GET",
1284
+ headers: this.builderHeaders(),
1285
+ cache: "no-store"
1286
+ }
1287
+ );
1288
+ }
1289
+ async listBillingProducts() {
1290
+ const url = `${this.getAppsBaseUrl()}/plans?apiVersion=2`;
1291
+ const body = await this.requestJson(
1292
+ url,
1293
+ {
1294
+ method: "GET",
1295
+ headers: this.builderHeaders(),
1296
+ cache: "no-store"
1297
+ }
1298
+ );
1299
+ return {
1300
+ apiVersion: body.apiVersion ?? 2,
1301
+ products: body.products ?? body.plans ?? []
1302
+ };
1303
+ }
1304
+ async syncBillingProduct(planId) {
1305
+ return this.requestJson(
1306
+ `${this.getAppsBaseUrl()}/plans/${encodeURIComponent(planId)}/sync`,
1307
+ {
1308
+ method: "POST",
1309
+ headers: this.builderHeaders(),
1310
+ cache: "no-store"
1311
+ }
1312
+ );
1313
+ }
1314
+ async getUsageBalance(externalUserId) {
1315
+ const url = new URL(`${this.getAppsBaseUrl()}/usage/balance`);
1316
+ url.searchParams.set("externalUserId", externalUserId);
1317
+ return this.requestJson(url.toString(), {
1318
+ method: "GET",
1319
+ headers: this.builderHeaders(),
1320
+ cache: "no-store"
1321
+ });
1322
+ }
1323
+ async getUserAllowances(externalUserId) {
1324
+ return this.requestJson(
1325
+ `${this.getAppsBaseUrl()}/users/${encodeURIComponent(externalUserId)}/allowances`,
1326
+ {
1327
+ method: "GET",
1328
+ headers: this.builderHeaders(),
1329
+ cache: "no-store"
1330
+ }
1331
+ );
1332
+ }
1333
+ async grantUserAllowance(externalUserId, input) {
1334
+ return this.requestJson(
1335
+ `${this.getAppsBaseUrl()}/users/${encodeURIComponent(externalUserId)}/allowances`,
1336
+ {
1337
+ method: "POST",
1338
+ headers: this.builderHeaders(),
1339
+ body: JSON.stringify(input),
1340
+ cache: "no-store"
1341
+ }
1342
+ );
1343
+ }
1344
+ /**
1345
+ * @deprecated Removed from PymtHouse — use {@link getUsageBalance} or {@link getUserAllowances}.
1346
+ */
1347
+ async getUserCredits(externalUserId) {
1348
+ return this.getUsageBalance(externalUserId);
1349
+ }
1350
+ /**
1351
+ * @deprecated Removed from PymtHouse — use {@link grantUserAllowance} (`POST .../allowances`).
1352
+ */
1353
+ async grantUserCredits(externalUserId, input) {
1354
+ const result = await this.grantUserAllowance(externalUserId, {
1355
+ amountUsdMicros: input.amountUsdMicros,
1356
+ source: input.source ?? "manual",
1357
+ featureKey: input.featureKey
1358
+ });
1359
+ const flat = result;
1360
+ const nested = result.allowances;
1361
+ return {
1362
+ externalUserId: result.externalUserId,
1363
+ balanceUsdMicros: flat.balanceUsdMicros ?? nested?.balanceUsdMicros ?? "0",
1364
+ consumedUsdMicros: flat.consumedUsdMicros ?? nested?.consumedUsdMicros ?? "0",
1365
+ lifetimeGrantedUsdMicros: flat.lifetimeGrantedUsdMicros ?? nested?.lifetimeGrantedUsdMicros ?? "0",
1366
+ hasAccess: flat.hasAccess ?? nested?.hasAccess ?? false,
1367
+ remainingUsdMicros: flat.balanceUsdMicros ?? nested?.balanceUsdMicros,
1368
+ grantedUsdMicros: flat.grantedUsdMicros,
1369
+ featureKey: flat.featureKey
1370
+ };
1371
+ }
1372
+ async getUserSubscription(externalUserId) {
1373
+ return this.requestJson(
1374
+ `${this.getAppsBaseUrl()}/users/${encodeURIComponent(externalUserId)}/subscription`,
1375
+ {
1376
+ method: "GET",
1377
+ headers: this.builderHeaders(),
1378
+ cache: "no-store"
1379
+ }
1380
+ );
1381
+ }
637
1382
  async fetchUsageForExternalUser(input) {
638
1383
  const usageByUser = await this.getUsage({
639
1384
  startDate: input.startDate,
@@ -653,7 +1398,18 @@ var PmtHouseClient = class {
653
1398
  })
654
1399
  )
655
1400
  );
656
- return buildMeScopeUsagePayload(usageByUser, input.externalUserId, usagePipelineModels);
1401
+ const usageDaily = await this.getUsage({
1402
+ startDate: input.startDate,
1403
+ endDate: input.endDate,
1404
+ groupBy: "daily_pipeline",
1405
+ userId: input.externalUserId
1406
+ });
1407
+ return buildMeScopeUsagePayload(
1408
+ usageByUser,
1409
+ input.externalUserId,
1410
+ usagePipelineModels,
1411
+ usageDaily
1412
+ );
657
1413
  }
658
1414
  async getAppManifest(opts) {
659
1415
  const url = `${this.getAppsBaseUrl()}/manifest`;
@@ -844,6 +1600,8 @@ var PmtHouseClient = class {
844
1600
  };
845
1601
 
846
1602
  // src/env.ts
1603
+ init_errors();
1604
+ init_string_utils();
847
1605
  function assertEnvModuleServerOnly() {
848
1606
  if (typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined") {
849
1607
  throw new Error(