@venizia/ignis 0.4.6 → 0.4.7-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) 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 +19 -15
  5. package/dist/esm/base/applications/base.js.map +1 -1
  6. package/dist/esm/base/applications/server.d.ts +14 -9
  7. package/dist/esm/base/applications/server.d.ts.map +1 -1
  8. package/dist/esm/base/applications/server.js +36 -29
  9. package/dist/esm/base/applications/server.js.map +1 -1
  10. package/dist/esm/base/controllers/grpc/adapter.d.ts.map +1 -1
  11. package/dist/esm/base/controllers/grpc/adapter.js +5 -1
  12. package/dist/esm/base/controllers/grpc/adapter.js.map +1 -1
  13. package/dist/esm/base/middlewares/request-spy/request-spy.middleware.d.ts.map +1 -1
  14. package/dist/esm/base/middlewares/request-spy/request-spy.middleware.js +9 -3
  15. package/dist/esm/base/middlewares/request-spy/request-spy.middleware.js.map +1 -1
  16. package/dist/esm/common/constants.d.ts.map +1 -1
  17. package/dist/esm/common/constants.js +2 -2
  18. package/dist/esm/common/constants.js.map +1 -1
  19. package/dist/esm/components/api-reference/ui/scalar.d.ts.map +1 -1
  20. package/dist/esm/components/api-reference/ui/scalar.js +2 -1
  21. package/dist/esm/components/api-reference/ui/scalar.js.map +1 -1
  22. package/dist/esm/components/api-reference/ui/swagger.d.ts.map +1 -1
  23. package/dist/esm/components/api-reference/ui/swagger.js +2 -1
  24. package/dist/esm/components/api-reference/ui/swagger.js.map +1 -1
  25. package/dist/esm/components/auth/authenticate/component.js +2 -2
  26. package/dist/esm/components/auth/authenticate/component.js.map +1 -1
  27. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts +139 -136
  28. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts.map +1 -1
  29. package/dist/esm/components/auth/authenticate/controllers/factory.js +175 -172
  30. package/dist/esm/components/auth/authenticate/controllers/factory.js.map +1 -1
  31. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js +2 -2
  32. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js.map +1 -1
  33. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js +2 -2
  34. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js.map +1 -1
  35. package/dist/esm/components/auth/authenticate/services/bearer/abstract.service.d.ts.map +1 -1
  36. package/dist/esm/components/auth/authenticate/services/bearer/abstract.service.js +4 -2
  37. package/dist/esm/components/auth/authenticate/services/bearer/abstract.service.js.map +1 -1
  38. package/dist/esm/components/auth/authenticate/services/service/signer.service.d.ts.map +1 -1
  39. package/dist/esm/components/auth/authenticate/services/service/signer.service.js +6 -4
  40. package/dist/esm/components/auth/authenticate/services/service/signer.service.js.map +1 -1
  41. package/dist/esm/components/auth/authorize/adapters/base-filtered.js +2 -2
  42. package/dist/esm/components/auth/authorize/adapters/base-filtered.js.map +1 -1
  43. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.d.ts.map +1 -1
  44. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js +2 -2
  45. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js.map +1 -1
  46. package/dist/esm/components/auth/authorize/adapters/scoped-casbin/adapter.d.ts.map +1 -1
  47. package/dist/esm/components/auth/authorize/adapters/scoped-casbin/adapter.js +6 -3
  48. package/dist/esm/components/auth/authorize/adapters/scoped-casbin/adapter.js.map +1 -1
  49. package/dist/esm/components/auth/authorize/enforcers/casbin-module.d.ts.map +1 -1
  50. package/dist/esm/components/auth/authorize/enforcers/casbin-module.js +2 -1
  51. package/dist/esm/components/auth/authorize/enforcers/casbin-module.js.map +1 -1
  52. package/dist/esm/components/auth/authorize/enforcers/casbin.enforcer.d.ts.map +1 -1
  53. package/dist/esm/components/auth/authorize/enforcers/casbin.enforcer.js +9 -3
  54. package/dist/esm/components/auth/authorize/enforcers/casbin.enforcer.js.map +1 -1
  55. package/dist/esm/components/auth/models/entities/columns.d.ts +99 -0
  56. package/dist/esm/components/auth/models/entities/columns.d.ts.map +1 -0
  57. package/dist/esm/components/auth/models/entities/columns.js +133 -0
  58. package/dist/esm/components/auth/models/entities/columns.js.map +1 -0
  59. package/dist/esm/components/auth/models/entities/index.d.ts +1 -2
  60. package/dist/esm/components/auth/models/entities/index.d.ts.map +1 -1
  61. package/dist/esm/components/auth/models/entities/index.js +1 -2
  62. package/dist/esm/components/auth/models/entities/index.js.map +1 -1
  63. package/dist/esm/components/auth/models/entities/permission.model.d.ts +1 -12
  64. package/dist/esm/components/auth/models/entities/permission.model.d.ts.map +1 -1
  65. package/dist/esm/components/auth/models/entities/permission.model.js +1 -36
  66. package/dist/esm/components/auth/models/entities/permission.model.js.map +1 -1
  67. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts +1 -49
  68. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts.map +1 -1
  69. package/dist/esm/components/auth/models/entities/policy-definition.model.js +1 -69
  70. package/dist/esm/components/auth/models/entities/policy-definition.model.js.map +1 -1
  71. package/dist/esm/components/controller/grpc/grpc.component.js +2 -2
  72. package/dist/esm/components/controller/grpc/grpc.component.js.map +1 -1
  73. package/dist/esm/components/health-check/component.d.ts.map +1 -1
  74. package/dist/esm/components/health-check/component.js +5 -3
  75. package/dist/esm/components/health-check/component.js.map +1 -1
  76. package/dist/esm/components/health-check/controller.js +5 -5
  77. package/dist/esm/components/health-check/controller.js.map +1 -1
  78. package/dist/esm/components/index.d.ts +0 -1
  79. package/dist/esm/components/index.d.ts.map +1 -1
  80. package/dist/esm/components/index.js +0 -1
  81. package/dist/esm/components/index.js.map +1 -1
  82. package/dist/esm/components/mail/helpers/executors/bull-mq-executor.helper.d.ts.map +1 -1
  83. package/dist/esm/components/mail/helpers/executors/bull-mq-executor.helper.js +2 -1
  84. package/dist/esm/components/mail/helpers/executors/bull-mq-executor.helper.js.map +1 -1
  85. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.d.ts.map +1 -1
  86. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js +13 -9
  87. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js.map +1 -1
  88. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.d.ts.map +1 -1
  89. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js +5 -3
  90. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js.map +1 -1
  91. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.d.ts.map +1 -1
  92. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js +9 -7
  93. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js.map +1 -1
  94. package/dist/esm/components/mail/services/generators/verification-data.d.ts.map +1 -1
  95. package/dist/esm/components/mail/services/generators/verification-data.js +7 -3
  96. package/dist/esm/components/mail/services/generators/verification-data.js.map +1 -1
  97. package/dist/esm/components/mail/services/mail.service.d.ts.map +1 -1
  98. package/dist/esm/components/mail/services/mail.service.js +12 -9
  99. package/dist/esm/components/mail/services/mail.service.js.map +1 -1
  100. package/dist/esm/components/mail/utilities/address.utility.d.ts +12 -8
  101. package/dist/esm/components/mail/utilities/address.utility.d.ts.map +1 -1
  102. package/dist/esm/components/mail/utilities/address.utility.js +30 -27
  103. package/dist/esm/components/mail/utilities/address.utility.js.map +1 -1
  104. package/dist/esm/components/mail/utilities/attachment.utility.d.ts +31 -29
  105. package/dist/esm/components/mail/utilities/attachment.utility.d.ts.map +1 -1
  106. package/dist/esm/components/mail/utilities/attachment.utility.js +94 -86
  107. package/dist/esm/components/mail/utilities/attachment.utility.js.map +1 -1
  108. package/dist/esm/components/mail/utilities/body.utility.d.ts +6 -4
  109. package/dist/esm/components/mail/utilities/body.utility.d.ts.map +1 -1
  110. package/dist/esm/components/mail/utilities/body.utility.js +14 -12
  111. package/dist/esm/components/mail/utilities/body.utility.js.map +1 -1
  112. package/dist/esm/components/mail/utilities/mime.utility.d.ts +23 -17
  113. package/dist/esm/components/mail/utilities/mime.utility.d.ts.map +1 -1
  114. package/dist/esm/components/mail/utilities/mime.utility.js +109 -98
  115. package/dist/esm/components/mail/utilities/mime.utility.js.map +1 -1
  116. package/dist/esm/components/mail/utilities/verification.utility.d.ts +8 -2
  117. package/dist/esm/components/mail/utilities/verification.utility.d.ts.map +1 -1
  118. package/dist/esm/components/mail/utilities/verification.utility.js +7 -5
  119. package/dist/esm/components/mail/utilities/verification.utility.js.map +1 -1
  120. package/dist/esm/components/socket-io/component.js +3 -3
  121. package/dist/esm/components/socket-io/component.js.map +1 -1
  122. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts +13 -11
  123. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts.map +1 -1
  124. package/dist/esm/components/socket-io/handlers/bun.handler.js +32 -30
  125. package/dist/esm/components/socket-io/handlers/bun.handler.js.map +1 -1
  126. package/dist/esm/components/static-asset/common/commit-token.d.ts +21 -16
  127. package/dist/esm/components/static-asset/common/commit-token.d.ts.map +1 -1
  128. package/dist/esm/components/static-asset/common/commit-token.js +35 -28
  129. package/dist/esm/components/static-asset/common/commit-token.js.map +1 -1
  130. package/dist/esm/components/static-asset/common/constants.d.ts +0 -2
  131. package/dist/esm/components/static-asset/common/constants.d.ts.map +1 -1
  132. package/dist/esm/components/static-asset/common/constants.js +1 -3
  133. package/dist/esm/components/static-asset/common/constants.js.map +1 -1
  134. package/dist/esm/components/static-asset/common/types.d.ts +0 -4
  135. package/dist/esm/components/static-asset/common/types.d.ts.map +1 -1
  136. package/dist/esm/components/static-asset/common/types.js.map +1 -1
  137. package/dist/esm/components/static-asset/component.js +2 -2
  138. package/dist/esm/components/static-asset/component.js.map +1 -1
  139. package/dist/esm/components/static-asset/controller/base.definition.d.ts +6 -6
  140. package/dist/esm/components/static-asset/controller/base.definition.d.ts.map +1 -1
  141. package/dist/esm/components/static-asset/controller/base.definition.js +224 -224
  142. package/dist/esm/components/static-asset/controller/base.definition.js.map +1 -1
  143. package/dist/esm/components/static-asset/controller/factory.d.ts +23 -23
  144. package/dist/esm/components/static-asset/controller/factory.d.ts.map +1 -1
  145. package/dist/esm/components/static-asset/controller/factory.js +104 -74
  146. package/dist/esm/components/static-asset/controller/factory.js.map +1 -1
  147. package/dist/esm/components/static-asset/controller/key-scope.d.ts +28 -26
  148. package/dist/esm/components/static-asset/controller/key-scope.d.ts.map +1 -1
  149. package/dist/esm/components/static-asset/controller/key-scope.js +34 -30
  150. package/dist/esm/components/static-asset/controller/key-scope.js.map +1 -1
  151. package/dist/esm/components/static-asset/controller/meta-link.d.ts +37 -33
  152. package/dist/esm/components/static-asset/controller/meta-link.d.ts.map +1 -1
  153. package/dist/esm/components/static-asset/controller/meta-link.js +86 -84
  154. package/dist/esm/components/static-asset/controller/meta-link.js.map +1 -1
  155. package/dist/esm/components/static-asset/controller/route-options.d.ts +18 -16
  156. package/dist/esm/components/static-asset/controller/route-options.d.ts.map +1 -1
  157. package/dist/esm/components/static-asset/controller/route-options.js +28 -26
  158. package/dist/esm/components/static-asset/controller/route-options.js.map +1 -1
  159. package/dist/esm/components/static-asset/models/base.model.js +3 -3
  160. package/dist/esm/components/static-asset/models/base.model.js.map +1 -1
  161. package/dist/esm/components/websocket/component.js +2 -2
  162. package/dist/esm/components/websocket/component.js.map +1 -1
  163. package/dist/esm/components/websocket/handlers/bun.handler.d.ts +6 -4
  164. package/dist/esm/components/websocket/handlers/bun.handler.d.ts.map +1 -1
  165. package/dist/esm/components/websocket/handlers/bun.handler.js +21 -19
  166. package/dist/esm/components/websocket/handlers/bun.handler.js.map +1 -1
  167. package/dist/esm/testing/assert-application-boots.d.ts +6 -1
  168. package/dist/esm/testing/assert-application-boots.d.ts.map +1 -1
  169. package/dist/esm/testing/assert-application-boots.js +139 -129
  170. package/dist/esm/testing/assert-application-boots.js.map +1 -1
  171. package/dist/esm/utilities/drizzle-result.utility.d.ts +6 -8
  172. package/dist/esm/utilities/drizzle-result.utility.d.ts.map +1 -1
  173. package/dist/esm/utilities/drizzle-result.utility.js +23 -49
  174. package/dist/esm/utilities/drizzle-result.utility.js.map +1 -1
  175. package/dist/esm/utilities/network.utility.d.ts.map +1 -1
  176. package/dist/esm/utilities/network.utility.js +1 -1
  177. package/dist/esm/utilities/network.utility.js.map +1 -1
  178. package/dist/presets/app/files/src/boot.test.ts +2 -2
  179. package/dist/presets/app/files/src/controllers/hello.controller.ts +2 -2
  180. package/dist/presets/app/preset.json +4 -4
  181. package/dist/presets/lib/preset.json +4 -4
  182. package/dist/presets/shared/files/.configs/formatters/.ignore +4 -0
  183. package/dist/presets/shared/files/.configs/lints/.ignore +4 -0
  184. package/dist/presets/shared/files/.configs/lints/eslint.config.mjs +4 -0
  185. package/dist/presets/shared/files/.configs/lints/oxlint.config.mts +4 -0
  186. package/dist/presets/shared/files/README.md +15 -0
  187. package/dist/presets/shared/files/src/index.test.ts +8 -0
  188. package/dist/presets/shared/files/src/index.ts +8 -0
  189. package/dist/presets/shared/files/tsconfig.json +20 -0
  190. package/dist/presets/shared/preset.json +35 -0
  191. package/package.json +11 -11
  192. package/dist/esm/components/auth/models/entities/role.model.d.ts +0 -10
  193. package/dist/esm/components/auth/models/entities/role.model.d.ts.map +0 -1
  194. package/dist/esm/components/auth/models/entities/role.model.js +0 -15
  195. package/dist/esm/components/auth/models/entities/role.model.js.map +0 -1
  196. package/dist/esm/components/auth/models/entities/user.model.d.ts +0 -28
  197. package/dist/esm/components/auth/models/entities/user.model.d.ts.map +0 -1
  198. package/dist/esm/components/auth/models/entities/user.model.js +0 -17
  199. package/dist/esm/components/auth/models/entities/user.model.js.map +0 -1
  200. package/dist/esm/components/controller/index.d.ts +0 -2
  201. package/dist/esm/components/controller/index.d.ts.map +0 -1
  202. package/dist/esm/components/controller/index.js +0 -7
  203. 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsmCzB"}
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}`,
@@ -510,7 +534,7 @@ export class AssetControllerFactory extends BaseHelper {
510
534
  return key;
511
535
  }
512
536
  : options?.normalizeNameFn;
513
- uploaded = await helper.upload({
537
+ const result = await helper.upload({
514
538
  bucket: { name: bucketName },
515
539
  files: modifiedFiles,
516
540
  normalizeNameFn,
@@ -518,6 +542,7 @@ export class AssetControllerFactory extends BaseHelper {
518
542
  // Without this the helper re-validates against its own hard default of 2, so an app configured for a deeper tree spools the body and only then fails inside the helper.
519
543
  maxFolderDepth: objectKeyMaxDepth,
520
544
  });
545
+ uploaded = result;
521
546
  }
522
547
  finally {
523
548
  this.removeSpoolFiles({ paths: spoolPaths });
@@ -532,7 +557,7 @@ export class AssetControllerFactory extends BaseHelper {
532
557
  bucket: uploadResult.bucket,
533
558
  object: uploadResult.object,
534
559
  });
535
- const createdMetaLink = await createMetaLinkRow({
560
+ const createdMetaLink = await AssetMetaLink.createRow({
536
561
  metaLink,
537
562
  helper,
538
563
  storage,
@@ -560,7 +585,7 @@ export class AssetControllerFactory extends BaseHelper {
560
585
  },
561
586
  });
562
587
  }
563
- const deleteObjectRoute = readRouteOverride({ route: routes?.deleteObject });
588
+ const deleteObjectRoute = AssetRouteOptions.readOverride({ route: routes?.deleteObject });
564
589
  if (deleteObjectRoute.isEnabled) {
565
590
  this.bindRoute({
566
591
  configs: { ...definitions.DELETE_OBJECT, ...deleteObjectRoute.override },
@@ -582,7 +607,7 @@ export class AssetControllerFactory extends BaseHelper {
582
607
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
583
608
  }
584
609
  // Before any storage call: a key outside the scope must not even be probed.
585
- assertKeyInScope({ key: objectName, keyPrefix });
610
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
586
611
  // Deliberately idempotent: S3 answers 200 for a key that was never there, and consumers
587
612
  // already depend on it. `disk` throws instead, so the two are reconciled here, not below.
588
613
  try {
@@ -592,14 +617,16 @@ export class AssetControllerFactory extends BaseHelper {
592
617
  });
593
618
  }
594
619
  catch (error) {
595
- if (!isNotFoundError({ error })) {
620
+ if (!StorageUtility.isNotFoundError({ error })) {
596
621
  throw error;
597
622
  }
598
623
  }
599
624
  if (!useMetaLink || !metaLink) {
600
625
  return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);
601
626
  }
602
- const deleteRepository = await resolveValueAsync({ value: metaLink.repository });
627
+ const deleteRepository = await ResolverUtility.resolveValueAsync({
628
+ value: metaLink.repository,
629
+ });
603
630
  deleteRepository
604
631
  .deleteAll({
605
632
  where: {
@@ -621,7 +648,7 @@ export class AssetControllerFactory extends BaseHelper {
621
648
  },
622
649
  });
623
650
  }
624
- const listObjectsRoute = readRouteOverride({ route: routes?.listObjects });
651
+ const listObjectsRoute = AssetRouteOptions.readOverride({ route: routes?.listObjects });
625
652
  if (listObjectsRoute.isEnabled) {
626
653
  this.bindRoute({
627
654
  configs: { ...definitions.LIST_OBJECTS, ...listObjectsRoute.override },
@@ -647,7 +674,7 @@ export class AssetControllerFactory extends BaseHelper {
647
674
  });
648
675
  }
649
676
  }
650
- const scoped = resolveScopedListPrefix({ prefix, keyPrefix });
677
+ const scoped = AssetKeyScope.resolveListPrefix({ prefix, keyPrefix });
651
678
  if (scoped.isOutOfScope) {
652
679
  return ctx.json([], HTTP.ResultCodes.RS_2.Ok);
653
680
  }
@@ -670,13 +697,14 @@ export class AssetControllerFactory extends BaseHelper {
670
697
  const pendingPrefix = directUpload.pendingPrefix ?? DEFAULT_PENDING_PREFIX;
671
698
  // The scope rides inside the pending key, so the commit, which strips `pendingPrefix`, lands inside it.
672
699
  const policyKeyPrefix = `${pendingPrefix}${keyPrefix ?? ''}`;
673
- const uploadPolicyRoute = readRouteOverride({ route: routes?.uploadPolicy });
700
+ const uploadPolicyRoute = AssetRouteOptions.readOverride({ route: routes?.uploadPolicy });
674
701
  if (uploadPolicyRoute.isEnabled) {
675
702
  this.bindRoute({
676
703
  configs: { ...definitions.UPLOAD_POLICY, ...uploadPolicyRoute.override },
677
704
  }).to({
678
705
  handler: async (ctx) => {
679
- if (!(await directUpload.authorize({ context: ctx }))) {
706
+ const result = await directUpload.authorize({ context: ctx });
707
+ if (!result) {
680
708
  throw getError({ error: StaticAssetErrors.UPLOAD_NOT_AUTHORIZED });
681
709
  }
682
710
  const { files } = ctx.req.valid('json');
@@ -702,7 +730,7 @@ export class AssetControllerFactory extends BaseHelper {
702
730
  policies.push({
703
731
  ...policy,
704
732
  objectName,
705
- commitToken: buildCommitToken({
733
+ commitToken: AssetCommitToken.build({
706
734
  payload: {
707
735
  bucket: bucketName,
708
736
  key: objectName,
@@ -716,7 +744,7 @@ export class AssetControllerFactory extends BaseHelper {
716
744
  },
717
745
  });
718
746
  }
719
- const uploadCommitRoute = readRouteOverride({ route: routes?.uploadCommit });
747
+ const uploadCommitRoute = AssetRouteOptions.readOverride({ route: routes?.uploadCommit });
720
748
  if (uploadCommitRoute.isEnabled) {
721
749
  this.bindRoute({
722
750
  configs: { ...definitions.UPLOAD_COMMIT, ...uploadCommitRoute.override },
@@ -732,7 +760,7 @@ export class AssetControllerFactory extends BaseHelper {
732
760
  const { commitToken, ...labels } = ctx.req.valid('json');
733
761
  // Verified BEFORE any storage call. That is what keeps this route from being a name
734
762
  // prober: a forged token fails without a round trip, so timing says nothing.
735
- const payload = readCommitToken({
763
+ const payload = AssetCommitToken.read({
736
764
  token: commitToken,
737
765
  secretKey: directUpload.secretKey,
738
766
  });
@@ -743,7 +771,7 @@ export class AssetControllerFactory extends BaseHelper {
743
771
  const pendingObject = { key: payload.key };
744
772
  const object = { key: payload.key.slice(pendingPrefix.length) };
745
773
  // A token another controller signed with the same secret must not land outside this scope.
746
- assertKeyInScope({ key: object.key, keyPrefix });
774
+ AssetKeyScope.assertInScope({ key: object.key, keyPrefix });
747
775
  // Before the copy, so a hook that throws leaves the object under the pending prefix
748
776
  // for a lifecycle rule, rather than stranding it at the final key.
749
777
  await directUpload.onCommit?.({ bucket: bucketRef, pendingObject, object });
@@ -762,7 +790,7 @@ export class AssetControllerFactory extends BaseHelper {
762
790
  .for('UPLOAD_COMMIT')
763
791
  .warn('Committed, but the pending object remains | key: %s | error: %s', pendingObject.key, error);
764
792
  });
765
- const link = buildObjectLink({
793
+ const link = AssetControllerFactory.buildObjectLink({
766
794
  basePath: normalizedBasePath,
767
795
  bucket: bucketRef,
768
796
  object,
@@ -775,11 +803,11 @@ export class AssetControllerFactory extends BaseHelper {
775
803
  if (useMetaLink && metaLink) {
776
804
  try {
777
805
  const fileStat = await helper.getStat({ bucket: bucketRef, object });
778
- const data = await createMetaLinkRow({
806
+ const data = await AssetMetaLink.createRow({
779
807
  metaLink,
780
808
  helper,
781
809
  storage,
782
- uploadResult: buildStoredUploadResult({
810
+ uploadResult: AssetMetaLink.buildStoredUploadResult({
783
811
  helper,
784
812
  bucket: bucketRef,
785
813
  object,
@@ -811,7 +839,9 @@ export class AssetControllerFactory extends BaseHelper {
811
839
  }
812
840
  }
813
841
  if (useMetaLink && metaLink) {
814
- const recreateMetaLinkRoute = readRouteOverride({ route: routes?.recreateMetaLink });
842
+ const recreateMetaLinkRoute = AssetRouteOptions.readOverride({
843
+ route: routes?.recreateMetaLink,
844
+ });
815
845
  if (recreateMetaLinkRoute.isEnabled) {
816
846
  this.bindRoute({
817
847
  configs: { ...definitions.RECREATE_METALINK, ...recreateMetaLinkRoute.override },
@@ -838,20 +868,20 @@ export class AssetControllerFactory extends BaseHelper {
838
868
  throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });
839
869
  }
840
870
  // Before any storage call: a key outside the scope must not even be probed.
841
- assertKeyInScope({ key: objectName, keyPrefix });
871
+ AssetKeyScope.assertInScope({ key: objectName, keyPrefix });
842
872
  const bucketRef = { name: bucketName };
843
873
  const object = { key: objectName };
844
874
  const fileStat = await helper.getStat({ bucket: bucketRef, object });
845
875
  const link = options?.normalizeLinkFn
846
876
  ? options.normalizeLinkFn({ bucket: bucketRef, object })
847
- : buildObjectLink({
877
+ : AssetControllerFactory.buildObjectLink({
848
878
  basePath: normalizedBasePath,
849
879
  bucket: bucketRef,
850
880
  object,
851
881
  hasConfiguredBucket,
852
882
  rawObjectPath,
853
883
  });
854
- const refreshed = await refreshMetaLinkRows({
884
+ const refreshed = await AssetMetaLink.refreshRows({
855
885
  metaLink,
856
886
  helper,
857
887
  bucket: bucketRef,
@@ -870,11 +900,11 @@ export class AssetControllerFactory extends BaseHelper {
870
900
  }
871
901
  // Not atomic with the refresh above: two concurrent calls may both create, which the
872
902
  // table allows - rows per pair are deliberately not unique.
873
- const created = await createMetaLinkRow({
903
+ const created = await AssetMetaLink.createRow({
874
904
  metaLink,
875
905
  helper,
876
906
  storage,
877
- uploadResult: buildStoredUploadResult({
907
+ uploadResult: AssetMetaLink.buildStoredUploadResult({
878
908
  helper,
879
909
  bucket: bucketRef,
880
910
  object,