@geekmidas/constructs 10.0.0-alpha.118 → 10.0.0-alpha.119

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 (117) hide show
  1. package/dist/{Construct-BQALFCh2.d.cts → Construct-B7AXn0xH.d.mts} +7 -7
  2. package/dist/{Construct-BQALFCh2.d.cts.map → Construct-B7AXn0xH.d.mts.map} +1 -1
  3. package/dist/{Construct-QXnl3VqT.d.mts → Construct-CFW0zjdD.d.cts} +7 -7
  4. package/dist/{Construct-QXnl3VqT.d.mts.map → Construct-CFW0zjdD.d.cts.map} +1 -1
  5. package/dist/{Cron-CQJqqkhY.d.mts → Cron-bdGRSROY.d.cts} +7 -7
  6. package/dist/{Cron-CQJqqkhY.d.mts.map → Cron-bdGRSROY.d.cts.map} +1 -1
  7. package/dist/{Cron-DI3nKoic.d.cts → Cron-i4Uetezh.d.mts} +7 -7
  8. package/dist/{Cron-DI3nKoic.d.cts.map → Cron-i4Uetezh.d.mts.map} +1 -1
  9. package/dist/{CronBuilder-Xx_zakuc.d.mts → CronBuilder-9H4BnD6W.d.mts} +6 -6
  10. package/dist/{CronBuilder-Xx_zakuc.d.mts.map → CronBuilder-9H4BnD6W.d.mts.map} +1 -1
  11. package/dist/{CronBuilder-g1lZLWyG.d.cts → CronBuilder-B_24LZpn.d.cts} +6 -6
  12. package/dist/{CronBuilder-g1lZLWyG.d.cts.map → CronBuilder-B_24LZpn.d.cts.map} +1 -1
  13. package/dist/{Endpoint-CrE9Ppdk.d.mts → Endpoint-CeFkSwh5.d.mts} +5 -5
  14. package/dist/{Endpoint-BWyKCa2x.d.cts.map → Endpoint-CeFkSwh5.d.mts.map} +1 -1
  15. package/dist/{Endpoint-BWyKCa2x.d.cts → Endpoint-DgrpG15P.d.cts} +5 -5
  16. package/dist/{Endpoint-CrE9Ppdk.d.mts.map → Endpoint-DgrpG15P.d.cts.map} +1 -1
  17. package/dist/{EndpointFactory-BVv6EIDu.cjs → EndpointFactory-CSrAyazj.cjs} +264 -1
  18. package/dist/EndpointFactory-CSrAyazj.cjs.map +1 -0
  19. package/dist/{EndpointFactory-C1-IBwm4.d.cts → EndpointFactory-Cc863XJS.d.cts} +111 -6
  20. package/dist/EndpointFactory-Cc863XJS.d.cts.map +1 -0
  21. package/dist/{EndpointFactory-BV-nfnaP.d.mts → EndpointFactory-Dbw9ugkX.d.mts} +111 -6
  22. package/dist/EndpointFactory-Dbw9ugkX.d.mts.map +1 -0
  23. package/dist/{EndpointFactory-Cs8IHvwF.mjs → EndpointFactory-c2ZugGig.mjs} +223 -2
  24. package/dist/EndpointFactory-c2ZugGig.mjs.map +1 -0
  25. package/dist/{Function-DuqGcbOI.d.mts → Function-B0uZhZnU.d.cts} +5 -5
  26. package/dist/{Function-DuqGcbOI.d.mts.map → Function-B0uZhZnU.d.cts.map} +1 -1
  27. package/dist/{Function-Pu-1kKZz.d.cts → Function-B_9R7Zy1.d.mts} +5 -5
  28. package/dist/{Function-Pu-1kKZz.d.cts.map → Function-B_9R7Zy1.d.mts.map} +1 -1
  29. package/dist/{Queue-DlsHRzUp.d.mts → Queue-B-dDXyjF.d.mts} +4 -4
  30. package/dist/{Queue-DlsHRzUp.d.mts.map → Queue-B-dDXyjF.d.mts.map} +1 -1
  31. package/dist/{Queue-HPyi0e1i.d.cts → Queue-JbIjVtTf.d.cts} +4 -4
  32. package/dist/{Queue-HPyi0e1i.d.cts.map → Queue-JbIjVtTf.d.cts.map} +1 -1
  33. package/dist/{QueueBuilder-Cx9lKC5d.d.mts → QueueBuilder-48W-q8In.d.mts} +3 -3
  34. package/dist/{QueueBuilder-Cx9lKC5d.d.mts.map → QueueBuilder-48W-q8In.d.mts.map} +1 -1
  35. package/dist/{QueueBuilder-OSi6LkV9.d.cts → QueueBuilder-MfpkJ3R9.d.cts} +3 -3
  36. package/dist/{QueueBuilder-OSi6LkV9.d.cts.map → QueueBuilder-MfpkJ3R9.d.cts.map} +1 -1
  37. package/dist/{Subscriber-Bpp02cGr.d.cts → Subscriber-CEt7kHkc.d.cts} +4 -4
  38. package/dist/{Subscriber-Bpp02cGr.d.cts.map → Subscriber-CEt7kHkc.d.cts.map} +1 -1
  39. package/dist/{Subscriber-CtN9R48-.d.mts → Subscriber-dsxc5LKa.d.mts} +4 -4
  40. package/dist/{Subscriber-CtN9R48-.d.mts.map → Subscriber-dsxc5LKa.d.mts.map} +1 -1
  41. package/dist/{SubscriberBuilder-g3fAVWgs.d.cts → SubscriberBuilder-BRa_nrmH.d.cts} +4 -4
  42. package/dist/{SubscriberBuilder-4DWe9feX.d.mts.map → SubscriberBuilder-BRa_nrmH.d.cts.map} +1 -1
  43. package/dist/{SubscriberBuilder-4DWe9feX.d.mts → SubscriberBuilder-D9bkrYzH.d.mts} +4 -4
  44. package/dist/{SubscriberBuilder-g3fAVWgs.d.cts.map → SubscriberBuilder-D9bkrYzH.d.mts.map} +1 -1
  45. package/dist/adaptors/aws.d.cts +6 -6
  46. package/dist/adaptors/aws.d.mts +6 -6
  47. package/dist/adaptors/hono.d.cts +2 -2
  48. package/dist/adaptors/hono.d.mts +2 -2
  49. package/dist/adaptors/testing.d.cts +6 -6
  50. package/dist/adaptors/testing.d.mts +6 -6
  51. package/dist/credential.d.cts +1 -1
  52. package/dist/credential.d.mts +1 -1
  53. package/dist/crons/index.d.cts +2 -2
  54. package/dist/crons/index.d.mts +2 -2
  55. package/dist/endpoints/index.cjs +8 -1
  56. package/dist/endpoints/index.d.cts +4 -4
  57. package/dist/endpoints/index.d.mts +4 -4
  58. package/dist/endpoints/index.mjs +2 -2
  59. package/dist/expire-C586zznE.d.cts +38 -0
  60. package/dist/expire-C586zznE.d.cts.map +1 -0
  61. package/dist/expire-C586zznE.d.mts +38 -0
  62. package/dist/expire-C586zznE.d.mts.map +1 -0
  63. package/dist/expire-CieftS01.cjs +67 -0
  64. package/dist/expire-CieftS01.cjs.map +1 -0
  65. package/dist/expire-CpzUAfr9.mjs +50 -0
  66. package/dist/expire-CpzUAfr9.mjs.map +1 -0
  67. package/dist/external-api.d.cts +1 -1
  68. package/dist/external-api.d.mts +1 -1
  69. package/dist/{fake-Dvion_Fh.d.cts → fake-B7rvi4Qp.d.cts} +2 -2
  70. package/dist/{fake-DqKo8INJ.d.mts.map → fake-B7rvi4Qp.d.cts.map} +1 -1
  71. package/dist/{fake-DqKo8INJ.d.mts → fake-JXbkdao8.d.mts} +2 -2
  72. package/dist/{fake-Dvion_Fh.d.cts.map → fake-JXbkdao8.d.mts.map} +1 -1
  73. package/dist/file-server.cjs +24 -1
  74. package/dist/file-server.cjs.map +1 -1
  75. package/dist/file-server.d.cts +19 -0
  76. package/dist/file-server.d.cts.map +1 -1
  77. package/dist/file-server.d.mts +19 -0
  78. package/dist/file-server.d.mts.map +1 -1
  79. package/dist/file-server.mjs +24 -2
  80. package/dist/file-server.mjs.map +1 -1
  81. package/dist/functions/index.d.cts +2 -2
  82. package/dist/functions/index.d.mts +2 -2
  83. package/dist/{index-BuzRvKOQ.d.cts → index-Cd2w-DRL.d.cts} +4 -4
  84. package/dist/{index-B13kQB_U.d.mts.map → index-Cd2w-DRL.d.cts.map} +1 -1
  85. package/dist/{index-CeEtxDmK.d.cts → index-DdRjYhiJ.d.cts} +42 -2
  86. package/dist/{index-CeEtxDmK.d.cts.map → index-DdRjYhiJ.d.cts.map} +1 -1
  87. package/dist/{index-CeEtxDmK.d.mts → index-DdRjYhiJ.d.mts} +42 -2
  88. package/dist/{index-CeEtxDmK.d.mts.map → index-DdRjYhiJ.d.mts.map} +1 -1
  89. package/dist/{index-B13kQB_U.d.mts → index-aBIcAiH5.d.mts} +4 -4
  90. package/dist/{index-BuzRvKOQ.d.cts.map → index-aBIcAiH5.d.mts.map} +1 -1
  91. package/dist/index.d.cts +1 -1
  92. package/dist/index.d.mts +1 -1
  93. package/dist/object-storage.cjs +8 -1
  94. package/dist/object-storage.cjs.map +1 -1
  95. package/dist/object-storage.d.cts +9 -0
  96. package/dist/object-storage.d.cts.map +1 -1
  97. package/dist/object-storage.d.mts +9 -0
  98. package/dist/object-storage.d.mts.map +1 -1
  99. package/dist/object-storage.mjs +7 -2
  100. package/dist/object-storage.mjs.map +1 -1
  101. package/dist/queue/index.d.cts +2 -2
  102. package/dist/queue/index.d.mts +2 -2
  103. package/dist/rest-api.cjs +1 -1
  104. package/dist/rest-api.d.cts +2 -2
  105. package/dist/rest-api.d.mts +2 -2
  106. package/dist/rest-api.mjs +1 -1
  107. package/dist/subscribers/index.d.cts +2 -2
  108. package/dist/subscribers/index.d.mts +2 -2
  109. package/dist/topic/index.d.cts +1 -1
  110. package/dist/topic/index.d.mts +1 -1
  111. package/dist/worker.d.cts +8 -8
  112. package/dist/worker.d.mts +8 -8
  113. package/package.json +31 -31
  114. package/dist/EndpointFactory-BV-nfnaP.d.mts.map +0 -1
  115. package/dist/EndpointFactory-BVv6EIDu.cjs.map +0 -1
  116. package/dist/EndpointFactory-C1-IBwm4.d.cts.map +0 -1
  117. package/dist/EndpointFactory-Cs8IHvwF.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { t as StandardSchemaV1 } from "./index-CeEtxDmK.mjs";
1
+ import { n as StandardSchemaV1 } from "./index-DdRjYhiJ.mjs";
2
2
  import { r as Consumable } from "./construct-interface-ZvYQbivO.mjs";
3
3
  import { n as DeployedStage, r as LocalStage } from "./stages-BSCF19o2.mjs";
4
4
  import { ConstructName, Declaration } from "@geekmidas/manifest";
@@ -198,4 +198,4 @@ declare const fake: {
198
198
  declare function isFake(value: unknown): value is Fake;
199
199
  //#endregion
200
200
  export { ExternalApi as a, Credential as c, decodeCredentials as d, readCredentials as f, isFake as i, CredentialOptions as l, FetchHandler as n, ExternalApiOptions as o, fake as r, ExternalApiUrl as s, Fake as t, MalformedCredential as u };
201
- //# sourceMappingURL=fake-DqKo8INJ.d.mts.map
201
+ //# sourceMappingURL=fake-JXbkdao8.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fake-Dvion_Fh.d.cts","names":["Value"],"sources":["../src/credential.ts","../src/external-api.ts","../src/fake.ts"],"mappings":";;;;;;;KAiEKA,QAAM,gBAAgB,oBAC1B,iBAAiB,YAAY;UAEb,kBAAkB,gBAAgB;;;;;;;;EAQlD,QAAQ;;;;;;;;;;EAUR;;cAGY,WACZ,+BACA,gBAAgB,mBAAmB,6BACvB,WAAW,OAAOA,QAAM;mBA6BlB;WApBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQA,QAAM;;;;;mBAMpC;;;;;;;;UAST;EAER,YACC,IAAI,cAAc,QACD,SAAS,kBAAkB;;;;;;;MAoBzC,qBAAqB;EAIzB,WAAW;UAUH;UAQA;;;;;;;;;;;iBAmBa,gBAAgB,gBAAgB,kBACrD,YACA,aACA,QAAQ,SACR,WAAW,sCACT,QAAQA,QAAM;;;;;;;;;;;iBAsBD,kBAAkB;;cAoBrB,4BAA4B;WAE9B;WACA;WACA;EAHV,YACU,YACA,aACA;;;;;KCpLN,MAAM,gBAAgB,oBAC1B,iBAAiB,YAAY;;;;;;;;;KAUlB,0CAEO,aAAa,gBAC3B,SAAS,sCACG,KAAK,aAAa;WACrB;;UAGG,mBAAmB,gBAAgB,kBAAkB;;;;;EAKrE,KAAK;;EAEL,aAAa;;EAEb,SAAS;IACR;IACA,aAAa,MAAM;QACd,UAAU,QAAQ;;cAGZ,YACZ,+BACA,gBAAgB,mBAAmB,kBACnC,8BACY,WAAW,OAAO;mBAeZ;WAXT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ;;mBAG9B;;UAGT;EAER,YACC,IAAI,cAAc,QACD,SAAS,mBAAmB,SAAS;;;;;;;MA0BnD,qBAAqB;EAIzB,WAAW;UAaG;;;;;;;;cCjHT;;UAGW;EAChB,MAAM,SAAS,UAAU,WAAW,QAAQ;;;;;;KAOxC,cAAc,cAClB,mBAAmB,0BAA0B,oBAC1C,iBAAiB,WAAW,WAC5B,mBAAmB,yBAAyB,WAC3C,iBAAiB,WAAW;;;;;;;;KAUrB;YACD;WACD;;WAGE;;WAEA,SAAS;;WAGT;;WAEA;;WAEA;;;WAIA;;;;;;;;cAUC;;EAEZ,IAAI,gBAAc,SACR,cAAY;IACV,aAAa,cAAc;MACpC;;EAUH,MAAM,gBAAc,eACN;IACF;IAAc,aAAa,cAAc;MAClD;;;;;;EAeH,WAAW,uBAAqB,aAClB,cAAc,eACzB;;;iBAMY,OAAO,iBAAiB,SAAS"}
1
+ {"version":3,"file":"fake-JXbkdao8.d.mts","names":["Value"],"sources":["../src/credential.ts","../src/external-api.ts","../src/fake.ts"],"mappings":";;;;;;;KAiEKA,QAAM,gBAAgB,oBAC1B,iBAAiB,YAAY;UAEb,kBAAkB,gBAAgB;;;;;;;;EAQlD,QAAQ;;;;;;;;;;EAUR;;cAGY,WACZ,+BACA,gBAAgB,mBAAmB,6BACvB,WAAW,OAAOA,QAAM;mBA6BlB;WApBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQA,QAAM;;;;;mBAMpC;;;;;;;;UAST;EAER,YACC,IAAI,cAAc,QACD,SAAS,kBAAkB;;;;;;;MAoBzC,qBAAqB;EAIzB,WAAW;UAUH;UAQA;;;;;;;;;;;iBAmBa,gBAAgB,gBAAgB,kBACrD,YACA,aACA,QAAQ,SACR,WAAW,sCACT,QAAQA,QAAM;;;;;;;;;;;iBAsBD,kBAAkB;;cAoBrB,4BAA4B;WAE9B;WACA;WACA;EAHV,YACU,YACA,aACA;;;;;KCpLN,MAAM,gBAAgB,oBAC1B,iBAAiB,YAAY;;;;;;;;;KAUlB,0CAEO,aAAa,gBAC3B,SAAS,sCACG,KAAK,aAAa;WACrB;;UAGG,mBAAmB,gBAAgB,kBAAkB;;;;;EAKrE,KAAK;;EAEL,aAAa;;EAEb,SAAS;IACR;IACA,aAAa,MAAM;QACd,UAAU,QAAQ;;cAGZ,YACZ,+BACA,gBAAgB,mBAAmB,kBACnC,8BACY,WAAW,OAAO;mBAeZ;WAXT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ;;mBAG9B;;UAGT;EAER,YACC,IAAI,cAAc,QACD,SAAS,mBAAmB,SAAS;;;;;;;MA0BnD,qBAAqB;EAIzB,WAAW;UAaG;;;;;;;;cCjHT;;UAGW;EAChB,MAAM,SAAS,UAAU,WAAW,QAAQ;;;;;;KAOxC,cAAc,cAClB,mBAAmB,0BAA0B,oBAC1C,iBAAiB,WAAW,WAC5B,mBAAmB,yBAAyB,WAC3C,iBAAiB,WAAW;;;;;;;;KAUrB;YACD;WACD;;WAGE;;WAEA,SAAS;;WAGT;;WAEA;;WAEA;;;WAIA;;;;;;;;cAUC;;EAEZ,IAAI,gBAAc,SACR,cAAY;IACV,aAAa,cAAc;MACpC;;EAUH,MAAM,gBAAc,eACN;IACF;IAAc,aAAa,cAAc;MAClD;;;;;;EAeH,WAAW,uBAAqB,aAClB,cAAc,eACzB;;;iBAMY,OAAO,iBAAiB,SAAS"}
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_expire = require("./expire-CieftS01.cjs");
2
3
  let _geekmidas_manifest = require("@geekmidas/manifest");
3
4
  let _geekmidas_storage = require("@geekmidas/storage");
4
5
  //#region src/file-server.ts
@@ -32,6 +33,22 @@ let _geekmidas_storage = require("@geekmidas/storage");
32
33
  * and naming the bucket after the construct makes that edit *add* a node rather
33
34
  * than rename the one holding the data.
34
35
  */
36
+ /**
37
+ * A bucket setting given to a file server that fronts a bucket declared
38
+ * elsewhere — where the bucket's own construct is the one that says it.
39
+ */
40
+ var BucketOptionOnOrigin = class extends Error {
41
+ server;
42
+ origin;
43
+ option;
44
+ constructor(server, origin, option) {
45
+ super(`'${server}' fronts '${origin}', which declares itself, so '${option}' belongs on the construct that declares '${origin}', not on the file server.`);
46
+ this.server = server;
47
+ this.origin = origin;
48
+ this.option = option;
49
+ this.name = "BucketOptionOnOrigin";
50
+ }
51
+ };
35
52
  /** A key was asked to be served unsigned, and no open pattern admits it. */
36
53
  var NotOpen = class extends Error {
37
54
  key;
@@ -50,6 +67,8 @@ var FileServer = class {
50
67
  /** The id of the surface node, as opposed to the bucket's. */
51
68
  surfaceId;
52
69
  open;
70
+ /** The vended bucket's expiry, checked once: prefix → days. */
71
+ expire;
53
72
  /**
54
73
  * Declared once and read by both `declare()` and `connect()`, so the keys the
55
74
  * target publishes and the keys the client reads cannot drift.
@@ -61,6 +80,8 @@ var FileServer = class {
61
80
  this.id = canonical;
62
81
  this.open = options.open ?? [];
63
82
  const originId = options.origin?.id ?? canonical;
83
+ if (options.origin && options.expire) throw new BucketOptionOnOrigin(canonical, originId, "expire");
84
+ this.expire = require_expire.expiryDays(canonical, options.expire);
64
85
  this.surfaceId = `${canonical}Server`;
65
86
  this.keys = {
66
87
  origin: (0, _geekmidas_manifest.provideKey)(originId, "url"),
@@ -115,7 +136,8 @@ var FileServer = class {
115
136
  kind: "objects",
116
137
  id: this.id,
117
138
  provides: [this.keys.origin],
118
- ...this.options.versioned ? { versioned: true } : {}
139
+ ...this.options.versioned ? { versioned: true } : {},
140
+ ...this.expire ? { expire: this.expire } : {}
119
141
  }, surface];
120
142
  }
121
143
  /**
@@ -180,6 +202,7 @@ function globToRegExp(pattern) {
180
202
  return new RegExp(`^${source}$`);
181
203
  }
182
204
  //#endregion
205
+ exports.BucketOptionOnOrigin = BucketOptionOnOrigin;
183
206
  exports.FileServer = FileServer;
184
207
  exports.NotOpen = NotOpen;
185
208
 
@@ -1 +1 @@
1
- {"version":3,"file":"file-server.cjs","names":["canonicalId","provideKey","serviceKey","createStorageClient"],"sources":["../src/file-server.ts"],"sourcesContent":["/**\n * `FileServer` — a domain that serves a bucket's objects.\n *\n * `ObjectStorage` is the bucket: it writes, it presigns, and its URL is never\n * public. Serving those objects on a domain is a different thing, and it is a\n * construct of its own rather than a flag on the bucket — see\n * `docs/design/constructs-paradigm.md`, \"Why a separate construct, and what it\n * costs\", for the comparison that rules the other two shapes out.\n *\n * ```ts\n * export const uploads = new FileServer('Uploads', { open: ['brand/**'] });\n *\n * uploads.getUploadURL({ path, contentType }) // an S3 presign at the bucket\n * uploads.url('brand/logo.png') // open path — no signature\n * uploads.signedUrl('invoices/7.pdf') // one object, one recipient\n * ```\n *\n * **One construct, one client, both halves.** How a file lands in the bucket is\n * the same whether or not it is served, so splitting the upload half from the\n * serving half would be ceremony rather than safety. The client is a *superset*\n * of `StorageClient`, made literal in the type, so anything taking\n * `services.uploads` keeps compiling when the construct behind it grows a\n * serving half.\n *\n * **The id names the bucket, not the surface.** This is the detail that has to\n * be right before anything ships, because getting it backwards is destructive:\n * the migration people actually perform is serving a bucket they already have,\n * and naming the bucket after the construct makes that edit *add* a node rather\n * than rename the one holding the data.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { createStorageClient, type StorageClient } from '@geekmidas/storage';\nimport type { Construct, Declarable } from './construct-interface';\n\n/**\n * A key an open pattern admits.\n *\n * The same template-literal trick `ConstructName` uses, so `open` is checked at\n * the call site rather than only at the edge:\n *\n * ```ts\n * files.url('brand/logo.png') // ok\n * files.url(`avatars/${id}.png`) // ok — a template literal still matches\n * files.url('invoices/7.pdf') // not assignable — never served unsigned\n * ```\n *\n * A single star and a double star resolve to the same type, stated rather than\n * discovered: a template literal cannot exclude `/`, so this is a prefix-and-\n * suffix guard while the *exact* pattern is enforced by the bucket policy, by\n * the cache behaviour, and by this construct's own runtime check. The type says\n * plausibly open; the infrastructure says definitely.\n */\nexport type Served<P extends string> = P extends `${infer Head}**`\n\t? `${Head}${string}`\n\t: P extends `${infer Head}*${infer Tail}`\n\t\t? `${Head}${string}${Tail}`\n\t\t: P;\n\n/** What consuming a file server hands you: a bucket client that also serves. */\nexport interface FileServerClient<TOpen extends string = never>\n\textends StorageClient {\n\t/**\n\t * The unsigned address of an open object.\n\t *\n\t * Compile-checked against the declared patterns, *and* checked again at\n\t * runtime — a JavaScript caller gets no compiler, and minting an unsigned\n\t * URL for a private object is a leak rather than a mistake.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\turl(key: Served<TOpen>): string;\n\n\t/**\n\t * The same thing for a key the compiler cannot see.\n\t *\n\t * A fully dynamic key does not type, which is correct and is also the case\n\t * people will hit — so the escape hatch is a named method rather than a\n\t * cast, and it runs the *same* runtime check rather than being a way around\n\t * it.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\topenUrl(key: string): string;\n\n\t/**\n\t * A signed address for one object and one recipient.\n\t *\n\t * Today this is an **S3 presign at the bucket**, which is what works\n\t * unchanged against MinIO locally and against S3 deployed. It is deliberately\n\t * not described as a CDN URL: CloudFront signing is a different mechanism,\n\t * with different keys, against a different host, and it needs key material\n\t * this construct does not yet declare.\n\t *\n\t * @param expiresIn - minutes, matching `getUploadURL`.\n\t */\n\tsignedUrl(key: string, expiresIn?: number): Promise<string>;\n}\n\nexport interface FileServerOptions<TOpen extends string = never> {\n\t/**\n\t * Paths served without a signature. Everything else needs one.\n\t *\n\t * Private by default: a bucket where forgetting a flag publishes user\n\t * uploads is the wrong default, so this is an exception list, and listing it\n\t * in code means exactly one set of paths is unauthenticated and it is\n\t * reviewable in a diff.\n\t *\n\t * Uploading is deliberately *not* restricted to these. Writing to a path\n\t * that happens to be open is ordinary; the only asymmetry worth enforcing is\n\t * that you cannot hand out an unsigned URL for something the server would\n\t * refuse to serve unsigned.\n\t */\n\topen?: readonly TOpen[];\n\t/** Keep previous versions of an object. */\n\tversioned?: boolean;\n\t/**\n\t * A bucket declared elsewhere, instead of one of this server's own.\n\t *\n\t * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that\n\t * already exists, which is also how the two edges come back when you want\n\t * them separately — a handler depending on the bucket writes, a handler\n\t * depending on the server mints URLs.\n\t */\n\torigin?: Declarable;\n}\n\n/** A key was asked to be served unsigned, and no open pattern admits it. */\nexport class NotOpen extends Error {\n\tconstructor(\n\t\treadonly key: string,\n\t\treadonly open: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${key}' is not served without a signature. ` +\n\t\t\t\t(open.length\n\t\t\t\t\t? `Open paths: ${open.join(', ')}. Use signedUrl() for anything else.`\n\t\t\t\t\t: 'This file server declares no open paths, so every object needs signedUrl().'),\n\t\t);\n\t\tthis.name = 'NotOpen';\n\t}\n}\n\nexport class FileServer<\n\tTName extends string = string,\n\tTOpen extends string = never,\n> implements Construct<TName, FileServerClient<TOpen>>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;\n\n\t/** The id of the surface node, as opposed to the bucket's. */\n\treadonly surfaceId: string;\n\n\tprivate readonly open: readonly string[];\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the client reads cannot drift.\n\t */\n\tprivate readonly keys: { origin: string; server: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: FileServerOptions<TOpen> = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.open = options.open ?? [];\n\n\t\t// The surface takes the suffix and the bucket keeps the plain id, which\n\t\t// is what makes \"serve a bucket I already have\" an edit that adds a node\n\t\t// instead of renaming the one holding the data.\n\t\tconst originId = options.origin?.id ?? canonical;\n\t\tthis.surfaceId = `${canonical}Server`;\n\n\t\tthis.keys = {\n\t\t\torigin: provideKey(originId, 'url'),\n\t\t\tserver: provideKey(this.surfaceId, 'url'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (registerOptions) => this.connect(registerOptions),\n\t\t};\n\t}\n\n\t/**\n\t * The served surface, as something an edge can point at.\n\t *\n\t * Depending on the `FileServer` itself points at the **bucket** — its\n\t * canonical node — which is right for a handler: it presigns and writes. But\n\t * a bucket's URL is never public, so a site depending on it gets nothing\n\t * inlined, which is correct and also useless.\n\t *\n\t * This is the other half: `.dependsOn([uploads.server])` points at the\n\t * surface, whose address *is* public, and is what puts\n\t * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape\n\t * `database.reader()` uses, and for the same reason — one construct owning\n\t * two addresses needs a way to name the second.\n\t */\n\tget server(): Declarable {\n\t\tconst surface = this.declare().find(\n\t\t\t(declaration) => declaration.id === this.surfaceId,\n\t\t);\n\n\t\treturn {\n\t\t\tid: this.surfaceId,\n\t\t\tdeclare: () => (surface ? [surface] : []),\n\t\t};\n\t}\n\n\t/**\n\t * The bucket and the surface over it — or just the surface, when the bucket\n\t * was declared elsewhere.\n\t *\n\t * The surface names its origin through `of`, which is what makes the\n\t * reference check work: an origin resolving to nothing is a build failure,\n\t * the same guarantee `assertDerivations` already gives a reader and a schema\n\t * tenant.\n\t */\n\tdeclare(): Declaration[] {\n\t\tconst origin = this.options.origin;\n\n\t\tconst surface: Declaration = {\n\t\t\tkind: 'file-server',\n\t\t\tid: this.surfaceId,\n\t\t\tof: origin?.id ?? this.id,\n\t\t\t...(this.open.length ? { open: this.open } : {}),\n\t\t\tprovides: [this.keys.server],\n\t\t};\n\n\t\t// A vended bucket is declared here; a given one already declares itself,\n\t\t// and declaring it twice is the duplication the whole model removes.\n\t\tif (origin) return [surface];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'objects',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.keys.origin],\n\t\t\t\t...(this.options.versioned ? { versioned: true } : {}),\n\t\t\t},\n\t\t\tsurface,\n\t\t];\n\t}\n\n\t/**\n\t * The bucket's client, with the serving half added.\n\t *\n\t * Both addresses are read here, which is also how the environment reaches a\n\t * handler: the sniffer records what this reads, so `.dependsOn([uploads])`\n\t * carries the bucket URL and the server URL without either being written\n\t * down beside the handler.\n\t */\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<FileServerClient<TOpen>> {\n\t\tconst { origin, server } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigin: get(this.keys.origin).string(),\n\t\t\t\tserver: get(this.keys.server).string(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tconst storage = createStorageClient(origin);\n\t\tconst base = server.replace(/\\/+$/, '');\n\n\t\tconst serve = (key: string): string => {\n\t\t\tif (!this.serves(key)) throw new NotOpen(key, this.open);\n\n\t\t\treturn `${base}/${key.replace(/^\\/+/, '')}`;\n\t\t};\n\n\t\t// Delegating rather than copying: the bucket half is whatever the driver\n\t\t// produced, including anything it grows later, and only the serving half\n\t\t// is added on top.\n\t\treturn Object.assign(Object.create(storage) as StorageClient, {\n\t\t\turl: serve as (key: Served<TOpen>) => string,\n\t\t\topenUrl: serve,\n\t\t\tsignedUrl: (key: string, expiresIn?: number) =>\n\t\t\t\tstorage.getDownloadURL({ path: key } as never, expiresIn),\n\t\t}) as FileServerClient<TOpen>;\n\t}\n\n\t/**\n\t * Whether an open pattern admits a key.\n\t *\n\t * The runtime half of {@link Served}, and stricter than it: here a single\n\t * star stops at a segment boundary and a double star does not, which is the\n\t * distinction a template-literal type cannot draw and the infrastructure\n\t * does.\n\t */\n\tprivate serves(key: string): boolean {\n\t\treturn this.open.some((pattern) => globToRegExp(pattern).test(key));\n\t}\n}\n\n/**\n * One open pattern as an anchored expression.\n *\n * A double star crosses `/`; a single star does not. Both are consumed in one\n * left-to-right pass rather than by substitution, so a pattern cannot be\n * rewritten into a placeholder that a later pass mistakes for literal text.\n */\nfunction globToRegExp(pattern: string): RegExp {\n\tlet source = '';\n\n\tfor (let index = 0; index < pattern.length; index++) {\n\t\tconst character = pattern[index];\n\n\t\tif (character !== '*') {\n\t\t\tsource += character?.replace(/[.+^${}()|[\\]\\\\?]/, '\\\\$&') ?? '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pattern[index + 1] === '*') {\n\t\t\tsource += '.*';\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsource += '[^/]*';\n\t}\n\n\treturn new RegExp(`^${source}$`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"file-server.cjs","names":["canonicalId","expiryDays","provideKey","serviceKey","createStorageClient"],"sources":["../src/file-server.ts"],"sourcesContent":["/**\n * `FileServer` — a domain that serves a bucket's objects.\n *\n * `ObjectStorage` is the bucket: it writes, it presigns, and its URL is never\n * public. Serving those objects on a domain is a different thing, and it is a\n * construct of its own rather than a flag on the bucket — see\n * `docs/design/constructs-paradigm.md`, \"Why a separate construct, and what it\n * costs\", for the comparison that rules the other two shapes out.\n *\n * ```ts\n * export const uploads = new FileServer('Uploads', { open: ['brand/**'] });\n *\n * uploads.getUploadURL({ path, contentType }) // an S3 presign at the bucket\n * uploads.url('brand/logo.png') // open path — no signature\n * uploads.signedUrl('invoices/7.pdf') // one object, one recipient\n * ```\n *\n * **One construct, one client, both halves.** How a file lands in the bucket is\n * the same whether or not it is served, so splitting the upload half from the\n * serving half would be ceremony rather than safety. The client is a *superset*\n * of `StorageClient`, made literal in the type, so anything taking\n * `services.uploads` keeps compiling when the construct behind it grows a\n * serving half.\n *\n * **The id names the bucket, not the surface.** This is the detail that has to\n * be right before anything ships, because getting it backwards is destructive:\n * the migration people actually perform is serving a bucket they already have,\n * and naming the bucket after the construct makes that edit *add* a node rather\n * than rename the one holding the data.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { createStorageClient, type StorageClient } from '@geekmidas/storage';\nimport type { Construct, Declarable } from './construct-interface';\nimport { expiryDays, type ObjectExpiry } from './expire';\n\n/**\n * A key an open pattern admits.\n *\n * The same template-literal trick `ConstructName` uses, so `open` is checked at\n * the call site rather than only at the edge:\n *\n * ```ts\n * files.url('brand/logo.png') // ok\n * files.url(`avatars/${id}.png`) // ok — a template literal still matches\n * files.url('invoices/7.pdf') // not assignable — never served unsigned\n * ```\n *\n * A single star and a double star resolve to the same type, stated rather than\n * discovered: a template literal cannot exclude `/`, so this is a prefix-and-\n * suffix guard while the *exact* pattern is enforced by the bucket policy, by\n * the cache behaviour, and by this construct's own runtime check. The type says\n * plausibly open; the infrastructure says definitely.\n */\nexport type Served<P extends string> = P extends `${infer Head}**`\n\t? `${Head}${string}`\n\t: P extends `${infer Head}*${infer Tail}`\n\t\t? `${Head}${string}${Tail}`\n\t\t: P;\n\n/** What consuming a file server hands you: a bucket client that also serves. */\nexport interface FileServerClient<TOpen extends string = never>\n\textends StorageClient {\n\t/**\n\t * The unsigned address of an open object.\n\t *\n\t * Compile-checked against the declared patterns, *and* checked again at\n\t * runtime — a JavaScript caller gets no compiler, and minting an unsigned\n\t * URL for a private object is a leak rather than a mistake.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\turl(key: Served<TOpen>): string;\n\n\t/**\n\t * The same thing for a key the compiler cannot see.\n\t *\n\t * A fully dynamic key does not type, which is correct and is also the case\n\t * people will hit — so the escape hatch is a named method rather than a\n\t * cast, and it runs the *same* runtime check rather than being a way around\n\t * it.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\topenUrl(key: string): string;\n\n\t/**\n\t * A signed address for one object and one recipient.\n\t *\n\t * Today this is an **S3 presign at the bucket**, which is what works\n\t * unchanged against MinIO locally and against S3 deployed. It is deliberately\n\t * not described as a CDN URL: CloudFront signing is a different mechanism,\n\t * with different keys, against a different host, and it needs key material\n\t * this construct does not yet declare.\n\t *\n\t * @param expiresIn - minutes, matching `getUploadURL`.\n\t */\n\tsignedUrl(key: string, expiresIn?: number): Promise<string>;\n}\n\nexport interface FileServerOptions<TOpen extends string = never> {\n\t/**\n\t * Paths served without a signature. Everything else needs one.\n\t *\n\t * Private by default: a bucket where forgetting a flag publishes user\n\t * uploads is the wrong default, so this is an exception list, and listing it\n\t * in code means exactly one set of paths is unauthenticated and it is\n\t * reviewable in a diff.\n\t *\n\t * Uploading is deliberately *not* restricted to these. Writing to a path\n\t * that happens to be open is ordinary; the only asymmetry worth enforcing is\n\t * that you cannot hand out an unsigned URL for something the server would\n\t * refuse to serve unsigned.\n\t */\n\topen?: readonly TOpen[];\n\t/** Keep previous versions of an object. */\n\tversioned?: boolean;\n\t/**\n\t * Delete the objects under each prefix this many days after they were\n\t * written — `{ 'previews/': { days: 7 } }`. A setting of the bucket this\n\t * server vends, so it cannot be given with `origin`.\n\t */\n\texpire?: ObjectExpiry;\n\t/**\n\t * A bucket declared elsewhere, instead of one of this server's own.\n\t *\n\t * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that\n\t * already exists, which is also how the two edges come back when you want\n\t * them separately — a handler depending on the bucket writes, a handler\n\t * depending on the server mints URLs.\n\t */\n\torigin?: Declarable;\n}\n\n/**\n * A bucket setting given to a file server that fronts a bucket declared\n * elsewhere — where the bucket's own construct is the one that says it.\n */\nexport class BucketOptionOnOrigin extends Error {\n\tconstructor(\n\t\treadonly server: string,\n\t\treadonly origin: string,\n\t\treadonly option: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${server}' fronts '${origin}', which declares itself, so '${option}' ` +\n\t\t\t\t`belongs on the construct that declares '${origin}', not on the file server.`,\n\t\t);\n\t\tthis.name = 'BucketOptionOnOrigin';\n\t}\n}\n\n/** A key was asked to be served unsigned, and no open pattern admits it. */\nexport class NotOpen extends Error {\n\tconstructor(\n\t\treadonly key: string,\n\t\treadonly open: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${key}' is not served without a signature. ` +\n\t\t\t\t(open.length\n\t\t\t\t\t? `Open paths: ${open.join(', ')}. Use signedUrl() for anything else.`\n\t\t\t\t\t: 'This file server declares no open paths, so every object needs signedUrl().'),\n\t\t);\n\t\tthis.name = 'NotOpen';\n\t}\n}\n\nexport class FileServer<\n\tTName extends string = string,\n\tTOpen extends string = never,\n> implements Construct<TName, FileServerClient<TOpen>>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;\n\n\t/** The id of the surface node, as opposed to the bucket's. */\n\treadonly surfaceId: string;\n\n\tprivate readonly open: readonly string[];\n\n\t/** The vended bucket's expiry, checked once: prefix → days. */\n\tprivate readonly expire: Record<string, number> | undefined;\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the client reads cannot drift.\n\t */\n\tprivate readonly keys: { origin: string; server: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: FileServerOptions<TOpen> = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.open = options.open ?? [];\n\n\t\t// The surface takes the suffix and the bucket keeps the plain id, which\n\t\t// is what makes \"serve a bucket I already have\" an edit that adds a node\n\t\t// instead of renaming the one holding the data.\n\t\tconst originId = options.origin?.id ?? canonical;\n\t\tif (options.origin && options.expire) {\n\t\t\tthrow new BucketOptionOnOrigin(canonical, originId, 'expire');\n\t\t}\n\t\tthis.expire = expiryDays(canonical, options.expire);\n\t\tthis.surfaceId = `${canonical}Server`;\n\n\t\tthis.keys = {\n\t\t\torigin: provideKey(originId, 'url'),\n\t\t\tserver: provideKey(this.surfaceId, 'url'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (registerOptions) => this.connect(registerOptions),\n\t\t};\n\t}\n\n\t/**\n\t * The served surface, as something an edge can point at.\n\t *\n\t * Depending on the `FileServer` itself points at the **bucket** — its\n\t * canonical node — which is right for a handler: it presigns and writes. But\n\t * a bucket's URL is never public, so a site depending on it gets nothing\n\t * inlined, which is correct and also useless.\n\t *\n\t * This is the other half: `.dependsOn([uploads.server])` points at the\n\t * surface, whose address *is* public, and is what puts\n\t * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape\n\t * `database.reader()` uses, and for the same reason — one construct owning\n\t * two addresses needs a way to name the second.\n\t */\n\tget server(): Declarable {\n\t\tconst surface = this.declare().find(\n\t\t\t(declaration) => declaration.id === this.surfaceId,\n\t\t);\n\n\t\treturn {\n\t\t\tid: this.surfaceId,\n\t\t\tdeclare: () => (surface ? [surface] : []),\n\t\t};\n\t}\n\n\t/**\n\t * The bucket and the surface over it — or just the surface, when the bucket\n\t * was declared elsewhere.\n\t *\n\t * The surface names its origin through `of`, which is what makes the\n\t * reference check work: an origin resolving to nothing is a build failure,\n\t * the same guarantee `assertDerivations` already gives a reader and a schema\n\t * tenant.\n\t */\n\tdeclare(): Declaration[] {\n\t\tconst origin = this.options.origin;\n\n\t\tconst surface: Declaration = {\n\t\t\tkind: 'file-server',\n\t\t\tid: this.surfaceId,\n\t\t\tof: origin?.id ?? this.id,\n\t\t\t...(this.open.length ? { open: this.open } : {}),\n\t\t\tprovides: [this.keys.server],\n\t\t};\n\n\t\t// A vended bucket is declared here; a given one already declares itself,\n\t\t// and declaring it twice is the duplication the whole model removes.\n\t\tif (origin) return [surface];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'objects',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.keys.origin],\n\t\t\t\t...(this.options.versioned ? { versioned: true } : {}),\n\t\t\t\t...(this.expire ? { expire: this.expire } : {}),\n\t\t\t},\n\t\t\tsurface,\n\t\t];\n\t}\n\n\t/**\n\t * The bucket's client, with the serving half added.\n\t *\n\t * Both addresses are read here, which is also how the environment reaches a\n\t * handler: the sniffer records what this reads, so `.dependsOn([uploads])`\n\t * carries the bucket URL and the server URL without either being written\n\t * down beside the handler.\n\t */\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<FileServerClient<TOpen>> {\n\t\tconst { origin, server } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigin: get(this.keys.origin).string(),\n\t\t\t\tserver: get(this.keys.server).string(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tconst storage = createStorageClient(origin);\n\t\tconst base = server.replace(/\\/+$/, '');\n\n\t\tconst serve = (key: string): string => {\n\t\t\tif (!this.serves(key)) throw new NotOpen(key, this.open);\n\n\t\t\treturn `${base}/${key.replace(/^\\/+/, '')}`;\n\t\t};\n\n\t\t// Delegating rather than copying: the bucket half is whatever the driver\n\t\t// produced, including anything it grows later, and only the serving half\n\t\t// is added on top.\n\t\treturn Object.assign(Object.create(storage) as StorageClient, {\n\t\t\turl: serve as (key: Served<TOpen>) => string,\n\t\t\topenUrl: serve,\n\t\t\tsignedUrl: (key: string, expiresIn?: number) =>\n\t\t\t\tstorage.getDownloadURL({ path: key } as never, expiresIn),\n\t\t}) as FileServerClient<TOpen>;\n\t}\n\n\t/**\n\t * Whether an open pattern admits a key.\n\t *\n\t * The runtime half of {@link Served}, and stricter than it: here a single\n\t * star stops at a segment boundary and a double star does not, which is the\n\t * distinction a template-literal type cannot draw and the infrastructure\n\t * does.\n\t */\n\tprivate serves(key: string): boolean {\n\t\treturn this.open.some((pattern) => globToRegExp(pattern).test(key));\n\t}\n}\n\n/**\n * One open pattern as an anchored expression.\n *\n * A double star crosses `/`; a single star does not. Both are consumed in one\n * left-to-right pass rather than by substitution, so a pattern cannot be\n * rewritten into a placeholder that a later pass mistakes for literal text.\n */\nfunction globToRegExp(pattern: string): RegExp {\n\tlet source = '';\n\n\tfor (let index = 0; index < pattern.length; index++) {\n\t\tconst character = pattern[index];\n\n\t\tif (character !== '*') {\n\t\t\tsource += character?.replace(/[.+^${}()|[\\]\\\\?]/, '\\\\$&') ?? '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pattern[index + 1] === '*') {\n\t\t\tsource += '.*';\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsource += '[^/]*';\n\t}\n\n\treturn new RegExp(`^${source}$`);\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { i as Declarable, n as Construct } from "./construct-interface-B1AfqRl4.cjs";
2
+ import { r as ObjectExpiry } from "./expire-C586zznE.cjs";
2
3
  import { Service } from "@geekmidas/services";
3
4
  import { ConstructName, Declaration } from "@geekmidas/manifest";
4
5
  import { StorageClient } from "@geekmidas/storage";
@@ -75,6 +76,12 @@ export interface FileServerOptions<TOpen extends string = never> {
75
76
  open?: readonly TOpen[];
76
77
  /** Keep previous versions of an object. */
77
78
  versioned?: boolean;
79
+ /**
80
+ * Delete the objects under each prefix this many days after they were
81
+ * written — `{ 'previews/': { days: 7 } }`. A setting of the bucket this
82
+ * server vends, so it cannot be given with `origin`.
83
+ */
84
+ expire?: ObjectExpiry;
78
85
  /**
79
86
  * A bucket declared elsewhere, instead of one of this server's own.
80
87
  *
@@ -85,6 +92,16 @@ export interface FileServerOptions<TOpen extends string = never> {
85
92
  */
86
93
  origin?: Declarable;
87
94
  }
95
+ /**
96
+ * A bucket setting given to a file server that fronts a bucket declared
97
+ * elsewhere — where the bucket's own construct is the one that says it.
98
+ */
99
+ export declare class BucketOptionOnOrigin extends Error {
100
+ readonly server: string;
101
+ readonly origin: string;
102
+ readonly option: string;
103
+ constructor(server: string, origin: string, option: string);
104
+ }
88
105
  /** A key was asked to be served unsigned, and no open pattern admits it. */
89
106
  export declare class NotOpen extends Error {
90
107
  readonly key: string;
@@ -98,6 +115,8 @@ export declare class FileServer<TName extends string = string, TOpen extends str
98
115
  /** The id of the surface node, as opposed to the bucket's. */
99
116
  readonly surfaceId: string;
100
117
  private readonly open;
118
+ /** The vended bucket's expiry, checked once: prefix → days. */
119
+ private readonly expire;
101
120
  /**
102
121
  * Declared once and read by both `declare()` and `connect()`, so the keys the
103
122
  * target publishes and the keys the client reads cannot drift.
@@ -1 +1 @@
1
- {"version":3,"file":"file-server.d.cts","names":[],"sources":["../src/file-server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;YA4DY,OAAO,oBAAoB,mBAAmB,cACpD,kBACH,mBAAmB,cAAc,YAC7B,gBAAgB,SACnB;;iBAGa,iBAAiB,sCACzB;;;;;;;;;;EAUR,IAAI,KAAK,OAAO;;;;;;;;;;;EAYhB,QAAQ;;;;;;;;;;;;EAaR,UAAU,aAAa,qBAAqB;;iBAG5B,kBAAkB;;;;;;;;;;;;;;EAclC,gBAAgB;;EAEhB;;;;;;;;;EASA,SAAS;;;qBAIG,gBAAgB;WAElB;WACA;EAFV,YACU,aACA;;qBAYE,WACZ,+BACA,yCACY,UAAU,OAAO,iBAAiB;mBAkB5B;WAhBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ,iBAAiB;;WAGvD;mBAEQ;;;;;mBAMA;EAEjB,YACC,IAAI,cAAc,QACD,UAAS,kBAAkB;;;;;;;;;;;;;;;MAuCzC,UAAU;;;;;;;;;;EAoBd,WAAW;;;;;;;;;UAkCG;;;;;;;;;UAsCN"}
1
+ {"version":3,"file":"file-server.d.cts","names":[],"sources":["../src/file-server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;YA6DY,OAAO,oBAAoB,mBAAmB,cACpD,kBACH,mBAAmB,cAAc,YAC7B,gBAAgB,SACnB;;iBAGa,iBAAiB,sCACzB;;;;;;;;;;EAUR,IAAI,KAAK,OAAO;;;;;;;;;;;EAYhB,QAAQ;;;;;;;;;;;;EAaR,UAAU,aAAa,qBAAqB;;iBAG5B,kBAAkB;;;;;;;;;;;;;;EAclC,gBAAgB;;EAEhB;;;;;;EAMA,SAAS;;;;;;;;;EAST,SAAS;;;;;;qBAOG,6BAA6B;WAE/B;WACA;WACA;EAHV,YACU,gBACA,gBACA;;;qBAWE,gBAAgB;WAElB;WACA;EAFV,YACU,aACA;;qBAYE,WACZ,+BACA,yCACY,UAAU,OAAO,iBAAiB;mBAqB5B;WAnBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ,iBAAiB;;WAGvD;mBAEQ;;mBAGA;;;;;mBAMA;EAEjB,YACC,IAAI,cAAc,QACD,UAAS,kBAAkB;;;;;;;;;;;;;;;MA2CzC,UAAU;;;;;;;;;;EAoBd,WAAW;;;;;;;;;UAmCG;;;;;;;;;UAsCN"}
@@ -1,4 +1,5 @@
1
1
  import { i as Declarable, n as Construct } from "./construct-interface-ZvYQbivO.mjs";
2
+ import { r as ObjectExpiry } from "./expire-C586zznE.mjs";
2
3
  import { ConstructName, Declaration } from "@geekmidas/manifest";
3
4
  import { StorageClient } from "@geekmidas/storage";
4
5
  import { Service } from "@geekmidas/services";
@@ -75,6 +76,12 @@ export interface FileServerOptions<TOpen extends string = never> {
75
76
  open?: readonly TOpen[];
76
77
  /** Keep previous versions of an object. */
77
78
  versioned?: boolean;
79
+ /**
80
+ * Delete the objects under each prefix this many days after they were
81
+ * written — `{ 'previews/': { days: 7 } }`. A setting of the bucket this
82
+ * server vends, so it cannot be given with `origin`.
83
+ */
84
+ expire?: ObjectExpiry;
78
85
  /**
79
86
  * A bucket declared elsewhere, instead of one of this server's own.
80
87
  *
@@ -85,6 +92,16 @@ export interface FileServerOptions<TOpen extends string = never> {
85
92
  */
86
93
  origin?: Declarable;
87
94
  }
95
+ /**
96
+ * A bucket setting given to a file server that fronts a bucket declared
97
+ * elsewhere — where the bucket's own construct is the one that says it.
98
+ */
99
+ export declare class BucketOptionOnOrigin extends Error {
100
+ readonly server: string;
101
+ readonly origin: string;
102
+ readonly option: string;
103
+ constructor(server: string, origin: string, option: string);
104
+ }
88
105
  /** A key was asked to be served unsigned, and no open pattern admits it. */
89
106
  export declare class NotOpen extends Error {
90
107
  readonly key: string;
@@ -98,6 +115,8 @@ export declare class FileServer<TName extends string = string, TOpen extends str
98
115
  /** The id of the surface node, as opposed to the bucket's. */
99
116
  readonly surfaceId: string;
100
117
  private readonly open;
118
+ /** The vended bucket's expiry, checked once: prefix → days. */
119
+ private readonly expire;
101
120
  /**
102
121
  * Declared once and read by both `declare()` and `connect()`, so the keys the
103
122
  * target publishes and the keys the client reads cannot drift.
@@ -1 +1 @@
1
- {"version":3,"file":"file-server.d.mts","names":[],"sources":["../src/file-server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;YA4DY,OAAO,oBAAoB,mBAAmB,cACpD,kBACH,mBAAmB,cAAc,YAC7B,gBAAgB,SACnB;;iBAGa,iBAAiB,sCACzB;;;;;;;;;;EAUR,IAAI,KAAK,OAAO;;;;;;;;;;;EAYhB,QAAQ;;;;;;;;;;;;EAaR,UAAU,aAAa,qBAAqB;;iBAG5B,kBAAkB;;;;;;;;;;;;;;EAclC,gBAAgB;;EAEhB;;;;;;;;;EASA,SAAS;;;qBAIG,gBAAgB;WAElB;WACA;EAFV,YACU,aACA;;qBAYE,WACZ,+BACA,yCACY,UAAU,OAAO,iBAAiB;mBAkB5B;WAhBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ,iBAAiB;;WAGvD;mBAEQ;;;;;mBAMA;EAEjB,YACC,IAAI,cAAc,QACD,UAAS,kBAAkB;;;;;;;;;;;;;;;MAuCzC,UAAU;;;;;;;;;;EAoBd,WAAW;;;;;;;;;UAkCG;;;;;;;;;UAsCN"}
1
+ {"version":3,"file":"file-server.d.mts","names":[],"sources":["../src/file-server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;YA6DY,OAAO,oBAAoB,mBAAmB,cACpD,kBACH,mBAAmB,cAAc,YAC7B,gBAAgB,SACnB;;iBAGa,iBAAiB,sCACzB;;;;;;;;;;EAUR,IAAI,KAAK,OAAO;;;;;;;;;;;EAYhB,QAAQ;;;;;;;;;;;;EAaR,UAAU,aAAa,qBAAqB;;iBAG5B,kBAAkB;;;;;;;;;;;;;;EAclC,gBAAgB;;EAEhB;;;;;;EAMA,SAAS;;;;;;;;;EAST,SAAS;;;;;;qBAOG,6BAA6B;WAE/B;WACA;WACA;EAHV,YACU,gBACA,gBACA;;;qBAWE,gBAAgB;WAElB;WACA;EAFV,YACU,aACA;;qBAYE,WACZ,+BACA,yCACY,UAAU,OAAO,iBAAiB;mBAqB5B;WAnBT,IAAI;WACJ,SAAS,QAAQ,aAAa,QAAQ,iBAAiB;;WAGvD;mBAEQ;;mBAGA;;;;;mBAMA;EAEjB,YACC,IAAI,cAAc,QACD,UAAS,kBAAkB;;;;;;;;;;;;;;;MA2CzC,UAAU;;;;;;;;;;EAoBd,WAAW;;;;;;;;;UAmCG;;;;;;;;;UAsCN"}
@@ -1,3 +1,4 @@
1
+ import { r as expiryDays } from "./expire-CpzUAfr9.mjs";
1
2
  import { canonicalId, provideKey, serviceKey } from "@geekmidas/manifest";
2
3
  import { createStorageClient } from "@geekmidas/storage";
3
4
  //#region src/file-server.ts
@@ -31,6 +32,22 @@ import { createStorageClient } from "@geekmidas/storage";
31
32
  * and naming the bucket after the construct makes that edit *add* a node rather
32
33
  * than rename the one holding the data.
33
34
  */
35
+ /**
36
+ * A bucket setting given to a file server that fronts a bucket declared
37
+ * elsewhere — where the bucket's own construct is the one that says it.
38
+ */
39
+ var BucketOptionOnOrigin = class extends Error {
40
+ server;
41
+ origin;
42
+ option;
43
+ constructor(server, origin, option) {
44
+ super(`'${server}' fronts '${origin}', which declares itself, so '${option}' belongs on the construct that declares '${origin}', not on the file server.`);
45
+ this.server = server;
46
+ this.origin = origin;
47
+ this.option = option;
48
+ this.name = "BucketOptionOnOrigin";
49
+ }
50
+ };
34
51
  /** A key was asked to be served unsigned, and no open pattern admits it. */
35
52
  var NotOpen = class extends Error {
36
53
  key;
@@ -49,6 +66,8 @@ var FileServer = class {
49
66
  /** The id of the surface node, as opposed to the bucket's. */
50
67
  surfaceId;
51
68
  open;
69
+ /** The vended bucket's expiry, checked once: prefix → days. */
70
+ expire;
52
71
  /**
53
72
  * Declared once and read by both `declare()` and `connect()`, so the keys the
54
73
  * target publishes and the keys the client reads cannot drift.
@@ -60,6 +79,8 @@ var FileServer = class {
60
79
  this.id = canonical;
61
80
  this.open = options.open ?? [];
62
81
  const originId = options.origin?.id ?? canonical;
82
+ if (options.origin && options.expire) throw new BucketOptionOnOrigin(canonical, originId, "expire");
83
+ this.expire = expiryDays(canonical, options.expire);
63
84
  this.surfaceId = `${canonical}Server`;
64
85
  this.keys = {
65
86
  origin: provideKey(originId, "url"),
@@ -114,7 +135,8 @@ var FileServer = class {
114
135
  kind: "objects",
115
136
  id: this.id,
116
137
  provides: [this.keys.origin],
117
- ...this.options.versioned ? { versioned: true } : {}
138
+ ...this.options.versioned ? { versioned: true } : {},
139
+ ...this.expire ? { expire: this.expire } : {}
118
140
  }, surface];
119
141
  }
120
142
  /**
@@ -179,6 +201,6 @@ function globToRegExp(pattern) {
179
201
  return new RegExp(`^${source}$`);
180
202
  }
181
203
  //#endregion
182
- export { FileServer, NotOpen };
204
+ export { BucketOptionOnOrigin, FileServer, NotOpen };
183
205
 
184
206
  //# sourceMappingURL=file-server.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-server.mjs","names":[],"sources":["../src/file-server.ts"],"sourcesContent":["/**\n * `FileServer` — a domain that serves a bucket's objects.\n *\n * `ObjectStorage` is the bucket: it writes, it presigns, and its URL is never\n * public. Serving those objects on a domain is a different thing, and it is a\n * construct of its own rather than a flag on the bucket — see\n * `docs/design/constructs-paradigm.md`, \"Why a separate construct, and what it\n * costs\", for the comparison that rules the other two shapes out.\n *\n * ```ts\n * export const uploads = new FileServer('Uploads', { open: ['brand/**'] });\n *\n * uploads.getUploadURL({ path, contentType }) // an S3 presign at the bucket\n * uploads.url('brand/logo.png') // open path — no signature\n * uploads.signedUrl('invoices/7.pdf') // one object, one recipient\n * ```\n *\n * **One construct, one client, both halves.** How a file lands in the bucket is\n * the same whether or not it is served, so splitting the upload half from the\n * serving half would be ceremony rather than safety. The client is a *superset*\n * of `StorageClient`, made literal in the type, so anything taking\n * `services.uploads` keeps compiling when the construct behind it grows a\n * serving half.\n *\n * **The id names the bucket, not the surface.** This is the detail that has to\n * be right before anything ships, because getting it backwards is destructive:\n * the migration people actually perform is serving a bucket they already have,\n * and naming the bucket after the construct makes that edit *add* a node rather\n * than rename the one holding the data.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { createStorageClient, type StorageClient } from '@geekmidas/storage';\nimport type { Construct, Declarable } from './construct-interface';\n\n/**\n * A key an open pattern admits.\n *\n * The same template-literal trick `ConstructName` uses, so `open` is checked at\n * the call site rather than only at the edge:\n *\n * ```ts\n * files.url('brand/logo.png') // ok\n * files.url(`avatars/${id}.png`) // ok — a template literal still matches\n * files.url('invoices/7.pdf') // not assignable — never served unsigned\n * ```\n *\n * A single star and a double star resolve to the same type, stated rather than\n * discovered: a template literal cannot exclude `/`, so this is a prefix-and-\n * suffix guard while the *exact* pattern is enforced by the bucket policy, by\n * the cache behaviour, and by this construct's own runtime check. The type says\n * plausibly open; the infrastructure says definitely.\n */\nexport type Served<P extends string> = P extends `${infer Head}**`\n\t? `${Head}${string}`\n\t: P extends `${infer Head}*${infer Tail}`\n\t\t? `${Head}${string}${Tail}`\n\t\t: P;\n\n/** What consuming a file server hands you: a bucket client that also serves. */\nexport interface FileServerClient<TOpen extends string = never>\n\textends StorageClient {\n\t/**\n\t * The unsigned address of an open object.\n\t *\n\t * Compile-checked against the declared patterns, *and* checked again at\n\t * runtime — a JavaScript caller gets no compiler, and minting an unsigned\n\t * URL for a private object is a leak rather than a mistake.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\turl(key: Served<TOpen>): string;\n\n\t/**\n\t * The same thing for a key the compiler cannot see.\n\t *\n\t * A fully dynamic key does not type, which is correct and is also the case\n\t * people will hit — so the escape hatch is a named method rather than a\n\t * cast, and it runs the *same* runtime check rather than being a way around\n\t * it.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\topenUrl(key: string): string;\n\n\t/**\n\t * A signed address for one object and one recipient.\n\t *\n\t * Today this is an **S3 presign at the bucket**, which is what works\n\t * unchanged against MinIO locally and against S3 deployed. It is deliberately\n\t * not described as a CDN URL: CloudFront signing is a different mechanism,\n\t * with different keys, against a different host, and it needs key material\n\t * this construct does not yet declare.\n\t *\n\t * @param expiresIn - minutes, matching `getUploadURL`.\n\t */\n\tsignedUrl(key: string, expiresIn?: number): Promise<string>;\n}\n\nexport interface FileServerOptions<TOpen extends string = never> {\n\t/**\n\t * Paths served without a signature. Everything else needs one.\n\t *\n\t * Private by default: a bucket where forgetting a flag publishes user\n\t * uploads is the wrong default, so this is an exception list, and listing it\n\t * in code means exactly one set of paths is unauthenticated and it is\n\t * reviewable in a diff.\n\t *\n\t * Uploading is deliberately *not* restricted to these. Writing to a path\n\t * that happens to be open is ordinary; the only asymmetry worth enforcing is\n\t * that you cannot hand out an unsigned URL for something the server would\n\t * refuse to serve unsigned.\n\t */\n\topen?: readonly TOpen[];\n\t/** Keep previous versions of an object. */\n\tversioned?: boolean;\n\t/**\n\t * A bucket declared elsewhere, instead of one of this server's own.\n\t *\n\t * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that\n\t * already exists, which is also how the two edges come back when you want\n\t * them separately — a handler depending on the bucket writes, a handler\n\t * depending on the server mints URLs.\n\t */\n\torigin?: Declarable;\n}\n\n/** A key was asked to be served unsigned, and no open pattern admits it. */\nexport class NotOpen extends Error {\n\tconstructor(\n\t\treadonly key: string,\n\t\treadonly open: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${key}' is not served without a signature. ` +\n\t\t\t\t(open.length\n\t\t\t\t\t? `Open paths: ${open.join(', ')}. Use signedUrl() for anything else.`\n\t\t\t\t\t: 'This file server declares no open paths, so every object needs signedUrl().'),\n\t\t);\n\t\tthis.name = 'NotOpen';\n\t}\n}\n\nexport class FileServer<\n\tTName extends string = string,\n\tTOpen extends string = never,\n> implements Construct<TName, FileServerClient<TOpen>>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;\n\n\t/** The id of the surface node, as opposed to the bucket's. */\n\treadonly surfaceId: string;\n\n\tprivate readonly open: readonly string[];\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the client reads cannot drift.\n\t */\n\tprivate readonly keys: { origin: string; server: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: FileServerOptions<TOpen> = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.open = options.open ?? [];\n\n\t\t// The surface takes the suffix and the bucket keeps the plain id, which\n\t\t// is what makes \"serve a bucket I already have\" an edit that adds a node\n\t\t// instead of renaming the one holding the data.\n\t\tconst originId = options.origin?.id ?? canonical;\n\t\tthis.surfaceId = `${canonical}Server`;\n\n\t\tthis.keys = {\n\t\t\torigin: provideKey(originId, 'url'),\n\t\t\tserver: provideKey(this.surfaceId, 'url'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (registerOptions) => this.connect(registerOptions),\n\t\t};\n\t}\n\n\t/**\n\t * The served surface, as something an edge can point at.\n\t *\n\t * Depending on the `FileServer` itself points at the **bucket** — its\n\t * canonical node — which is right for a handler: it presigns and writes. But\n\t * a bucket's URL is never public, so a site depending on it gets nothing\n\t * inlined, which is correct and also useless.\n\t *\n\t * This is the other half: `.dependsOn([uploads.server])` points at the\n\t * surface, whose address *is* public, and is what puts\n\t * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape\n\t * `database.reader()` uses, and for the same reason — one construct owning\n\t * two addresses needs a way to name the second.\n\t */\n\tget server(): Declarable {\n\t\tconst surface = this.declare().find(\n\t\t\t(declaration) => declaration.id === this.surfaceId,\n\t\t);\n\n\t\treturn {\n\t\t\tid: this.surfaceId,\n\t\t\tdeclare: () => (surface ? [surface] : []),\n\t\t};\n\t}\n\n\t/**\n\t * The bucket and the surface over it — or just the surface, when the bucket\n\t * was declared elsewhere.\n\t *\n\t * The surface names its origin through `of`, which is what makes the\n\t * reference check work: an origin resolving to nothing is a build failure,\n\t * the same guarantee `assertDerivations` already gives a reader and a schema\n\t * tenant.\n\t */\n\tdeclare(): Declaration[] {\n\t\tconst origin = this.options.origin;\n\n\t\tconst surface: Declaration = {\n\t\t\tkind: 'file-server',\n\t\t\tid: this.surfaceId,\n\t\t\tof: origin?.id ?? this.id,\n\t\t\t...(this.open.length ? { open: this.open } : {}),\n\t\t\tprovides: [this.keys.server],\n\t\t};\n\n\t\t// A vended bucket is declared here; a given one already declares itself,\n\t\t// and declaring it twice is the duplication the whole model removes.\n\t\tif (origin) return [surface];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'objects',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.keys.origin],\n\t\t\t\t...(this.options.versioned ? { versioned: true } : {}),\n\t\t\t},\n\t\t\tsurface,\n\t\t];\n\t}\n\n\t/**\n\t * The bucket's client, with the serving half added.\n\t *\n\t * Both addresses are read here, which is also how the environment reaches a\n\t * handler: the sniffer records what this reads, so `.dependsOn([uploads])`\n\t * carries the bucket URL and the server URL without either being written\n\t * down beside the handler.\n\t */\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<FileServerClient<TOpen>> {\n\t\tconst { origin, server } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigin: get(this.keys.origin).string(),\n\t\t\t\tserver: get(this.keys.server).string(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tconst storage = createStorageClient(origin);\n\t\tconst base = server.replace(/\\/+$/, '');\n\n\t\tconst serve = (key: string): string => {\n\t\t\tif (!this.serves(key)) throw new NotOpen(key, this.open);\n\n\t\t\treturn `${base}/${key.replace(/^\\/+/, '')}`;\n\t\t};\n\n\t\t// Delegating rather than copying: the bucket half is whatever the driver\n\t\t// produced, including anything it grows later, and only the serving half\n\t\t// is added on top.\n\t\treturn Object.assign(Object.create(storage) as StorageClient, {\n\t\t\turl: serve as (key: Served<TOpen>) => string,\n\t\t\topenUrl: serve,\n\t\t\tsignedUrl: (key: string, expiresIn?: number) =>\n\t\t\t\tstorage.getDownloadURL({ path: key } as never, expiresIn),\n\t\t}) as FileServerClient<TOpen>;\n\t}\n\n\t/**\n\t * Whether an open pattern admits a key.\n\t *\n\t * The runtime half of {@link Served}, and stricter than it: here a single\n\t * star stops at a segment boundary and a double star does not, which is the\n\t * distinction a template-literal type cannot draw and the infrastructure\n\t * does.\n\t */\n\tprivate serves(key: string): boolean {\n\t\treturn this.open.some((pattern) => globToRegExp(pattern).test(key));\n\t}\n}\n\n/**\n * One open pattern as an anchored expression.\n *\n * A double star crosses `/`; a single star does not. Both are consumed in one\n * left-to-right pass rather than by substitution, so a pattern cannot be\n * rewritten into a placeholder that a later pass mistakes for literal text.\n */\nfunction globToRegExp(pattern: string): RegExp {\n\tlet source = '';\n\n\tfor (let index = 0; index < pattern.length; index++) {\n\t\tconst character = pattern[index];\n\n\t\tif (character !== '*') {\n\t\t\tsource += character?.replace(/[.+^${}()|[\\]\\\\?]/, '\\\\$&') ?? '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pattern[index + 1] === '*') {\n\t\t\tsource += '.*';\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsource += '[^/]*';\n\t}\n\n\treturn new RegExp(`^${source}$`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"file-server.mjs","names":[],"sources":["../src/file-server.ts"],"sourcesContent":["/**\n * `FileServer` — a domain that serves a bucket's objects.\n *\n * `ObjectStorage` is the bucket: it writes, it presigns, and its URL is never\n * public. Serving those objects on a domain is a different thing, and it is a\n * construct of its own rather than a flag on the bucket — see\n * `docs/design/constructs-paradigm.md`, \"Why a separate construct, and what it\n * costs\", for the comparison that rules the other two shapes out.\n *\n * ```ts\n * export const uploads = new FileServer('Uploads', { open: ['brand/**'] });\n *\n * uploads.getUploadURL({ path, contentType }) // an S3 presign at the bucket\n * uploads.url('brand/logo.png') // open path — no signature\n * uploads.signedUrl('invoices/7.pdf') // one object, one recipient\n * ```\n *\n * **One construct, one client, both halves.** How a file lands in the bucket is\n * the same whether or not it is served, so splitting the upload half from the\n * serving half would be ceremony rather than safety. The client is a *superset*\n * of `StorageClient`, made literal in the type, so anything taking\n * `services.uploads` keeps compiling when the construct behind it grows a\n * serving half.\n *\n * **The id names the bucket, not the surface.** This is the detail that has to\n * be right before anything ships, because getting it backwards is destructive:\n * the migration people actually perform is serving a bucket they already have,\n * and naming the bucket after the construct makes that edit *add* a node rather\n * than rename the one holding the data.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { createStorageClient, type StorageClient } from '@geekmidas/storage';\nimport type { Construct, Declarable } from './construct-interface';\nimport { expiryDays, type ObjectExpiry } from './expire';\n\n/**\n * A key an open pattern admits.\n *\n * The same template-literal trick `ConstructName` uses, so `open` is checked at\n * the call site rather than only at the edge:\n *\n * ```ts\n * files.url('brand/logo.png') // ok\n * files.url(`avatars/${id}.png`) // ok — a template literal still matches\n * files.url('invoices/7.pdf') // not assignable — never served unsigned\n * ```\n *\n * A single star and a double star resolve to the same type, stated rather than\n * discovered: a template literal cannot exclude `/`, so this is a prefix-and-\n * suffix guard while the *exact* pattern is enforced by the bucket policy, by\n * the cache behaviour, and by this construct's own runtime check. The type says\n * plausibly open; the infrastructure says definitely.\n */\nexport type Served<P extends string> = P extends `${infer Head}**`\n\t? `${Head}${string}`\n\t: P extends `${infer Head}*${infer Tail}`\n\t\t? `${Head}${string}${Tail}`\n\t\t: P;\n\n/** What consuming a file server hands you: a bucket client that also serves. */\nexport interface FileServerClient<TOpen extends string = never>\n\textends StorageClient {\n\t/**\n\t * The unsigned address of an open object.\n\t *\n\t * Compile-checked against the declared patterns, *and* checked again at\n\t * runtime — a JavaScript caller gets no compiler, and minting an unsigned\n\t * URL for a private object is a leak rather than a mistake.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\turl(key: Served<TOpen>): string;\n\n\t/**\n\t * The same thing for a key the compiler cannot see.\n\t *\n\t * A fully dynamic key does not type, which is correct and is also the case\n\t * people will hit — so the escape hatch is a named method rather than a\n\t * cast, and it runs the *same* runtime check rather than being a way around\n\t * it.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\topenUrl(key: string): string;\n\n\t/**\n\t * A signed address for one object and one recipient.\n\t *\n\t * Today this is an **S3 presign at the bucket**, which is what works\n\t * unchanged against MinIO locally and against S3 deployed. It is deliberately\n\t * not described as a CDN URL: CloudFront signing is a different mechanism,\n\t * with different keys, against a different host, and it needs key material\n\t * this construct does not yet declare.\n\t *\n\t * @param expiresIn - minutes, matching `getUploadURL`.\n\t */\n\tsignedUrl(key: string, expiresIn?: number): Promise<string>;\n}\n\nexport interface FileServerOptions<TOpen extends string = never> {\n\t/**\n\t * Paths served without a signature. Everything else needs one.\n\t *\n\t * Private by default: a bucket where forgetting a flag publishes user\n\t * uploads is the wrong default, so this is an exception list, and listing it\n\t * in code means exactly one set of paths is unauthenticated and it is\n\t * reviewable in a diff.\n\t *\n\t * Uploading is deliberately *not* restricted to these. Writing to a path\n\t * that happens to be open is ordinary; the only asymmetry worth enforcing is\n\t * that you cannot hand out an unsigned URL for something the server would\n\t * refuse to serve unsigned.\n\t */\n\topen?: readonly TOpen[];\n\t/** Keep previous versions of an object. */\n\tversioned?: boolean;\n\t/**\n\t * Delete the objects under each prefix this many days after they were\n\t * written — `{ 'previews/': { days: 7 } }`. A setting of the bucket this\n\t * server vends, so it cannot be given with `origin`.\n\t */\n\texpire?: ObjectExpiry;\n\t/**\n\t * A bucket declared elsewhere, instead of one of this server's own.\n\t *\n\t * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that\n\t * already exists, which is also how the two edges come back when you want\n\t * them separately — a handler depending on the bucket writes, a handler\n\t * depending on the server mints URLs.\n\t */\n\torigin?: Declarable;\n}\n\n/**\n * A bucket setting given to a file server that fronts a bucket declared\n * elsewhere — where the bucket's own construct is the one that says it.\n */\nexport class BucketOptionOnOrigin extends Error {\n\tconstructor(\n\t\treadonly server: string,\n\t\treadonly origin: string,\n\t\treadonly option: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${server}' fronts '${origin}', which declares itself, so '${option}' ` +\n\t\t\t\t`belongs on the construct that declares '${origin}', not on the file server.`,\n\t\t);\n\t\tthis.name = 'BucketOptionOnOrigin';\n\t}\n}\n\n/** A key was asked to be served unsigned, and no open pattern admits it. */\nexport class NotOpen extends Error {\n\tconstructor(\n\t\treadonly key: string,\n\t\treadonly open: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${key}' is not served without a signature. ` +\n\t\t\t\t(open.length\n\t\t\t\t\t? `Open paths: ${open.join(', ')}. Use signedUrl() for anything else.`\n\t\t\t\t\t: 'This file server declares no open paths, so every object needs signedUrl().'),\n\t\t);\n\t\tthis.name = 'NotOpen';\n\t}\n}\n\nexport class FileServer<\n\tTName extends string = string,\n\tTOpen extends string = never,\n> implements Construct<TName, FileServerClient<TOpen>>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;\n\n\t/** The id of the surface node, as opposed to the bucket's. */\n\treadonly surfaceId: string;\n\n\tprivate readonly open: readonly string[];\n\n\t/** The vended bucket's expiry, checked once: prefix → days. */\n\tprivate readonly expire: Record<string, number> | undefined;\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the client reads cannot drift.\n\t */\n\tprivate readonly keys: { origin: string; server: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: FileServerOptions<TOpen> = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.open = options.open ?? [];\n\n\t\t// The surface takes the suffix and the bucket keeps the plain id, which\n\t\t// is what makes \"serve a bucket I already have\" an edit that adds a node\n\t\t// instead of renaming the one holding the data.\n\t\tconst originId = options.origin?.id ?? canonical;\n\t\tif (options.origin && options.expire) {\n\t\t\tthrow new BucketOptionOnOrigin(canonical, originId, 'expire');\n\t\t}\n\t\tthis.expire = expiryDays(canonical, options.expire);\n\t\tthis.surfaceId = `${canonical}Server`;\n\n\t\tthis.keys = {\n\t\t\torigin: provideKey(originId, 'url'),\n\t\t\tserver: provideKey(this.surfaceId, 'url'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (registerOptions) => this.connect(registerOptions),\n\t\t};\n\t}\n\n\t/**\n\t * The served surface, as something an edge can point at.\n\t *\n\t * Depending on the `FileServer` itself points at the **bucket** — its\n\t * canonical node — which is right for a handler: it presigns and writes. But\n\t * a bucket's URL is never public, so a site depending on it gets nothing\n\t * inlined, which is correct and also useless.\n\t *\n\t * This is the other half: `.dependsOn([uploads.server])` points at the\n\t * surface, whose address *is* public, and is what puts\n\t * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape\n\t * `database.reader()` uses, and for the same reason — one construct owning\n\t * two addresses needs a way to name the second.\n\t */\n\tget server(): Declarable {\n\t\tconst surface = this.declare().find(\n\t\t\t(declaration) => declaration.id === this.surfaceId,\n\t\t);\n\n\t\treturn {\n\t\t\tid: this.surfaceId,\n\t\t\tdeclare: () => (surface ? [surface] : []),\n\t\t};\n\t}\n\n\t/**\n\t * The bucket and the surface over it — or just the surface, when the bucket\n\t * was declared elsewhere.\n\t *\n\t * The surface names its origin through `of`, which is what makes the\n\t * reference check work: an origin resolving to nothing is a build failure,\n\t * the same guarantee `assertDerivations` already gives a reader and a schema\n\t * tenant.\n\t */\n\tdeclare(): Declaration[] {\n\t\tconst origin = this.options.origin;\n\n\t\tconst surface: Declaration = {\n\t\t\tkind: 'file-server',\n\t\t\tid: this.surfaceId,\n\t\t\tof: origin?.id ?? this.id,\n\t\t\t...(this.open.length ? { open: this.open } : {}),\n\t\t\tprovides: [this.keys.server],\n\t\t};\n\n\t\t// A vended bucket is declared here; a given one already declares itself,\n\t\t// and declaring it twice is the duplication the whole model removes.\n\t\tif (origin) return [surface];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'objects',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.keys.origin],\n\t\t\t\t...(this.options.versioned ? { versioned: true } : {}),\n\t\t\t\t...(this.expire ? { expire: this.expire } : {}),\n\t\t\t},\n\t\t\tsurface,\n\t\t];\n\t}\n\n\t/**\n\t * The bucket's client, with the serving half added.\n\t *\n\t * Both addresses are read here, which is also how the environment reaches a\n\t * handler: the sniffer records what this reads, so `.dependsOn([uploads])`\n\t * carries the bucket URL and the server URL without either being written\n\t * down beside the handler.\n\t */\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<FileServerClient<TOpen>> {\n\t\tconst { origin, server } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigin: get(this.keys.origin).string(),\n\t\t\t\tserver: get(this.keys.server).string(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tconst storage = createStorageClient(origin);\n\t\tconst base = server.replace(/\\/+$/, '');\n\n\t\tconst serve = (key: string): string => {\n\t\t\tif (!this.serves(key)) throw new NotOpen(key, this.open);\n\n\t\t\treturn `${base}/${key.replace(/^\\/+/, '')}`;\n\t\t};\n\n\t\t// Delegating rather than copying: the bucket half is whatever the driver\n\t\t// produced, including anything it grows later, and only the serving half\n\t\t// is added on top.\n\t\treturn Object.assign(Object.create(storage) as StorageClient, {\n\t\t\turl: serve as (key: Served<TOpen>) => string,\n\t\t\topenUrl: serve,\n\t\t\tsignedUrl: (key: string, expiresIn?: number) =>\n\t\t\t\tstorage.getDownloadURL({ path: key } as never, expiresIn),\n\t\t}) as FileServerClient<TOpen>;\n\t}\n\n\t/**\n\t * Whether an open pattern admits a key.\n\t *\n\t * The runtime half of {@link Served}, and stricter than it: here a single\n\t * star stops at a segment boundary and a double star does not, which is the\n\t * distinction a template-literal type cannot draw and the infrastructure\n\t * does.\n\t */\n\tprivate serves(key: string): boolean {\n\t\treturn this.open.some((pattern) => globToRegExp(pattern).test(key));\n\t}\n}\n\n/**\n * One open pattern as an anchored expression.\n *\n * A double star crosses `/`; a single star does not. Both are consumed in one\n * left-to-right pass rather than by substitution, so a pattern cannot be\n * rewritten into a placeholder that a later pass mistakes for literal text.\n */\nfunction globToRegExp(pattern: string): RegExp {\n\tlet source = '';\n\n\tfor (let index = 0; index < pattern.length; index++) {\n\t\tconst character = pattern[index];\n\n\t\tif (character !== '*') {\n\t\t\tsource += character?.replace(/[.+^${}()|[\\]\\\\?]/, '\\\\$&') ?? '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pattern[index + 1] === '*') {\n\t\t\tsource += '.*';\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsource += '[^/]*';\n\t}\n\n\treturn new RegExp(`^${source}$`);\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { i as FunctionHandler, n as Function, r as FunctionContext } from "../Function-Pu-1kKZz.cjs";
2
- import { n as BaseFunctionBuilder, t as FunctionBuilder } from "../index-BuzRvKOQ.cjs";
1
+ import { i as FunctionHandler, n as Function, r as FunctionContext } from "../Function-B0uZhZnU.cjs";
2
+ import { n as BaseFunctionBuilder, t as FunctionBuilder } from "../index-Cd2w-DRL.cjs";
3
3
  export { BaseFunctionBuilder, Function, FunctionBuilder, type FunctionContext, type FunctionHandler };
@@ -1,3 +1,3 @@
1
- import { i as FunctionHandler, n as Function, r as FunctionContext } from "../Function-DuqGcbOI.mjs";
2
- import { n as BaseFunctionBuilder, t as FunctionBuilder } from "../index-B13kQB_U.mjs";
1
+ import { i as FunctionHandler, n as Function, r as FunctionContext } from "../Function-B_9R7Zy1.mjs";
2
+ import { n as BaseFunctionBuilder, t as FunctionBuilder } from "../index-aBIcAiH5.mjs";
3
3
  export { BaseFunctionBuilder, Function, FunctionBuilder, type FunctionContext, type FunctionHandler };
@@ -1,6 +1,6 @@
1
- import { t as StandardSchemaV1 } from "./index-CeEtxDmK.cjs";
2
- import { a as EventFor, c as Topic, n as ConstructType, o as TopicEvent } from "./Construct-BQALFCh2.cjs";
3
- import { i as FunctionHandler, n as Function } from "./Function-Pu-1kKZz.cjs";
1
+ import { n as StandardSchemaV1 } from "./index-DdRjYhiJ.cjs";
2
+ import { a as EventFor, c as Topic, n as ConstructType, o as TopicEvent } from "./Construct-CFW0zjdD.cjs";
3
+ import { i as FunctionHandler, n as Function } from "./Function-B0uZhZnU.cjs";
4
4
  import { c as ServicesOf, r as Consumable } from "./construct-interface-B1AfqRl4.cjs";
5
5
  import { Logger } from "@geekmidas/logger";
6
6
  import { ComposableStandardSchema, InferComposableStandardSchema, InferStandardSchema } from "@geekmidas/schema";
@@ -112,4 +112,4 @@ declare class FunctionBuilder<TInput extends ComposableStandardSchema, OutSchema
112
112
  }
113
113
  //#endregion
114
114
  export { BaseFunctionBuilder as n, FunctionBuilder as t };
115
- //# sourceMappingURL=index-BuzRvKOQ.d.cts.map
115
+ //# sourceMappingURL=index-Cd2w-DRL.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-B13kQB_U.d.mts","names":[],"sources":["../src/functions/BaseFunctionBuilder.ts","../src/functions/FunctionBuilder.ts"],"mappings":";;;;;;;;;uBAsBsB,oBACrB,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA;EAoFmB,MAAI;YAlFb,cAAc;YACd,eAAe;YACf;EAEH,WAAW;;;;;;;;;EASX;EACA,SAAS;;;;;;;EAQT;;;;;;;;EASA;;EAGA,SAAS;YACN,kBAAkB,QAAQ,0BAA0B;YACpD,mBAAmB,QAAQ,sBAAsB;;YAEjD;SAEH,mBAAmB,aAAa,KAAK;SAM/B,8BACZ,UAAU,sCACT,eAAe,QAAQ,IAAI,QAAQ,8BAA8B;EAkCnE,YAAmB,OAAI;WAEd,SAAS,UAAU,WAAW,UAAU;WAExC,OAAO,UAAU,QAAQ,QAAQ;EAE1C,QAAQ;WAIC,OAAO,UAAU,kBAAkB,QAAQ;WAE3C,MAAM,UAAU,0BAA0B,QAAQ;;;;;;;YAQjD,UACT,OAAO,iBACP,OAAO,SAAS;EAcjB,QAAQ,UAAU,cAAc,sBAC/B,SAAS,QAAQ,OAAO,KACtB,oBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA;;;;;EAuBD,SAAS,GAAG,sBACX,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,oBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA;;;;cCzKW,gBACZ,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC,0CAI/C,oBACT,QACA,WACA,WACA,SACA,eACA,0BACA,WACA;EAI4B,MAAI;YAFtB;EAEV,YAA4B,OAAI;EAIvB,QAAQ;EAIjB,WAAW;EAIX,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,GACA,WACA,SACA,eACA,0BACA,WACA,sBACA;EAiBD,MAAM,UAAU,0BACf,QAAQ,IACN,gBACF,GACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;;;;;;;;EA4BD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,gBACF,QACA,eACI,cAAc,WAAW,KAC7B,SACA,eACA,0BACA,WACA,sBACA;EA8BD,SAAS,UAAU,WAClB,UAAU,IACR,gBACF,QACA,eACI,cAAc,IAClB,SACA,eACA,0BACA,WACA,sBACA;EAoBD,OAAO,UAAU,QAChB,QAAQ,IACN,gBACF,QACA,WACA,WACA,GACA,eACA,0BACA,WACA,sBACA;;;;;;;EAuBD,MAAM,eAAe,iBACpB,OAAO,QACP,OAAO,SAAS,QAAQ,oBAAoB,cAC1C,gBACF,QACA,eACI,WAAW,oBACf,SACA,eACA,0BACA,WACA,sBACA;EAeQ,QAAQ,UAAU,cAAc,sBACxC,SAAS,QAAQ,OAAO,KACtB,gBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA,sBACA;;;;;EAwBD,QAAQ,UAAU,qCAAqC,gBACtD,QACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;EAmBQ,SAAS,GAAG,sBACpB,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,gBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA,OACA;EAkCD,OACC,IAAI,gBACH,QACA,WACA,SACA,WACA,WACA,eACA,gBAEC,SACF,QACA,WACA,SACA,WACA,eACA,0BACA,WACA,sBACA,cACA,gBACC,QACA,WACA,SACA,WACA,WACA,eACA"}
1
+ {"version":3,"file":"index-Cd2w-DRL.d.cts","names":[],"sources":["../src/functions/BaseFunctionBuilder.ts","../src/functions/FunctionBuilder.ts"],"mappings":";;;;;;;;;uBAsBsB,oBACrB,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA;EAoFmB,MAAI;YAlFb,cAAc;YACd,eAAe;YACf;EAEH,WAAW;;;;;;;;;EASX;EACA,SAAS;;;;;;;EAQT;;;;;;;;EASA;;EAGA,SAAS;YACN,kBAAkB,QAAQ,0BAA0B;YACpD,mBAAmB,QAAQ,sBAAsB;;YAEjD;SAEH,mBAAmB,aAAa,KAAK;SAM/B,8BACZ,UAAU,sCACT,eAAe,QAAQ,IAAI,QAAQ,8BAA8B;EAkCnE,YAAmB,OAAI;WAEd,SAAS,UAAU,WAAW,UAAU;WAExC,OAAO,UAAU,QAAQ,QAAQ;EAE1C,QAAQ;WAIC,OAAO,UAAU,kBAAkB,QAAQ;WAE3C,MAAM,UAAU,0BAA0B,QAAQ;;;;;;;YAQjD,UACT,OAAO,iBACP,OAAO,SAAS;EAcjB,QAAQ,UAAU,cAAc,sBAC/B,SAAS,QAAQ,OAAO,KACtB,oBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA;;;;;EAuBD,SAAS,GAAG,sBACX,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,oBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA;;;;cCzKW,gBACZ,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC,0CAI/C,oBACT,QACA,WACA,WACA,SACA,eACA,0BACA,WACA;EAI4B,MAAI;YAFtB;EAEV,YAA4B,OAAI;EAIvB,QAAQ;EAIjB,WAAW;EAIX,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,GACA,WACA,SACA,eACA,0BACA,WACA,sBACA;EAiBD,MAAM,UAAU,0BACf,QAAQ,IACN,gBACF,GACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;;;;;;;;EA4BD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,gBACF,QACA,eACI,cAAc,WAAW,KAC7B,SACA,eACA,0BACA,WACA,sBACA;EA8BD,SAAS,UAAU,WAClB,UAAU,IACR,gBACF,QACA,eACI,cAAc,IAClB,SACA,eACA,0BACA,WACA,sBACA;EAoBD,OAAO,UAAU,QAChB,QAAQ,IACN,gBACF,QACA,WACA,WACA,GACA,eACA,0BACA,WACA,sBACA;;;;;;;EAuBD,MAAM,eAAe,iBACpB,OAAO,QACP,OAAO,SAAS,QAAQ,oBAAoB,cAC1C,gBACF,QACA,eACI,WAAW,oBACf,SACA,eACA,0BACA,WACA,sBACA;EAeQ,QAAQ,UAAU,cAAc,sBACxC,SAAS,QAAQ,OAAO,KACtB,gBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA,sBACA;;;;;EAwBD,QAAQ,UAAU,qCAAqC,gBACtD,QACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;EAmBQ,SAAS,GAAG,sBACpB,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,gBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA,OACA;EAkCD,OACC,IAAI,gBACH,QACA,WACA,SACA,WACA,WACA,eACA,gBAEC,SACF,QACA,WACA,SACA,WACA,eACA,0BACA,WACA,sBACA,cACA,gBACC,QACA,WACA,SACA,WACA,WACA,eACA"}
@@ -74,6 +74,46 @@ declare namespace StandardSchemaV1 {
74
74
  /** Infers the output type of a Standard. */
75
75
  type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
76
76
  }
77
+ /** The Standard JSON Schema interface. */
78
+ interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
79
+ /** The Standard JSON Schema properties. */
80
+ readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>;
81
+ }
82
+ declare namespace StandardJSONSchemaV1 {
83
+ /** The Standard JSON Schema properties interface. */
84
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
85
+ /** Methods for generating the input/output JSON Schema. */
86
+ readonly jsonSchema: StandardJSONSchemaV1.Converter;
87
+ }
88
+ /** The Standard JSON Schema converter interface. */
89
+ interface Converter {
90
+ /** Converts the input type to JSON Schema. May throw if conversion is not supported. */
91
+ readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
92
+ /** Converts the output type to JSON Schema. May throw if conversion is not supported. */
93
+ readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
94
+ }
95
+ /**
96
+ * The target version of the generated JSON Schema.
97
+ *
98
+ * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.
99
+ *
100
+ * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`.
101
+ */
102
+ type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string);
103
+ /** The options for the input/output methods. */
104
+ interface Options {
105
+ /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */
106
+ readonly target: Target;
107
+ /** Explicit support for additional vendor-specific parameters, if needed. */
108
+ readonly libraryOptions?: Record<string, unknown> | undefined;
109
+ }
110
+ /** The Standard types interface. */
111
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
112
+ /** Infers the input type of a Standard. */
113
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
114
+ /** Infers the output type of a Standard. */
115
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
116
+ }
77
117
  //#endregion
78
- export { StandardSchemaV1 as t };
79
- //# sourceMappingURL=index-CeEtxDmK.d.cts.map
118
+ export { StandardSchemaV1 as n, StandardJSONSchemaV1 as t };
119
+ //# sourceMappingURL=index-DdRjYhiJ.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CeEtxDmK.d.cts","names":[],"sources":["../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;UACU,gBAAgB,iBAAiB,SAAS;;WAEvC,aAAa,gBAAgB,MAAM,OAAO;;kBAErC;;YAEJ,MAAM,iBAAiB,SAAS;;aAE7B;;aAEA;;aAEA,QAAQ,MAAM,OAAO;;;YAGxB,MAAM,iBAAiB,SAAS;;aAE7B,OAAO;;aAEP,QAAQ;;;OAGhB,WAAW,eAAe,mBAAmB,YAAY;;OAEzD,YAAY,eAAe,mBAAmB,YAAY;;;UAGzD,iBAAiB,iBAAiB,SAAS;;WAExC,aAAa,iBAAiB,MAAM,OAAO;;kBAEtC;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,WAAW,gBAAgB,UAAU,iBAAiB,wBAAwB,OAAO,UAAU,QAAQ,OAAO;;;OAGtH,OAAO,UAAU,cAAc,UAAU;;YAEpC,cAAc;;aAEX,OAAO;;aAEP;;YAEH;;aAEG,iBAAiB;;;YAGpB;;aAEG,QAAQ,cAAc;;;YAGzB;;aAEG;;aAEA,OAAO,cAAc,cAAc;;;YAGtC;;aAEG,KAAK;;;YAGR,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY"}
1
+ {"version":3,"file":"index-DdRjYhiJ.d.cts","names":[],"sources":["../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;UACU,gBAAgB,iBAAiB,SAAS;;WAEvC,aAAa,gBAAgB,MAAM,OAAO;;kBAErC;;YAEJ,MAAM,iBAAiB,SAAS;;aAE7B;;aAEA;;aAEA,QAAQ,MAAM,OAAO;;;YAGxB,MAAM,iBAAiB,SAAS;;aAE7B,OAAO;;aAEP,QAAQ;;;OAGhB,WAAW,eAAe,mBAAmB,YAAY;;OAEzD,YAAY,eAAe,mBAAmB,YAAY;;;UAGzD,iBAAiB,iBAAiB,SAAS;;WAExC,aAAa,iBAAiB,MAAM,OAAO;;kBAEtC;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,WAAW,gBAAgB,UAAU,iBAAiB,wBAAwB,OAAO,UAAU,QAAQ,OAAO;;;OAGtH,OAAO,UAAU,cAAc,UAAU;;YAEpC,cAAc;;aAEX,OAAO;;aAEP;;YAEH;;aAEG,iBAAiB;;;YAGpB;;aAEG,QAAQ,cAAc;;;YAGzB;;aAEG;;aAEA,OAAO,cAAc,cAAc;;;YAGtC;;aAEG,KAAK;;;YAGR,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY;;;UAGzE,qBAAqB,iBAAiB,SAAS;;WAE5C,aAAa,qBAAqB,MAAM,OAAO;;kBAE1C;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,YAAY,qBAAqB;;;YAGpC;;aAEG,QAAQ,SAAS,qBAAqB,YAAY;;aAElD,SAAS,SAAS,qBAAqB,YAAY;;;;;;;;;OAS3D;;YAEK;;aAEG,QAAQ;;aAER,iBAAiB;;;YAGpB,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY"}
@@ -74,6 +74,46 @@ declare namespace StandardSchemaV1 {
74
74
  /** Infers the output type of a Standard. */
75
75
  type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
76
76
  }
77
+ /** The Standard JSON Schema interface. */
78
+ interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
79
+ /** The Standard JSON Schema properties. */
80
+ readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>;
81
+ }
82
+ declare namespace StandardJSONSchemaV1 {
83
+ /** The Standard JSON Schema properties interface. */
84
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
85
+ /** Methods for generating the input/output JSON Schema. */
86
+ readonly jsonSchema: StandardJSONSchemaV1.Converter;
87
+ }
88
+ /** The Standard JSON Schema converter interface. */
89
+ interface Converter {
90
+ /** Converts the input type to JSON Schema. May throw if conversion is not supported. */
91
+ readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
92
+ /** Converts the output type to JSON Schema. May throw if conversion is not supported. */
93
+ readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
94
+ }
95
+ /**
96
+ * The target version of the generated JSON Schema.
97
+ *
98
+ * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.
99
+ *
100
+ * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`.
101
+ */
102
+ type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string);
103
+ /** The options for the input/output methods. */
104
+ interface Options {
105
+ /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */
106
+ readonly target: Target;
107
+ /** Explicit support for additional vendor-specific parameters, if needed. */
108
+ readonly libraryOptions?: Record<string, unknown> | undefined;
109
+ }
110
+ /** The Standard types interface. */
111
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
112
+ /** Infers the input type of a Standard. */
113
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
114
+ /** Infers the output type of a Standard. */
115
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
116
+ }
77
117
  //#endregion
78
- export { StandardSchemaV1 as t };
79
- //# sourceMappingURL=index-CeEtxDmK.d.mts.map
118
+ export { StandardSchemaV1 as n, StandardJSONSchemaV1 as t };
119
+ //# sourceMappingURL=index-DdRjYhiJ.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CeEtxDmK.d.mts","names":[],"sources":["../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;UACU,gBAAgB,iBAAiB,SAAS;;WAEvC,aAAa,gBAAgB,MAAM,OAAO;;kBAErC;;YAEJ,MAAM,iBAAiB,SAAS;;aAE7B;;aAEA;;aAEA,QAAQ,MAAM,OAAO;;;YAGxB,MAAM,iBAAiB,SAAS;;aAE7B,OAAO;;aAEP,QAAQ;;;OAGhB,WAAW,eAAe,mBAAmB,YAAY;;OAEzD,YAAY,eAAe,mBAAmB,YAAY;;;UAGzD,iBAAiB,iBAAiB,SAAS;;WAExC,aAAa,iBAAiB,MAAM,OAAO;;kBAEtC;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,WAAW,gBAAgB,UAAU,iBAAiB,wBAAwB,OAAO,UAAU,QAAQ,OAAO;;;OAGtH,OAAO,UAAU,cAAc,UAAU;;YAEpC,cAAc;;aAEX,OAAO;;aAEP;;YAEH;;aAEG,iBAAiB;;;YAGpB;;aAEG,QAAQ,cAAc;;;YAGzB;;aAEG;;aAEA,OAAO,cAAc,cAAc;;;YAGtC;;aAEG,KAAK;;;YAGR,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY"}
1
+ {"version":3,"file":"index-DdRjYhiJ.d.mts","names":[],"sources":["../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;UACU,gBAAgB,iBAAiB,SAAS;;WAEvC,aAAa,gBAAgB,MAAM,OAAO;;kBAErC;;YAEJ,MAAM,iBAAiB,SAAS;;aAE7B;;aAEA;;aAEA,QAAQ,MAAM,OAAO;;;YAGxB,MAAM,iBAAiB,SAAS;;aAE7B,OAAO;;aAEP,QAAQ;;;OAGhB,WAAW,eAAe,mBAAmB,YAAY;;OAEzD,YAAY,eAAe,mBAAmB,YAAY;;;UAGzD,iBAAiB,iBAAiB,SAAS;;WAExC,aAAa,iBAAiB,MAAM,OAAO;;kBAEtC;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,WAAW,gBAAgB,UAAU,iBAAiB,wBAAwB,OAAO,UAAU,QAAQ,OAAO;;;OAGtH,OAAO,UAAU,cAAc,UAAU;;YAEpC,cAAc;;aAEX,OAAO;;aAEP;;YAEH;;aAEG,iBAAiB;;;YAGpB;;aAEG,QAAQ,cAAc;;;YAGzB;;aAEG;;aAEA,OAAO,cAAc,cAAc;;;YAGtC;;aAEG,KAAK;;;YAGR,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY;;;UAGzE,qBAAqB,iBAAiB,SAAS;;WAE5C,aAAa,qBAAqB,MAAM,OAAO;;kBAE1C;;YAEJ,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;aAEzE,YAAY,qBAAqB;;;YAGpC;;aAEG,QAAQ,SAAS,qBAAqB,YAAY;;aAElD,SAAS,SAAS,qBAAqB,YAAY;;;;;;;;;OAS3D;;YAEK;;aAEG,QAAQ;;aAER,iBAAiB;;;YAGpB,MAAM,iBAAiB,SAAS,eAAe,gBAAgB,MAAM,OAAO;;OAGjF,WAAW,eAAe,mBAAmB,gBAAgB,WAAW;;OAExE,YAAY,eAAe,mBAAmB,gBAAgB,YAAY"}
@@ -1,6 +1,6 @@
1
- import { t as StandardSchemaV1 } from "./index-CeEtxDmK.mjs";
2
- import { a as EventFor, c as Topic, n as ConstructType, o as TopicEvent } from "./Construct-QXnl3VqT.mjs";
3
- import { i as FunctionHandler, n as Function } from "./Function-DuqGcbOI.mjs";
1
+ import { n as StandardSchemaV1 } from "./index-DdRjYhiJ.mjs";
2
+ import { a as EventFor, c as Topic, n as ConstructType, o as TopicEvent } from "./Construct-B7AXn0xH.mjs";
3
+ import { i as FunctionHandler, n as Function } from "./Function-B_9R7Zy1.mjs";
4
4
  import { c as ServicesOf, r as Consumable } from "./construct-interface-ZvYQbivO.mjs";
5
5
  import { Service } from "@geekmidas/services";
6
6
  import { AuditStorage, AuditableAction } from "@geekmidas/audit";
@@ -112,4 +112,4 @@ declare class FunctionBuilder<TInput extends ComposableStandardSchema, OutSchema
112
112
  }
113
113
  //#endregion
114
114
  export { BaseFunctionBuilder as n, FunctionBuilder as t };
115
- //# sourceMappingURL=index-B13kQB_U.d.mts.map
115
+ //# sourceMappingURL=index-aBIcAiH5.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-BuzRvKOQ.d.cts","names":[],"sources":["../src/functions/BaseFunctionBuilder.ts","../src/functions/FunctionBuilder.ts"],"mappings":";;;;;;;;;uBAsBsB,oBACrB,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA;EAoFmB,MAAI;YAlFb,cAAc;YACd,eAAe;YACf;EAEH,WAAW;;;;;;;;;EASX;EACA,SAAS;;;;;;;EAQT;;;;;;;;EASA;;EAGA,SAAS;YACN,kBAAkB,QAAQ,0BAA0B;YACpD,mBAAmB,QAAQ,sBAAsB;;YAEjD;SAEH,mBAAmB,aAAa,KAAK;SAM/B,8BACZ,UAAU,sCACT,eAAe,QAAQ,IAAI,QAAQ,8BAA8B;EAkCnE,YAAmB,OAAI;WAEd,SAAS,UAAU,WAAW,UAAU;WAExC,OAAO,UAAU,QAAQ,QAAQ;EAE1C,QAAQ;WAIC,OAAO,UAAU,kBAAkB,QAAQ;WAE3C,MAAM,UAAU,0BAA0B,QAAQ;;;;;;;YAQjD,UACT,OAAO,iBACP,OAAO,SAAS;EAcjB,QAAQ,UAAU,cAAc,sBAC/B,SAAS,QAAQ,OAAO,KACtB,oBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA;;;;;EAuBD,SAAS,GAAG,sBACX,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,oBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA;;;;cCzKW,gBACZ,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC,0CAI/C,oBACT,QACA,WACA,WACA,SACA,eACA,0BACA,WACA;EAI4B,MAAI;YAFtB;EAEV,YAA4B,OAAI;EAIvB,QAAQ;EAIjB,WAAW;EAIX,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,GACA,WACA,SACA,eACA,0BACA,WACA,sBACA;EAiBD,MAAM,UAAU,0BACf,QAAQ,IACN,gBACF,GACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;;;;;;;;EA4BD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,gBACF,QACA,eACI,cAAc,WAAW,KAC7B,SACA,eACA,0BACA,WACA,sBACA;EA8BD,SAAS,UAAU,WAClB,UAAU,IACR,gBACF,QACA,eACI,cAAc,IAClB,SACA,eACA,0BACA,WACA,sBACA;EAoBD,OAAO,UAAU,QAChB,QAAQ,IACN,gBACF,QACA,WACA,WACA,GACA,eACA,0BACA,WACA,sBACA;;;;;;;EAuBD,MAAM,eAAe,iBACpB,OAAO,QACP,OAAO,SAAS,QAAQ,oBAAoB,cAC1C,gBACF,QACA,eACI,WAAW,oBACf,SACA,eACA,0BACA,WACA,sBACA;EAeQ,QAAQ,UAAU,cAAc,sBACxC,SAAS,QAAQ,OAAO,KACtB,gBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA,sBACA;;;;;EAwBD,QAAQ,UAAU,qCAAqC,gBACtD,QACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;EAmBQ,SAAS,GAAG,sBACpB,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,gBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA,OACA;EAkCD,OACC,IAAI,gBACH,QACA,WACA,SACA,WACA,WACA,eACA,gBAEC,SACF,QACA,WACA,SACA,WACA,eACA,0BACA,WACA,sBACA,cACA,gBACC,QACA,WACA,SACA,WACA,WACA,eACA"}
1
+ {"version":3,"file":"index-aBIcAiH5.d.mts","names":[],"sources":["../src/functions/BaseFunctionBuilder.ts","../src/functions/FunctionBuilder.ts"],"mappings":";;;;;;;;;uBAsBsB,oBACrB,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA;EAoFmB,MAAI;YAlFb,cAAc;YACd,eAAe;YACf;EAEH,WAAW;;;;;;;;;EASX;EACA,SAAS;;;;;;;EAQT;;;;;;;;EASA;;EAGA,SAAS;YACN,kBAAkB,QAAQ,0BAA0B;YACpD,mBAAmB,QAAQ,sBAAsB;;YAEjD;SAEH,mBAAmB,aAAa,KAAK;SAM/B,8BACZ,UAAU,sCACT,eAAe,QAAQ,IAAI,QAAQ,8BAA8B;EAkCnE,YAAmB,OAAI;WAEd,SAAS,UAAU,WAAW,UAAU;WAExC,OAAO,UAAU,QAAQ,QAAQ;EAE1C,QAAQ;WAIC,OAAO,UAAU,kBAAkB,QAAQ;WAE3C,MAAM,UAAU,0BAA0B,QAAQ;;;;;;;YAQjD,UACT,OAAO,iBACP,OAAO,SAAS;EAcjB,QAAQ,UAAU,cAAc,sBAC/B,SAAS,QAAQ,OAAO,KACtB,oBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA;;;;;EAuBD,SAAS,GAAG,sBACX,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,oBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA;;;;cCzKW,gBACZ,eAAe,0BACf,kBAAkB,0CAClB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC,0CAI/C,oBACT,QACA,WACA,WACA,SACA,eACA,0BACA,WACA;EAI4B,MAAI;YAFtB;EAEV,YAA4B,OAAI;EAIvB,QAAQ;EAIjB,WAAW;EAIX,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,GACA,WACA,SACA,eACA,0BACA,WACA,sBACA;EAiBD,MAAM,UAAU,0BACf,QAAQ,IACN,gBACF,GACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;;;;;;;;EA4BD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,gBACF,QACA,eACI,cAAc,WAAW,KAC7B,SACA,eACA,0BACA,WACA,sBACA;EA8BD,SAAS,UAAU,WAClB,UAAU,IACR,gBACF,QACA,eACI,cAAc,IAClB,SACA,eACA,0BACA,WACA,sBACA;EAoBD,OAAO,UAAU,QAChB,QAAQ,IACN,gBACF,QACA,WACA,WACA,GACA,eACA,0BACA,WACA,sBACA;;;;;;;EAuBD,MAAM,eAAe,iBACpB,OAAO,QACP,OAAO,SAAS,QAAQ,oBAAoB,cAC1C,gBACF,QACA,eACI,WAAW,oBACf,SACA,eACA,0BACA,WACA,sBACA;EAeQ,QAAQ,UAAU,cAAc,sBACxC,SAAS,QAAQ,OAAO,KACtB,gBACF,QACA,WACA,WACA,SACA,GACA,OACA,WACA,sBACA;;;;;EAwBD,QAAQ,UAAU,qCAAqC,gBACtD,QACA,WACA,WACA,SACA,eACA,0BACA,WACA,sBACA;;;;;EAmBQ,SAAS,GAAG,sBACpB,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,gBACF,QACA,WACA,WACA,SACA,eACA,0BACA,GACA,OACA;EAkCD,OACC,IAAI,gBACH,QACA,WACA,SACA,WACA,WACA,eACA,gBAEC,SACF,QACA,WACA,SACA,WACA,eACA,0BACA,WACA,sBACA,cACA,gBACC,QACA,WACA,SACA,WACA,WACA,eACA"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as snifferContext, n as ConstructType, r as sniffService, t as Construct } from "./Construct-BQALFCh2.cjs";
1
+ import { i as snifferContext, n as ConstructType, r as sniffService, t as Construct } from "./Construct-CFW0zjdD.cjs";
2
2
  import { n as LowerHttpMethod, r as RemoveUndefined, t as HttpMethod } from "./types-DMuSQeLL.cjs";
3
3
  import { i as TelemetryResponse, n as TelemetryContext, r as TelemetryRequest, t as Telemetry } from "./lambdaTelemetry-8vnmVZQ5.cjs";
4
4
  import { a as Stages, i as SeedContext, n as DeployedStage, o as TestStage, r as LocalStage, t as AnyStage } from "./stages-BSCF19o2.cjs";
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as snifferContext, n as ConstructType, r as sniffService, t as Construct } from "./Construct-QXnl3VqT.mjs";
1
+ import { i as snifferContext, n as ConstructType, r as sniffService, t as Construct } from "./Construct-B7AXn0xH.mjs";
2
2
  import { n as LowerHttpMethod, r as RemoveUndefined, t as HttpMethod } from "./types-DMuSQeLL.mjs";
3
3
  import { i as TelemetryResponse, n as TelemetryContext, r as TelemetryRequest, t as Telemetry } from "./lambdaTelemetry-8vnmVZQ5.mjs";
4
4
  import { a as Stages, i as SeedContext, n as DeployedStage, o as TestStage, r as LocalStage, t as AnyStage } from "./stages-BSCF19o2.mjs";