@venizia/ignis 0.4.7-0 → 0.4.7-2

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 (177) hide show
  1. package/LICENSE.md +1 -4
  2. package/README.md +2 -2
  3. package/dist/esm/base/applications/base.d.ts.map +1 -1
  4. package/dist/esm/base/applications/base.js +25 -18
  5. package/dist/esm/base/applications/base.js.map +1 -1
  6. package/dist/esm/base/applications/common/index.d.ts +1 -0
  7. package/dist/esm/base/applications/common/index.d.ts.map +1 -1
  8. package/dist/esm/base/applications/common/index.js +1 -0
  9. package/dist/esm/base/applications/common/index.js.map +1 -1
  10. package/dist/esm/base/applications/common/logger-startup.d.ts +11 -0
  11. package/dist/esm/base/applications/common/logger-startup.d.ts.map +1 -0
  12. package/dist/esm/base/applications/common/logger-startup.js +29 -0
  13. package/dist/esm/base/applications/common/logger-startup.js.map +1 -0
  14. package/dist/esm/base/applications/server.d.ts +14 -9
  15. package/dist/esm/base/applications/server.d.ts.map +1 -1
  16. package/dist/esm/base/applications/server.js +36 -29
  17. package/dist/esm/base/applications/server.js.map +1 -1
  18. package/dist/esm/common/constants.d.ts.map +1 -1
  19. package/dist/esm/common/constants.js +2 -2
  20. package/dist/esm/common/constants.js.map +1 -1
  21. package/dist/esm/components/auth/authenticate/component.js +2 -2
  22. package/dist/esm/components/auth/authenticate/component.js.map +1 -1
  23. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts +139 -136
  24. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts.map +1 -1
  25. package/dist/esm/components/auth/authenticate/controllers/factory.js +175 -172
  26. package/dist/esm/components/auth/authenticate/controllers/factory.js.map +1 -1
  27. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js +2 -2
  28. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js.map +1 -1
  29. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js +2 -2
  30. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js.map +1 -1
  31. package/dist/esm/components/auth/authorize/adapters/base-filtered.js +2 -2
  32. package/dist/esm/components/auth/authorize/adapters/base-filtered.js.map +1 -1
  33. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.d.ts.map +1 -1
  34. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js +2 -2
  35. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js.map +1 -1
  36. package/dist/esm/components/auth/models/entities/columns.d.ts +99 -0
  37. package/dist/esm/components/auth/models/entities/columns.d.ts.map +1 -0
  38. package/dist/esm/components/auth/models/entities/columns.js +133 -0
  39. package/dist/esm/components/auth/models/entities/columns.js.map +1 -0
  40. package/dist/esm/components/auth/models/entities/index.d.ts +1 -2
  41. package/dist/esm/components/auth/models/entities/index.d.ts.map +1 -1
  42. package/dist/esm/components/auth/models/entities/index.js +1 -2
  43. package/dist/esm/components/auth/models/entities/index.js.map +1 -1
  44. package/dist/esm/components/auth/models/entities/permission.model.d.ts +1 -12
  45. package/dist/esm/components/auth/models/entities/permission.model.d.ts.map +1 -1
  46. package/dist/esm/components/auth/models/entities/permission.model.js +1 -36
  47. package/dist/esm/components/auth/models/entities/permission.model.js.map +1 -1
  48. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts +1 -49
  49. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts.map +1 -1
  50. package/dist/esm/components/auth/models/entities/policy-definition.model.js +1 -69
  51. package/dist/esm/components/auth/models/entities/policy-definition.model.js.map +1 -1
  52. package/dist/esm/components/controller/grpc/grpc.component.js +2 -2
  53. package/dist/esm/components/controller/grpc/grpc.component.js.map +1 -1
  54. package/dist/esm/components/health-check/controller.js +5 -5
  55. package/dist/esm/components/health-check/controller.js.map +1 -1
  56. package/dist/esm/components/index.d.ts +0 -1
  57. package/dist/esm/components/index.d.ts.map +1 -1
  58. package/dist/esm/components/index.js +0 -1
  59. package/dist/esm/components/index.js.map +1 -1
  60. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.d.ts.map +1 -1
  61. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js +13 -9
  62. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js.map +1 -1
  63. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.d.ts.map +1 -1
  64. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js +5 -3
  65. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js.map +1 -1
  66. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.d.ts.map +1 -1
  67. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js +5 -5
  68. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js.map +1 -1
  69. package/dist/esm/components/mail/services/generators/verification-data.d.ts.map +1 -1
  70. package/dist/esm/components/mail/services/generators/verification-data.js +7 -3
  71. package/dist/esm/components/mail/services/generators/verification-data.js.map +1 -1
  72. package/dist/esm/components/mail/services/mail.service.js +7 -7
  73. package/dist/esm/components/mail/services/mail.service.js.map +1 -1
  74. package/dist/esm/components/mail/utilities/address.utility.d.ts +12 -8
  75. package/dist/esm/components/mail/utilities/address.utility.d.ts.map +1 -1
  76. package/dist/esm/components/mail/utilities/address.utility.js +30 -27
  77. package/dist/esm/components/mail/utilities/address.utility.js.map +1 -1
  78. package/dist/esm/components/mail/utilities/attachment.utility.d.ts +31 -29
  79. package/dist/esm/components/mail/utilities/attachment.utility.d.ts.map +1 -1
  80. package/dist/esm/components/mail/utilities/attachment.utility.js +97 -86
  81. package/dist/esm/components/mail/utilities/attachment.utility.js.map +1 -1
  82. package/dist/esm/components/mail/utilities/body.utility.d.ts +6 -4
  83. package/dist/esm/components/mail/utilities/body.utility.d.ts.map +1 -1
  84. package/dist/esm/components/mail/utilities/body.utility.js +14 -12
  85. package/dist/esm/components/mail/utilities/body.utility.js.map +1 -1
  86. package/dist/esm/components/mail/utilities/mime.utility.d.ts +23 -17
  87. package/dist/esm/components/mail/utilities/mime.utility.d.ts.map +1 -1
  88. package/dist/esm/components/mail/utilities/mime.utility.js +109 -102
  89. package/dist/esm/components/mail/utilities/mime.utility.js.map +1 -1
  90. package/dist/esm/components/mail/utilities/verification.utility.d.ts +8 -2
  91. package/dist/esm/components/mail/utilities/verification.utility.d.ts.map +1 -1
  92. package/dist/esm/components/mail/utilities/verification.utility.js +7 -5
  93. package/dist/esm/components/mail/utilities/verification.utility.js.map +1 -1
  94. package/dist/esm/components/socket-io/component.js +3 -3
  95. package/dist/esm/components/socket-io/component.js.map +1 -1
  96. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts +13 -11
  97. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts.map +1 -1
  98. package/dist/esm/components/socket-io/handlers/bun.handler.js +32 -30
  99. package/dist/esm/components/socket-io/handlers/bun.handler.js.map +1 -1
  100. package/dist/esm/components/static-asset/common/commit-token.d.ts +21 -16
  101. package/dist/esm/components/static-asset/common/commit-token.d.ts.map +1 -1
  102. package/dist/esm/components/static-asset/common/commit-token.js +35 -28
  103. package/dist/esm/components/static-asset/common/commit-token.js.map +1 -1
  104. package/dist/esm/components/static-asset/common/constants.d.ts +0 -2
  105. package/dist/esm/components/static-asset/common/constants.d.ts.map +1 -1
  106. package/dist/esm/components/static-asset/common/constants.js +1 -3
  107. package/dist/esm/components/static-asset/common/constants.js.map +1 -1
  108. package/dist/esm/components/static-asset/common/types.d.ts +0 -4
  109. package/dist/esm/components/static-asset/common/types.d.ts.map +1 -1
  110. package/dist/esm/components/static-asset/common/types.js.map +1 -1
  111. package/dist/esm/components/static-asset/component.js +2 -2
  112. package/dist/esm/components/static-asset/component.js.map +1 -1
  113. package/dist/esm/components/static-asset/controller/base.definition.d.ts +6 -6
  114. package/dist/esm/components/static-asset/controller/base.definition.d.ts.map +1 -1
  115. package/dist/esm/components/static-asset/controller/base.definition.js +224 -224
  116. package/dist/esm/components/static-asset/controller/base.definition.js.map +1 -1
  117. package/dist/esm/components/static-asset/controller/factory.d.ts +23 -23
  118. package/dist/esm/components/static-asset/controller/factory.d.ts.map +1 -1
  119. package/dist/esm/components/static-asset/controller/factory.js +105 -76
  120. package/dist/esm/components/static-asset/controller/factory.js.map +1 -1
  121. package/dist/esm/components/static-asset/controller/key-scope.d.ts +28 -26
  122. package/dist/esm/components/static-asset/controller/key-scope.d.ts.map +1 -1
  123. package/dist/esm/components/static-asset/controller/key-scope.js +34 -30
  124. package/dist/esm/components/static-asset/controller/key-scope.js.map +1 -1
  125. package/dist/esm/components/static-asset/controller/meta-link.d.ts +37 -33
  126. package/dist/esm/components/static-asset/controller/meta-link.d.ts.map +1 -1
  127. package/dist/esm/components/static-asset/controller/meta-link.js +86 -84
  128. package/dist/esm/components/static-asset/controller/meta-link.js.map +1 -1
  129. package/dist/esm/components/static-asset/controller/route-options.d.ts +18 -16
  130. package/dist/esm/components/static-asset/controller/route-options.d.ts.map +1 -1
  131. package/dist/esm/components/static-asset/controller/route-options.js +28 -26
  132. package/dist/esm/components/static-asset/controller/route-options.js.map +1 -1
  133. package/dist/esm/components/static-asset/models/base.model.js +3 -3
  134. package/dist/esm/components/static-asset/models/base.model.js.map +1 -1
  135. package/dist/esm/components/websocket/component.js +2 -2
  136. package/dist/esm/components/websocket/component.js.map +1 -1
  137. package/dist/esm/components/websocket/handlers/bun.handler.d.ts +6 -4
  138. package/dist/esm/components/websocket/handlers/bun.handler.d.ts.map +1 -1
  139. package/dist/esm/components/websocket/handlers/bun.handler.js +21 -19
  140. package/dist/esm/components/websocket/handlers/bun.handler.js.map +1 -1
  141. package/dist/esm/testing/assert-application-boots.d.ts +6 -1
  142. package/dist/esm/testing/assert-application-boots.d.ts.map +1 -1
  143. package/dist/esm/testing/assert-application-boots.js +139 -136
  144. package/dist/esm/testing/assert-application-boots.js.map +1 -1
  145. package/dist/esm/utilities/drizzle-result.utility.d.ts +6 -8
  146. package/dist/esm/utilities/drizzle-result.utility.d.ts.map +1 -1
  147. package/dist/esm/utilities/drizzle-result.utility.js +23 -49
  148. package/dist/esm/utilities/drizzle-result.utility.js.map +1 -1
  149. package/dist/esm/utilities/network.utility.d.ts.map +1 -1
  150. package/dist/esm/utilities/network.utility.js +2 -2
  151. package/dist/esm/utilities/network.utility.js.map +1 -1
  152. package/dist/presets/app/files/src/boot.test.ts +2 -2
  153. package/dist/presets/app/files/src/controllers/hello.controller.ts +2 -2
  154. package/dist/presets/app/preset.json +4 -4
  155. package/dist/presets/lib/preset.json +4 -4
  156. package/dist/presets/shared/files/.configs/formatters/.ignore +4 -0
  157. package/dist/presets/shared/files/.configs/lints/.ignore +4 -0
  158. package/dist/presets/shared/files/.configs/lints/eslint.config.mjs +4 -0
  159. package/dist/presets/shared/files/.configs/lints/oxlint.config.mts +4 -0
  160. package/dist/presets/shared/files/README.md +15 -0
  161. package/dist/presets/shared/files/src/index.test.ts +8 -0
  162. package/dist/presets/shared/files/src/index.ts +8 -0
  163. package/dist/presets/shared/files/tsconfig.json +20 -0
  164. package/dist/presets/shared/preset.json +35 -0
  165. package/package.json +11 -11
  166. package/dist/esm/components/auth/models/entities/role.model.d.ts +0 -10
  167. package/dist/esm/components/auth/models/entities/role.model.d.ts.map +0 -1
  168. package/dist/esm/components/auth/models/entities/role.model.js +0 -15
  169. package/dist/esm/components/auth/models/entities/role.model.js.map +0 -1
  170. package/dist/esm/components/auth/models/entities/user.model.d.ts +0 -28
  171. package/dist/esm/components/auth/models/entities/user.model.d.ts.map +0 -1
  172. package/dist/esm/components/auth/models/entities/user.model.js +0 -17
  173. package/dist/esm/components/auth/models/entities/user.model.js.map +0 -1
  174. package/dist/esm/components/controller/index.d.ts +0 -2
  175. package/dist/esm/components/controller/index.d.ts.map +0 -1
  176. package/dist/esm/components/controller/index.js +0 -7
  177. package/dist/esm/components/controller/index.js.map +0 -1
@@ -24,31 +24,31 @@ export interface IAssetControllerOptions {
24
24
  /** The upload labels, read off the multipart form. Every value arrives as text, so `sequence` is the one that needs converting. */
25
25
  /** One list: the reader below and the stale-caller warning must agree. */
26
26
  declare const UPLOAD_LABEL_NAMES: readonly ["principalType", "principalId", "variant", "sequence", "folderPath"];
27
- /** Names any label a caller put in the query - where the upload routes refuse it. */
28
- export declare const findLabelsInQuery: (opts: {
29
- query: Record<string, string>;
30
- names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;
31
- }) => string[];
32
- /** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */
33
- export declare const buildObjectLink: (opts: IObjectLocation & {
34
- basePath: string;
35
- hasConfiguredBucket?: boolean;
36
- rawObjectPath?: boolean;
37
- }) => string;
38
- /**
39
- * The served type comes from the object NAME, never the backend or the uploader: a renderable type on
40
- * the API origin is stored XSS. Exported so a hand-written route makes the same decision - the
41
- * backend's own content-type is dropped by `WHITELIST_HEADERS`.
42
- */
43
- export declare const resolveServedContentType: (opts: {
44
- helper: IStorageHelper;
45
- object: IObjectRef;
46
- }) => {
47
- contentType: string;
48
- isRenderable: boolean;
49
- };
50
27
  export declare class AssetControllerFactory extends BaseHelper {
51
28
  constructor();
29
+ /** Names any label a caller put in the query - where the upload routes refuse it. */
30
+ static findLabelsInQuery(opts: {
31
+ query: Record<string, string>;
32
+ names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;
33
+ }): string[];
34
+ /** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */
35
+ static buildObjectLink(opts: IObjectLocation & {
36
+ basePath: string;
37
+ hasConfiguredBucket?: boolean;
38
+ rawObjectPath?: boolean;
39
+ }): string;
40
+ /**
41
+ * The served type comes from the object NAME, never the backend or the uploader: a renderable type on
42
+ * the API origin is stored XSS. Public so a hand-written route makes the same decision - the
43
+ * backend's own content-type is dropped by `WHITELIST_HEADERS`.
44
+ */
45
+ static resolveServedContentType(opts: {
46
+ helper: IStorageHelper;
47
+ object: IObjectRef;
48
+ }): {
49
+ contentType: string;
50
+ isRenderable: boolean;
51
+ };
52
52
  static defineAssetController(opts: IAssetControllerOptions): {
53
53
  new (): {
54
54
  /** Clears the multipart spool files written by `parseMultipartBody({ storage: 'disk' })`. */
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,UAAU,EAEf,KAAK,cAAc,EAMpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EAKpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAG7B,MAAM,WAAW,CAAC;AAYnB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAChE,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iRAAiR;IACjR,QAAQ,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC,qHAAqH;IACrH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IAExC,oGAAoG;IACpG,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED,6OAA6O;AAC7O,mIAAmI;AACnI,0EAA0E;AAC1E,QAAA,MAAM,kBAAkB,gFAMd,CAAC;AAEX,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,GAAI,MAAM;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D,KAAG,MAAM,EAAyF,CAAC;AA8DpG,qJAAqJ;AACrJ,eAAO,MAAM,eAAe,GAC1B,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,KACA,MAQF,CAAC;AAcF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM;IAC7C,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;CACpB,KAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAS/C,CAAC;AAyDF,qBAAa,sBAAuB,SAAQ,UAAU;;IAKpD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,uBAAuB;;YAwDtD,6FAA6F;2CAC9D;gBAAE,KAAK,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,IAAI;uBAYrC,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBArRrB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwmCzB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAIL,KAAK,eAAe,EAEpB,KAAK,UAAU,EACf,KAAK,cAAc,EAKpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EAKpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAG7B,MAAM,WAAW,CAAC;AAOnB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAChE,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iRAAiR;IACjR,QAAQ,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC,qHAAqH;IACrH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IAExC,oGAAoG;IACpG,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED,6OAA6O;AAC7O,mIAAmI;AACnI,0EAA0E;AAC1E,QAAA,MAAM,kBAAkB,gFAMd,CAAC;AAuIX,qBAAa,sBAAuB,SAAQ,UAAU;;IAKpD,qFAAqF;IACrF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KAC5D,GAAG,MAAM,EAAE;IAIZ,qJAAqJ;IACrJ,MAAM,CAAC,eAAe,CACpB,IAAI,EAAE,eAAe,GAAG;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,GACA,MAAM;IAUT;;;;OAIG;IACH,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,GAAG;QACrF,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC;KACvB;IAeD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,uBAAuB;;YAwDtD,6FAA6F;2CAC9D;gBAAE,KAAK,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,IAAI;uBAYrC,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA5RzC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmoCL"}
@@ -9,16 +9,16 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  import { BaseRestController } from '../../../base/controllers/index.js';
11
11
  import { controller as controllerDecorator } from '../../../base/metadata/index.js';
12
- import { BaseStorageHelper, createContentDispositionHeader, isNotFoundError, parseMultipartBody, } from '@venizia/ignis-helpers';
13
- import { HTTP, resolveValueAsync } from '@venizia/ignis-helpers/common';
12
+ import { BaseStorageHelper, RequestUtility, StorageUtility, } from '@venizia/ignis-helpers';
13
+ import { HTTP, ResolverUtility } from '@venizia/ignis-helpers/common';
14
14
  import { BaseHelper, getError, UuidHelper } from '@venizia/ignis-helpers/core';
15
15
  import { readFileSync, rmSync } from 'node:fs';
16
16
  import { RENDERABLE_CONTENT_TYPES, StaticAssetErrors, DEFAULT_PENDING_PREFIX, META_LINK_CREATE_FAILED, WHITELIST_HEADERS, } from '../common/index.js';
17
- import { buildCommitToken, MetaLinkRecreateActions, readCommitToken } from '../common/index.js';
18
- import { buildAssetDefinitions } from './base.definition.js';
19
- import { assertKeyInScope, isKeyInScope, normalizeKeyPrefix, resolveScopedListPrefix, } from './key-scope.js';
20
- import { buildStoredUploadResult, createMetaLinkRow, refreshMetaLinkRows } from './meta-link.js';
21
- import { appendDeclaredLengthGuard, readRouteOverride } from './route-options.js';
17
+ import { AssetCommitToken, MetaLinkRecreateActions } from '../common/index.js';
18
+ import { AssetDefinitionBuilder } from './base.definition.js';
19
+ import { AssetKeyScope } from './key-scope.js';
20
+ import { AssetMetaLink } from './meta-link.js';
21
+ import { AssetRouteOptions } from './route-options.js';
22
22
  /** Hono ALREADY percent-decodes path params - a second decodeURIComponent throws on `report_100%.pdf` and turns `a%2Fb.png` into a DIFFERENT object; `isValidName`/`isValidPath` still run on this value, so traversal is still rejected. */
23
23
  /** The upload labels, read off the multipart form. Every value arrives as text, so `sequence` is the one that needs converting. */
24
24
  /** One list: the reader below and the stale-caller warning must agree. */
@@ -29,11 +29,11 @@ const UPLOAD_LABEL_NAMES = [
29
29
  'sequence',
30
30
  'folderPath',
31
31
  ];
32
- /** Names any label a caller put in the query - where the upload routes refuse it. */
33
- export const findLabelsInQuery = (opts) => (opts.names ?? UPLOAD_LABEL_NAMES).filter((name) => opts.query[name] !== undefined);
32
+ /** The body of `AssetControllerFactory.findLabelsInQuery`, callable from the helpers above the class. */
33
+ const listLabelsInQuery = (opts) => (opts.names ?? UPLOAD_LABEL_NAMES).filter((name) => opts.query[name] !== undefined);
34
34
  /** Refused before the body is read: a route that ignored them would store an unlabelled row. */
35
35
  const refuseLabelsInQuery = (opts) => {
36
- const names = findLabelsInQuery(opts);
36
+ const names = listLabelsInQuery(opts);
37
37
  if (names.length > 0) {
38
38
  throw getError({
39
39
  error: StaticAssetErrors.LABELS_IN_QUERY,
@@ -70,15 +70,7 @@ const resolveBucket = async (opts) => {
70
70
  if (configured === undefined) {
71
71
  return param ?? '';
72
72
  }
73
- return resolveValueAsync({ value: configured });
74
- };
75
- /** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */
76
- export const buildObjectLink = (opts) => {
77
- const { basePath, bucket, object } = opts;
78
- const { hasConfiguredBucket = false, rawObjectPath = false } = opts;
79
- const bucketSegment = hasConfiguredBucket ? '' : `/buckets/${bucket.name}`;
80
- const objectSegment = rawObjectPath ? object.key : encodeObjectPath(object.key);
81
- return `${basePath}${bucketSegment}/objects/${objectSegment}`;
73
+ return ResolverUtility.resolveValueAsync({ value: configured });
82
74
  };
83
75
  /** Mirrors `BaseStorageHelper.normalizeObjectName`, which is protected: `resolveObjectName` is offered the very name the helper would otherwise have written. */
84
76
  const defaultObjectName = ({ file }) => {
@@ -89,19 +81,6 @@ const defaultObjectName = ({ file }) => {
89
81
  }
90
82
  return `${folderPath.toLowerCase().replace(/ /g, '_')}/${normalizedFileName}`;
91
83
  };
92
- /**
93
- * The served type comes from the object NAME, never the backend or the uploader: a renderable type on
94
- * the API origin is stored XSS. Exported so a hand-written route makes the same decision - the
95
- * backend's own content-type is dropped by `WHITELIST_HEADERS`.
96
- */
97
- export const resolveServedContentType = (opts) => {
98
- const { helper, object } = opts;
99
- const candidate = helper.getMimeType({ filename: object.key }).toLowerCase().split(';')[0].trim();
100
- if (!RENDERABLE_CONTENT_TYPES.has(candidate)) {
101
- return { contentType: HTTP.HeaderValues.APPLICATION_OCTET_STREAM, isRenderable: false };
102
- }
103
- return { contentType: candidate, isRenderable: true };
104
- };
105
84
  /**
106
85
  * Reads one `Range` header. Only a single byte range is honoured - multipart ranges need a multipart
107
86
  * body no browser asks for here. An unsatisfiable or malformed range returns `null`, and the caller
@@ -145,6 +124,35 @@ export class AssetControllerFactory extends BaseHelper {
145
124
  constructor() {
146
125
  super({ scope: AssetControllerFactory.name });
147
126
  }
127
+ /** Names any label a caller put in the query - where the upload routes refuse it. */
128
+ static findLabelsInQuery(opts) {
129
+ return listLabelsInQuery(opts);
130
+ }
131
+ /** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */
132
+ static buildObjectLink(opts) {
133
+ const { basePath, bucket, object } = opts;
134
+ const { hasConfiguredBucket = false, rawObjectPath = false } = opts;
135
+ const bucketSegment = hasConfiguredBucket ? '' : `/buckets/${bucket.name}`;
136
+ const objectSegment = rawObjectPath ? object.key : encodeObjectPath(object.key);
137
+ return `${basePath}${bucketSegment}/objects/${objectSegment}`;
138
+ }
139
+ /**
140
+ * The served type comes from the object NAME, never the backend or the uploader: a renderable type on
141
+ * the API origin is stored XSS. Public so a hand-written route makes the same decision - the
142
+ * backend's own content-type is dropped by `WHITELIST_HEADERS`.
143
+ */
144
+ static resolveServedContentType(opts) {
145
+ const { helper, object } = opts;
146
+ const candidate = helper
147
+ .getMimeType({ filename: object.key })
148
+ .toLowerCase()
149
+ .split(';')[0]
150
+ .trim();
151
+ if (!RENDERABLE_CONTENT_TYPES.has(candidate)) {
152
+ return { contentType: HTTP.HeaderValues.APPLICATION_OCTET_STREAM, isRenderable: false };
153
+ }
154
+ return { contentType: candidate, isRenderable: true };
155
+ }
148
156
  static defineAssetController(opts) {
149
157
  const { controller, helper, options, useMetaLink, metaLink, storage } = opts;
150
158
  const { resolveObjectName, defineRoutesBefore, defineExtraRoutes } = opts;
@@ -161,18 +169,18 @@ export class AssetControllerFactory extends BaseHelper {
161
169
  }
162
170
  const scope = controller.keyPrefix === undefined
163
171
  ? undefined
164
- : normalizeKeyPrefix({ keyPrefix: controller.keyPrefix, helper, scope: name });
172
+ : AssetKeyScope.normalizePrefix({ keyPrefix: controller.keyPrefix, helper, scope: name });
165
173
  const keyPrefix = scope?.keyPrefix;
166
174
  // `maxFolderDepth` counts the caller's folders; the scope's own are configuration, not input.
167
175
  const objectKeyMaxDepth = maxFolderDepth + (scope?.depth ?? 0);
168
176
  // The component's own name under a scope: the original name must stay one segment, as without one.
169
177
  const isScopedDefaultNaming = keyPrefix !== undefined && !resolveObjectName && !options?.normalizeNameFn;
170
- const definitions = buildAssetDefinitions({ hasConfiguredBucket, rawObjectPath });
178
+ const definitions = AssetDefinitionBuilder.build({ hasConfiguredBucket, rawObjectPath });
171
179
  // The mount path may be declared with or without a leading slash; a link must carry exactly one.
172
180
  const normalizedBasePath = basePath.startsWith('/') ? basePath : `/${basePath}`;
173
181
  /** Only when the URL shape deviates: with neither option the storage helper's own link is left untouched. */
174
182
  const shapedLinkFn = hasConfiguredBucket || rawObjectPath
175
- ? (linkOptions) => buildObjectLink({
183
+ ? (linkOptions) => AssetControllerFactory.buildObjectLink({
176
184
  basePath: normalizedBasePath,
177
185
  bucket: linkOptions.bucket,
178
186
  object: linkOptions.object,
@@ -208,7 +216,7 @@ export class AssetControllerFactory extends BaseHelper {
208
216
  // A single-bucket application has no reason to expose bucket creation or deletion, so the
209
217
  // four bucket-management routes are not registered once `bucket` is configured.
210
218
  if (!hasConfiguredBucket) {
211
- const getBucketsRoute = readRouteOverride({ route: routes?.getBuckets });
219
+ const getBucketsRoute = AssetRouteOptions.readOverride({ route: routes?.getBuckets });
212
220
  if (getBucketsRoute.isEnabled) {
213
221
  this.bindRoute({
214
222
  configs: { ...definitions.GET_BUCKETS, ...getBucketsRoute.override },
@@ -219,7 +227,9 @@ export class AssetControllerFactory extends BaseHelper {
219
227
  },
220
228
  });
221
229
  }
222
- const getBucketByNameRoute = readRouteOverride({ route: routes?.getBucketByName });
230
+ const getBucketByNameRoute = AssetRouteOptions.readOverride({
231
+ route: routes?.getBucketByName,
232
+ });
223
233
  if (getBucketByNameRoute.isEnabled) {
224
234
  this.bindRoute({
225
235
  configs: { ...definitions.GET_BUCKET_BY_NAME, ...getBucketByNameRoute.override },
@@ -238,7 +248,7 @@ export class AssetControllerFactory extends BaseHelper {
238
248
  },
239
249
  });
240
250
  }
241
- const createBucketRoute = readRouteOverride({ route: routes?.createBucket });
251
+ const createBucketRoute = AssetRouteOptions.readOverride({ route: routes?.createBucket });
242
252
  if (createBucketRoute.isEnabled) {
243
253
  this.bindRoute({
244
254
  configs: { ...definitions.CREATE_BUCKET, ...createBucketRoute.override },
@@ -257,7 +267,7 @@ export class AssetControllerFactory extends BaseHelper {
257
267
  },
258
268
  });
259
269
  }
260
- const deleteBucketRoute = readRouteOverride({ route: routes?.deleteBucket });
270
+ const deleteBucketRoute = AssetRouteOptions.readOverride({ route: routes?.deleteBucket });
261
271
  if (deleteBucketRoute.isEnabled) {
262
272
  this.bindRoute({
263
273
  configs: { ...definitions.DELETE_BUCKET, ...deleteBucketRoute.override },
@@ -279,7 +289,9 @@ export class AssetControllerFactory extends BaseHelper {
279
289
  });
280
290
  }
281
291
  }
282
- const getObjectByNameRoute = readRouteOverride({ route: routes?.getObjectByName });
292
+ const getObjectByNameRoute = AssetRouteOptions.readOverride({
293
+ route: routes?.getObjectByName,
294
+ });
283
295
  if (getObjectByNameRoute.isEnabled) {
284
296
  this.bindRoute({
285
297
  configs: { ...definitions.GET_OBJECT_BY_NAME, ...getObjectByNameRoute.override },
@@ -301,14 +313,17 @@ export class AssetControllerFactory extends BaseHelper {
301
313
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
302
314
  }
303
315
  // Before any storage call: a key outside the scope must not even be probed.
304
- assertKeyInScope({ key: objectName, keyPrefix });
316
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
305
317
  const fileStat = await helper.getStat({
306
318
  bucket: { name: bucketName },
307
319
  object: { key: objectName },
308
320
  });
309
321
  const { size, metadata } = fileStat;
310
322
  applyMetadataHeaders({ ctx, metadata });
311
- const served = resolveServedContentType({ helper, object: { key: objectName } });
323
+ const served = AssetControllerFactory.resolveServedContentType({
324
+ helper,
325
+ object: { key: objectName },
326
+ });
312
327
  ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);
313
328
  ctx.header('x-content-type-options', 'nosniff');
314
329
  // Sandboxed even when renderable, so an unforeseen renderable type cannot reach this origin.
@@ -318,7 +333,10 @@ export class AssetControllerFactory extends BaseHelper {
318
333
  // A type outside the allow-list downloads instead of rendering; that is the XSS boundary.
319
334
  if (!served.isRenderable) {
320
335
  const inlineName = objectName.split('/').pop() ?? objectName;
321
- ctx.header(HTTP.Headers.CONTENT_DISPOSITION, createContentDispositionHeader({ filename: inlineName, type: 'attachment' }));
336
+ ctx.header(HTTP.Headers.CONTENT_DISPOSITION, RequestUtility.buildContentDispositionHeader({
337
+ filename: inlineName,
338
+ type: 'attachment',
339
+ }));
322
340
  }
323
341
  const range = readByteRange({ header: ctx.req.header('range'), size });
324
342
  if (range) {
@@ -341,7 +359,7 @@ export class AssetControllerFactory extends BaseHelper {
341
359
  },
342
360
  });
343
361
  }
344
- const downloadObjectByNameRoute = readRouteOverride({
362
+ const downloadObjectByNameRoute = AssetRouteOptions.readOverride({
345
363
  route: routes?.downloadObjectByName,
346
364
  });
347
365
  if (downloadObjectByNameRoute.isEnabled) {
@@ -368,7 +386,7 @@ export class AssetControllerFactory extends BaseHelper {
368
386
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
369
387
  }
370
388
  // Before any storage call: a key outside the scope must not even be probed.
371
- assertKeyInScope({ key: objectName, keyPrefix });
389
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
372
390
  const fileStat = await helper.getStat({
373
391
  bucket: { name: bucketName },
374
392
  object: { key: objectName },
@@ -376,11 +394,17 @@ export class AssetControllerFactory extends BaseHelper {
376
394
  const { size, metadata } = fileStat;
377
395
  applyMetadataHeaders({ ctx, metadata });
378
396
  // Download always attaches, so the served type only has to be honest, never renderable.
379
- const served = resolveServedContentType({ helper, object: { key: objectName } });
397
+ const served = AssetControllerFactory.resolveServedContentType({
398
+ helper,
399
+ object: { key: objectName },
400
+ });
380
401
  ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);
381
402
  ctx.header(HTTP.Headers.CONTENT_LENGTH, size.toString());
382
403
  const fileName = objectName.split('/').pop() ?? objectName;
383
- ctx.header(HTTP.Headers.CONTENT_DISPOSITION, createContentDispositionHeader({ filename: fileName, type: 'attachment' }));
404
+ ctx.header(HTTP.Headers.CONTENT_DISPOSITION, RequestUtility.buildContentDispositionHeader({
405
+ filename: fileName,
406
+ type: 'attachment',
407
+ }));
384
408
  ctx.header('x-content-type-options', 'nosniff');
385
409
  ctx.header(HTTP.Headers.CONTENT_SECURITY_POLICY, 'sandbox');
386
410
  const stream = await helper.getObjectStream({
@@ -394,11 +418,11 @@ export class AssetControllerFactory extends BaseHelper {
394
418
  },
395
419
  });
396
420
  }
397
- const uploadRoute = readRouteOverride({ route: routes?.upload });
421
+ const uploadRoute = AssetRouteOptions.readOverride({ route: routes?.upload });
398
422
  if (uploadRoute.isEnabled) {
399
423
  const uploadMiddleware = maxBytes === undefined
400
424
  ? uploadRoute.override.middleware
401
- : appendDeclaredLengthGuard({
425
+ : AssetRouteOptions.appendLengthGuard({
402
426
  middleware: uploadRoute.override.middleware,
403
427
  maxBytes,
404
428
  });
@@ -440,7 +464,7 @@ export class AssetControllerFactory extends BaseHelper {
440
464
  }
441
465
  };
442
466
  refuseLabelsInQuery({ query: ctx.req.query() });
443
- const { files: filesArray, fields } = await parseMultipartBody({
467
+ const { files: filesArray, fields } = await RequestUtility.parseMultipartBody({
444
468
  context: ctx,
445
469
  storage: options?.parseMultipartBody?.storage,
446
470
  uploadDir: options?.parseMultipartBody?.uploadDir,
@@ -501,7 +525,7 @@ export class AssetControllerFactory extends BaseHelper {
501
525
  defaultKey,
502
526
  })
503
527
  : defaultKey;
504
- if (!isKeyInScope({ key, keyPrefix })) {
528
+ if (!AssetKeyScope.isInScope({ key, keyPrefix })) {
505
529
  throw getError({
506
530
  error: StaticAssetErrors.OBJECT_KEY_OUT_OF_SCOPE,
507
531
  message: `Object key is outside the key prefix of this controller | key: ${key} | keyPrefix: ${keyPrefix}`,
@@ -533,7 +557,7 @@ export class AssetControllerFactory extends BaseHelper {
533
557
  bucket: uploadResult.bucket,
534
558
  object: uploadResult.object,
535
559
  });
536
- const createdMetaLink = await createMetaLinkRow({
560
+ const createdMetaLink = await AssetMetaLink.createRow({
537
561
  metaLink,
538
562
  helper,
539
563
  storage,
@@ -561,7 +585,7 @@ export class AssetControllerFactory extends BaseHelper {
561
585
  },
562
586
  });
563
587
  }
564
- const deleteObjectRoute = readRouteOverride({ route: routes?.deleteObject });
588
+ const deleteObjectRoute = AssetRouteOptions.readOverride({ route: routes?.deleteObject });
565
589
  if (deleteObjectRoute.isEnabled) {
566
590
  this.bindRoute({
567
591
  configs: { ...definitions.DELETE_OBJECT, ...deleteObjectRoute.override },
@@ -583,7 +607,7 @@ export class AssetControllerFactory extends BaseHelper {
583
607
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
584
608
  }
585
609
  // Before any storage call: a key outside the scope must not even be probed.
586
- assertKeyInScope({ key: objectName, keyPrefix });
610
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
587
611
  // Deliberately idempotent: S3 answers 200 for a key that was never there, and consumers
588
612
  // already depend on it. `disk` throws instead, so the two are reconciled here, not below.
589
613
  try {
@@ -593,14 +617,16 @@ export class AssetControllerFactory extends BaseHelper {
593
617
  });
594
618
  }
595
619
  catch (error) {
596
- if (!isNotFoundError({ error })) {
620
+ if (!StorageUtility.isNotFoundError({ error })) {
597
621
  throw error;
598
622
  }
599
623
  }
600
624
  if (!useMetaLink || !metaLink) {
601
625
  return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);
602
626
  }
603
- const deleteRepository = await resolveValueAsync({ value: metaLink.repository });
627
+ const deleteRepository = await ResolverUtility.resolveValueAsync({
628
+ value: metaLink.repository,
629
+ });
604
630
  deleteRepository
605
631
  .deleteAll({
606
632
  where: {
@@ -622,7 +648,7 @@ export class AssetControllerFactory extends BaseHelper {
622
648
  },
623
649
  });
624
650
  }
625
- const listObjectsRoute = readRouteOverride({ route: routes?.listObjects });
651
+ const listObjectsRoute = AssetRouteOptions.readOverride({ route: routes?.listObjects });
626
652
  if (listObjectsRoute.isEnabled) {
627
653
  this.bindRoute({
628
654
  configs: { ...definitions.LIST_OBJECTS, ...listObjectsRoute.override },
@@ -648,7 +674,7 @@ export class AssetControllerFactory extends BaseHelper {
648
674
  });
649
675
  }
650
676
  }
651
- const scoped = resolveScopedListPrefix({ prefix, keyPrefix });
677
+ const scoped = AssetKeyScope.resolveListPrefix({ prefix, keyPrefix });
652
678
  if (scoped.isOutOfScope) {
653
679
  return ctx.json([], HTTP.ResultCodes.RS_2.Ok);
654
680
  }
@@ -671,7 +697,7 @@ export class AssetControllerFactory extends BaseHelper {
671
697
  const pendingPrefix = directUpload.pendingPrefix ?? DEFAULT_PENDING_PREFIX;
672
698
  // The scope rides inside the pending key, so the commit, which strips `pendingPrefix`, lands inside it.
673
699
  const policyKeyPrefix = `${pendingPrefix}${keyPrefix ?? ''}`;
674
- const uploadPolicyRoute = readRouteOverride({ route: routes?.uploadPolicy });
700
+ const uploadPolicyRoute = AssetRouteOptions.readOverride({ route: routes?.uploadPolicy });
675
701
  if (uploadPolicyRoute.isEnabled) {
676
702
  this.bindRoute({
677
703
  configs: { ...definitions.UPLOAD_POLICY, ...uploadPolicyRoute.override },
@@ -704,7 +730,7 @@ export class AssetControllerFactory extends BaseHelper {
704
730
  policies.push({
705
731
  ...policy,
706
732
  objectName,
707
- commitToken: buildCommitToken({
733
+ commitToken: AssetCommitToken.build({
708
734
  payload: {
709
735
  bucket: bucketName,
710
736
  key: objectName,
@@ -718,7 +744,7 @@ export class AssetControllerFactory extends BaseHelper {
718
744
  },
719
745
  });
720
746
  }
721
- const uploadCommitRoute = readRouteOverride({ route: routes?.uploadCommit });
747
+ const uploadCommitRoute = AssetRouteOptions.readOverride({ route: routes?.uploadCommit });
722
748
  if (uploadCommitRoute.isEnabled) {
723
749
  this.bindRoute({
724
750
  configs: { ...definitions.UPLOAD_COMMIT, ...uploadCommitRoute.override },
@@ -734,7 +760,7 @@ export class AssetControllerFactory extends BaseHelper {
734
760
  const { commitToken, ...labels } = ctx.req.valid('json');
735
761
  // Verified BEFORE any storage call. That is what keeps this route from being a name
736
762
  // prober: a forged token fails without a round trip, so timing says nothing.
737
- const payload = readCommitToken({
763
+ const payload = AssetCommitToken.read({
738
764
  token: commitToken,
739
765
  secretKey: directUpload.secretKey,
740
766
  });
@@ -745,7 +771,7 @@ export class AssetControllerFactory extends BaseHelper {
745
771
  const pendingObject = { key: payload.key };
746
772
  const object = { key: payload.key.slice(pendingPrefix.length) };
747
773
  // A token another controller signed with the same secret must not land outside this scope.
748
- assertKeyInScope({ key: object.key, keyPrefix });
774
+ AssetKeyScope.assertInScope({ key: object.key, keyPrefix });
749
775
  // Before the copy, so a hook that throws leaves the object under the pending prefix
750
776
  // for a lifecycle rule, rather than stranding it at the final key.
751
777
  await directUpload.onCommit?.({ bucket: bucketRef, pendingObject, object });
@@ -757,14 +783,15 @@ export class AssetControllerFactory extends BaseHelper {
757
783
  // The copy IS the commit; removing the temporary object is cleanup. A failure here
758
784
  // leaves one object for the lifecycle rule, and failing the request would tell the
759
785
  // caller their upload did not work when it did.
760
- await helper
761
- .removeObject({ bucket: bucketRef, object: pendingObject })
762
- .catch((error) => {
786
+ try {
787
+ await helper.removeObject({ bucket: bucketRef, object: pendingObject });
788
+ }
789
+ catch (error) {
763
790
  this.logger
764
791
  .for('UPLOAD_COMMIT')
765
792
  .warn('Committed, but the pending object remains | key: %s | error: %s', pendingObject.key, error);
766
- });
767
- const link = buildObjectLink({
793
+ }
794
+ const link = AssetControllerFactory.buildObjectLink({
768
795
  basePath: normalizedBasePath,
769
796
  bucket: bucketRef,
770
797
  object,
@@ -777,11 +804,11 @@ export class AssetControllerFactory extends BaseHelper {
777
804
  if (useMetaLink && metaLink) {
778
805
  try {
779
806
  const fileStat = await helper.getStat({ bucket: bucketRef, object });
780
- const data = await createMetaLinkRow({
807
+ const data = await AssetMetaLink.createRow({
781
808
  metaLink,
782
809
  helper,
783
810
  storage,
784
- uploadResult: buildStoredUploadResult({
811
+ uploadResult: AssetMetaLink.buildStoredUploadResult({
785
812
  helper,
786
813
  bucket: bucketRef,
787
814
  object,
@@ -813,7 +840,9 @@ export class AssetControllerFactory extends BaseHelper {
813
840
  }
814
841
  }
815
842
  if (useMetaLink && metaLink) {
816
- const recreateMetaLinkRoute = readRouteOverride({ route: routes?.recreateMetaLink });
843
+ const recreateMetaLinkRoute = AssetRouteOptions.readOverride({
844
+ route: routes?.recreateMetaLink,
845
+ });
817
846
  if (recreateMetaLinkRoute.isEnabled) {
818
847
  this.bindRoute({
819
848
  configs: { ...definitions.RECREATE_METALINK, ...recreateMetaLinkRoute.override },
@@ -840,20 +869,20 @@ export class AssetControllerFactory extends BaseHelper {
840
869
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
841
870
  }
842
871
  // Before any storage call: a key outside the scope must not even be probed.
843
- assertKeyInScope({ key: objectName, keyPrefix });
872
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
844
873
  const bucketRef = { name: bucketName };
845
874
  const object = { key: objectName };
846
875
  const fileStat = await helper.getStat({ bucket: bucketRef, object });
847
876
  const link = options?.normalizeLinkFn
848
877
  ? options.normalizeLinkFn({ bucket: bucketRef, object })
849
- : buildObjectLink({
878
+ : AssetControllerFactory.buildObjectLink({
850
879
  basePath: normalizedBasePath,
851
880
  bucket: bucketRef,
852
881
  object,
853
882
  hasConfiguredBucket,
854
883
  rawObjectPath,
855
884
  });
856
- const refreshed = await refreshMetaLinkRows({
885
+ const refreshed = await AssetMetaLink.refreshRows({
857
886
  metaLink,
858
887
  helper,
859
888
  bucket: bucketRef,
@@ -872,11 +901,11 @@ export class AssetControllerFactory extends BaseHelper {
872
901
  }
873
902
  // Not atomic with the refresh above: two concurrent calls may both create, which the
874
903
  // table allows - rows per pair are deliberately not unique.
875
- const created = await createMetaLinkRow({
904
+ const created = await AssetMetaLink.createRow({
876
905
  metaLink,
877
906
  helper,
878
907
  storage,
879
- uploadResult: buildStoredUploadResult({
908
+ uploadResult: AssetMetaLink.buildStoredUploadResult({
880
909
  helper,
881
910
  bucket: bucketRef,
882
911
  object,