@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
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseRestController, type TRouteContext } from '@/base/controllers';\nimport { controller as controllerDecorator } from '@/base/metadata';\nimport {\n BaseStorageHelper,\n createContentDispositionHeader,\n type IObjectLocation,\n type IObjectMetadata,\n type IObjectRef,\n isNotFoundError,\n type IStorageHelper,\n type IUploadFile,\n type IPostPolicy,\n type IUploadResult,\n parseMultipartBody,\n type TUploadNaming,\n} from '@venizia/ignis-helpers';\nimport { HTTP, resolveValueAsync, type ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport type { AnyType, TValueOrAsyncResolver } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError, UuidHelper } from '@venizia/ignis-helpers/core';\nimport { type Env } from 'hono';\nimport { readFileSync, rmSync } from 'node:fs';\nimport {\n RENDERABLE_CONTENT_TYPES,\n StaticAssetErrors,\n type TBucketParams,\n type TDefineExtraRoutes,\n type TListQuery,\n type TMetaLinkConfig,\n DEFAULT_PENDING_PREFIX,\n META_LINK_CREATE_FAILED,\n type TObjectParams,\n type TUploadPolicyRequest,\n type TObjectNameResolver,\n type TStaticAssetExtraOptions,\n type TStaticAssetsComponentOptions,\n type TStaticAssetStorageType,\n type TUploadQuery,\n WHITELIST_HEADERS,\n} from '../common';\nimport { buildCommitToken, MetaLinkRecreateActions, readCommitToken } from '../common';\nimport { buildAssetDefinitions } from './base.definition';\nimport {\n assertKeyInScope,\n isKeyInScope,\n normalizeKeyPrefix,\n resolveScopedListPrefix,\n} from './key-scope';\nimport { buildStoredUploadResult, createMetaLinkRow, refreshMetaLinkRows } from './meta-link';\nimport { appendDeclaredLengthGuard, readRouteOverride } from './route-options';\n\nexport interface IAssetControllerOptions {\n controller: TStaticAssetsComponentOptions[string]['controller'];\n storage: TStaticAssetStorageType;\n helper: IStorageHelper;\n useMetaLink?: boolean;\n /** The table is erased at this seam on purpose. The public option types carry the real `Schema` and check it; inside the controller every read and write is on MetaLink COLUMNS, and threading a table type nobody here constrains through 700 lines of handler buys nothing. */\n metaLink?: TMetaLinkConfig<AnyType>;\n options?: TStaticAssetExtraOptions;\n\n /** Decides the stored object name of each uploaded file. Absent leaves the storage helper's own naming untouched. */\n resolveObjectName?: TObjectNameResolver;\n\n /** Registers the application's own routes on the generated controller, after every built-in one. */\n /** Registers the application's own routes BEFORE every built-in one, so a literal path wins over the catch-all `rawObjectPath` produces. */\n defineRoutesBefore?: TDefineExtraRoutes;\n defineExtraRoutes?: TDefineExtraRoutes;\n}\n\n/** 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. */\n/** The upload labels, read off the multipart form. Every value arrives as text, so `sequence` is the one that needs converting. */\n/** One list: the reader below and the stale-caller warning must agree. */\nconst UPLOAD_LABEL_NAMES = [\n 'principalType',\n 'principalId',\n 'variant',\n 'sequence',\n 'folderPath',\n] as const;\n\n/** Names any label a caller put in the query - where the upload routes refuse it. */\nexport const findLabelsInQuery = (opts: {\n query: Record<string, string>;\n names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;\n}): string[] => (opts.names ?? UPLOAD_LABEL_NAMES).filter((name) => opts.query[name] !== undefined);\n\n/** Refused before the body is read: a route that ignored them would store an unlabelled row. */\nconst refuseLabelsInQuery = (opts: {\n query: Record<string, string>;\n names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;\n reason?: string;\n}): void => {\n const names = findLabelsInQuery(opts);\n if (names.length > 0) {\n throw getError({\n error: StaticAssetErrors.LABELS_IN_QUERY,\n message: `${opts.reason ?? 'Upload labels belong in the request body, not the query'} | names: ${names.join(', ')}`,\n });\n }\n};\n\n/** The commit body carries four of the five: the object key - and so `folderPath` - was fixed when the policy was issued. */\nconst COMMIT_LABEL_NAMES = UPLOAD_LABEL_NAMES.filter((name) => name !== 'folderPath');\n\n// A multipart form hands strings; a JSON commit body may hand `sequence` as a number.\nconst readUploadLabels = (opts: {\n fields: Partial<Record<(typeof UPLOAD_LABEL_NAMES)[number], string | number>>;\n}): TUploadQuery => {\n const { fields } = opts;\n const read = (name: (typeof UPLOAD_LABEL_NAMES)[number]) => {\n const value = fields[name];\n return value === undefined || value === '' ? undefined : String(value);\n };\n\n const sequence = read('sequence');\n\n return {\n principalType: read('principalType'),\n principalId: read('principalId'),\n variant: read('variant'),\n sequence: sequence === undefined ? undefined : Number(sequence),\n folderPath: read('folderPath'),\n };\n};\n\nconst readObjectName: (rawObjectName: string) => string = (rawObjectName) => rawObjectName;\n\n/** Encodes an object path into a SINGLE url segment: `{objectName}` matches one segment only, so `/` must be percent-encoded too (Hono decodes it back before the handler reads the param). */\nconst encodeObjectPath: (objectPath: string) => string = (objectPath) => {\n return encodeURIComponent(objectPath);\n};\n\n/** The bucket one request works on: a configured value wins - called on every request, so an application may read an environment variable lazily - else the path param, which is only registered when there is no configured bucket. */\nconst resolveBucket = async (opts: {\n configured?: TValueOrAsyncResolver<string>;\n param?: string;\n}): Promise<string> => {\n const { configured, param } = opts;\n\n if (configured === undefined) {\n return param ?? '';\n }\n\n return resolveValueAsync({ value: configured });\n};\n\n/** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */\nexport const buildObjectLink = (\n opts: IObjectLocation & {\n basePath: string;\n hasConfiguredBucket?: boolean;\n rawObjectPath?: boolean;\n },\n): string => {\n const { basePath, bucket, object } = opts;\n const { hasConfiguredBucket = false, rawObjectPath = false } = opts;\n\n const bucketSegment = hasConfiguredBucket ? '' : `/buckets/${bucket.name}`;\n const objectSegment = rawObjectPath ? object.key : encodeObjectPath(object.key);\n\n return `${basePath}${bucketSegment}/objects/${objectSegment}`;\n};\n\n/** Mirrors `BaseStorageHelper.normalizeObjectName`, which is protected: `resolveObjectName` is offered the very name the helper would otherwise have written. */\nconst defaultObjectName: (opts: { file: TUploadNaming }) => string = ({ file }) => {\n const { originalName, folderPath } = file;\n const normalizedFileName = originalName.toLowerCase().replace(/ /g, '_');\n\n if (!folderPath) {\n return normalizedFileName;\n }\n\n return `${folderPath.toLowerCase().replace(/ /g, '_')}/${normalizedFileName}`;\n};\n\n/**\n * The served type comes from the object NAME, never the backend or the uploader: a renderable type on\n * the API origin is stored XSS. Exported so a hand-written route makes the same decision - the\n * backend's own content-type is dropped by `WHITELIST_HEADERS`.\n */\nexport const resolveServedContentType = (opts: {\n helper: IStorageHelper;\n object: IObjectRef;\n}): { contentType: string; isRenderable: boolean } => {\n const { helper, object } = opts;\n const candidate = helper.getMimeType({ filename: object.key }).toLowerCase().split(';')[0].trim();\n\n if (!RENDERABLE_CONTENT_TYPES.has(candidate)) {\n return { contentType: HTTP.HeaderValues.APPLICATION_OCTET_STREAM, isRenderable: false };\n }\n\n return { contentType: candidate, isRenderable: true };\n};\n\n/**\n * Reads one `Range` header. Only a single byte range is honoured - multipart ranges need a multipart\n * body no browser asks for here. An unsatisfiable or malformed range returns `null`, and the caller\n * serves the whole object, which is what RFC 9110 allows.\n */\nconst readByteRange = (opts: {\n header: string | undefined;\n size: number;\n}): { start: number; end: number } | null => {\n const { header, size } = opts;\n\n if (!header || size <= 0) {\n return null;\n }\n\n const match = /^bytes=(\\d*)-(\\d*)$/.exec(header.trim());\n if (!match) {\n return null;\n }\n\n const [, rawStart, rawEnd] = match;\n\n // `bytes=-500` means the LAST 500 bytes, not \"from 0 to 500\".\n if (!rawStart) {\n const suffixLength = Number(rawEnd);\n if (!Number.isInteger(suffixLength) || suffixLength <= 0) {\n return null;\n }\n\n return { start: Math.max(size - suffixLength, 0), end: size - 1 };\n }\n\n const start = Number(rawStart);\n const end = rawEnd ? Number(rawEnd) : size - 1;\n\n if (!Number.isInteger(start) || !Number.isInteger(end) || start > end || start >= size) {\n return null;\n }\n\n return { start, end: Math.min(end, size - 1) };\n};\n\n/** Sets whitelisted metadata headers on the response context. `content-type` is not among them. */\nconst applyMetadataHeaders: (opts: {\n ctx: TRouteContext<Env>;\n metadata: IObjectMetadata;\n}) => void = ({ ctx, metadata }) => {\n Object.entries(metadata).forEach(([key, value]) => {\n if (!WHITELIST_HEADERS.includes(key.toLowerCase() as (typeof WHITELIST_HEADERS)[number])) {\n return;\n }\n ctx.header(key.toLowerCase(), String(value).replace(/[\\r\\n]/g, ''));\n });\n};\n\nexport class AssetControllerFactory extends BaseHelper {\n constructor() {\n super({ scope: AssetControllerFactory.name });\n }\n\n static defineAssetController(opts: IAssetControllerOptions) {\n const { controller, helper, options, useMetaLink, metaLink, storage } = opts;\n const { resolveObjectName, defineRoutesBefore, defineExtraRoutes } = opts;\n const { directUpload } = controller;\n const { name, basePath, routes, isStrict = true, bucket, rawObjectPath = false } = controller;\n const maxFolderDepth = options?.maxFolderDepth ?? BaseStorageHelper.DEFAULT_MAX_FOLDER_DEPTH;\n const maxBytes = options?.maxBytes;\n\n const hasConfiguredBucket = bucket !== undefined;\n\n // With the bucket in the URL, the bucket routes stay unscoped and the scope spans every bucket.\n if (controller.keyPrefix !== undefined && !hasConfiguredBucket) {\n throw getError({\n message: `[${name}] keyPrefix needs controller.bucket | a bucket in the URL is a bucket the caller chooses, and the bucket routes cannot be scoped`,\n });\n }\n\n const scope =\n controller.keyPrefix === undefined\n ? undefined\n : normalizeKeyPrefix({ keyPrefix: controller.keyPrefix, helper, scope: name });\n const keyPrefix = scope?.keyPrefix;\n // `maxFolderDepth` counts the caller's folders; the scope's own are configuration, not input.\n const objectKeyMaxDepth = maxFolderDepth + (scope?.depth ?? 0);\n // The component's own name under a scope: the original name must stay one segment, as without one.\n const isScopedDefaultNaming =\n keyPrefix !== undefined && !resolveObjectName && !options?.normalizeNameFn;\n const definitions = buildAssetDefinitions({ hasConfiguredBucket, rawObjectPath });\n\n // The mount path may be declared with or without a leading slash; a link must carry exactly one.\n const normalizedBasePath = basePath.startsWith('/') ? basePath : `/${basePath}`;\n\n /** Only when the URL shape deviates: with neither option the storage helper's own link is left untouched. */\n const shapedLinkFn =\n hasConfiguredBucket || rawObjectPath\n ? (linkOptions: IObjectLocation) =>\n buildObjectLink({\n basePath: normalizedBasePath,\n bucket: linkOptions.bucket,\n object: linkOptions.object,\n hasConfiguredBucket,\n rawObjectPath,\n })\n : undefined;\n const normalizeLinkFn = options?.normalizeLinkFn ?? shapedLinkFn;\n\n @controllerDecorator({ path: basePath })\n class GeneratedStaticAssetController extends BaseRestController {\n constructor() {\n super({\n scope: name,\n path: basePath,\n isStrict,\n });\n }\n\n /** Clears the multipart spool files written by `parseMultipartBody({ storage: 'disk' })`. */\n removeSpoolFiles(spoolOptions: { paths: string[] }): void {\n for (const filePath of spoolOptions.paths) {\n try {\n rmSync(filePath, { force: true });\n } catch (error) {\n this.logger\n .for('UPLOAD')\n .error('Failed to remove spool file | path: %s | Error: %s', filePath, error);\n }\n }\n }\n\n override binding(): ValueOrPromise<void> {\n // First, so a literal path can win over the built-in catch-all `rawObjectPath` registers.\n defineRoutesBefore?.({ controller: this, helper, basePath: normalizedBasePath });\n\n // A single-bucket application has no reason to expose bucket creation or deletion, so the\n // four bucket-management routes are not registered once `bucket` is configured.\n if (!hasConfiguredBucket) {\n const getBucketsRoute = readRouteOverride({ route: routes?.getBuckets });\n if (getBucketsRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_BUCKETS, ...getBucketsRoute.override },\n }).to({\n handler: async (ctx) => {\n const buckets = await helper.getBuckets();\n return ctx.json(buckets, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const getBucketByNameRoute = readRouteOverride({ route: routes?.getBucketByName });\n if (getBucketByNameRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_BUCKET_BY_NAME, ...getBucketByNameRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const found = await helper.getBucket({ bucket: { name: bucketName } });\n return ctx.json(found, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const createBucketRoute = readRouteOverride({ route: routes?.createBucket });\n if (createBucketRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.CREATE_BUCKET, ...createBucketRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const createdBucket = await helper.createBucket({ bucket: { name: bucketName } });\n return ctx.json(createdBucket, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const deleteBucketRoute = readRouteOverride({ route: routes?.deleteBucket });\n if (deleteBucketRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.DELETE_BUCKET, ...deleteBucketRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const isRemovedBucket = await helper.removeBucket({\n bucket: { name: bucketName },\n });\n return ctx.json({ isDeleted: isRemovedBucket }, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n }\n\n const getObjectByNameRoute = readRouteOverride({ route: routes?.getObjectByName });\n if (getObjectByNameRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_OBJECT_BY_NAME, ...getObjectByNameRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n assertKeyInScope({ key: objectName, keyPrefix });\n\n const fileStat = await helper.getStat({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n const { size, metadata } = fileStat;\n applyMetadataHeaders({ ctx, metadata });\n\n const served = resolveServedContentType({ helper, object: { key: objectName } });\n ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);\n ctx.header('x-content-type-options', 'nosniff');\n // Sandboxed even when renderable, so an unforeseen renderable type cannot reach this origin.\n ctx.header(HTTP.Headers.CONTENT_SECURITY_POLICY, 'sandbox');\n // Advertised unconditionally: a player only offers seeking once it sees this.\n ctx.header('accept-ranges', 'bytes');\n\n // A type outside the allow-list downloads instead of rendering; that is the XSS boundary.\n if (!served.isRenderable) {\n const inlineName = objectName.split('/').pop() ?? objectName;\n ctx.header(\n HTTP.Headers.CONTENT_DISPOSITION,\n createContentDispositionHeader({ filename: inlineName, type: 'attachment' }),\n );\n }\n\n const range = readByteRange({ header: ctx.req.header('range'), size });\n\n if (range) {\n ctx.header(HTTP.Headers.CONTENT_LENGTH, String(range.end - range.start + 1));\n ctx.header(HTTP.Headers.CONTENT_RANGE, `bytes ${range.start}-${range.end}/${size}`);\n } else {\n ctx.header(HTTP.Headers.CONTENT_LENGTH, size.toString());\n }\n\n // The web stream is what a Response body wants, so no Node Readable sits in between.\n const stream = await helper.getObjectStream({\n bucket: { name: bucketName },\n object: { key: objectName },\n ...(range ? { range } : {}),\n });\n\n return new Response(stream, {\n headers: ctx.res.headers,\n status: range ? HTTP.ResultCodes.RS_2.PartialContent : HTTP.ResultCodes.RS_2.Ok,\n });\n },\n });\n }\n\n const downloadObjectByNameRoute = readRouteOverride({\n route: routes?.downloadObjectByName,\n });\n if (downloadObjectByNameRoute.isEnabled) {\n this.bindRoute({\n configs: {\n ...definitions.DOWNLOAD_OBJECT_BY_NAME,\n ...downloadObjectByNameRoute.override,\n },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n assertKeyInScope({ key: objectName, keyPrefix });\n\n const fileStat = await helper.getStat({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n const { size, metadata } = fileStat;\n applyMetadataHeaders({ ctx, metadata });\n\n // Download always attaches, so the served type only has to be honest, never renderable.\n const served = resolveServedContentType({ helper, object: { key: objectName } });\n ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);\n ctx.header(HTTP.Headers.CONTENT_LENGTH, size.toString());\n\n const fileName = objectName.split('/').pop() ?? objectName;\n ctx.header(\n HTTP.Headers.CONTENT_DISPOSITION,\n createContentDispositionHeader({ filename: fileName, type: 'attachment' }),\n );\n ctx.header('x-content-type-options', 'nosniff');\n ctx.header(HTTP.Headers.CONTENT_SECURITY_POLICY, 'sandbox');\n\n const stream = await helper.getObjectStream({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n return new Response(stream, {\n headers: ctx.res.headers,\n status: HTTP.ResultCodes.RS_2.Ok,\n });\n },\n });\n }\n\n const uploadRoute = readRouteOverride({ route: routes?.upload });\n if (uploadRoute.isEnabled) {\n const uploadMiddleware =\n maxBytes === undefined\n ? uploadRoute.override.middleware\n : appendDeclaredLengthGuard({\n middleware: uploadRoute.override.middleware,\n maxBytes,\n });\n\n this.bindRoute({\n configs: {\n ...definitions.UPLOAD,\n ...uploadRoute.override,\n middleware: uploadMiddleware,\n },\n }).to({\n handler: async (ctx) => {\n // A configured bucket drops `params` from this route entirely, so it is read only when it exists.\n const bucketParam = hasConfiguredBucket\n ? undefined\n : ctx.req.valid<TBucketParams>('param').bucketName;\n const bucketName = await resolveBucket({ configured: bucket, param: bucketParam });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const validateFolderPath = (folderPath: string) => {\n const normalizedFolder = folderPath.replace(/^\\/+|\\/+$/g, '');\n if (!normalizedFolder) {\n throw getError({ error: StaticAssetErrors.FOLDER_PATH_INVALID });\n }\n // maxFolderDepth excludes the filename, so it is compared directly against segment count.\n const folderSegments = normalizedFolder.split('/');\n if (folderSegments.length > maxFolderDepth) {\n throw getError({\n error: StaticAssetErrors.FOLDER_DEPTH_EXCEEDED,\n message: `Folder path exceeds max depth of ${maxFolderDepth}`,\n });\n }\n const invalidSegmentIndex = folderSegments.findIndex(\n (segment) => !helper.isValidSegment({ segment }),\n );\n if (invalidSegmentIndex !== -1) {\n throw getError({\n error: StaticAssetErrors.FOLDER_SEGMENT_INVALID,\n message: `Invalid folder path segment: ${folderSegments[invalidSegmentIndex]}`,\n });\n }\n };\n\n refuseLabelsInQuery({ query: ctx.req.query() });\n\n const { files: filesArray, fields } = await parseMultipartBody({\n context: ctx,\n storage: options?.parseMultipartBody?.storage,\n uploadDir: options?.parseMultipartBody?.uploadDir,\n });\n\n // Labels travel with the payload, not the URL, so the folder check waits for the parse.\n const query = readUploadLabels({ fields });\n\n const folderPath = query.folderPath;\n if (folderPath) {\n validateFolderPath(folderPath);\n }\n\n const spoolPaths = filesArray\n .map((file) => file.path)\n .filter((filePath): filePath is string => Boolean(filePath));\n\n let uploaded: IUploadResult[];\n try {\n // `storage: 'disk'` spools the payload to `uploadDir` and returns `path` instead of `buffer`; the storage helpers only ever write `buffer`, so it must be read back.\n const modifiedFiles: IUploadFile[] = filesArray.map((file) => {\n const buffer = file.buffer ?? (file.path ? readFileSync(file.path) : undefined);\n\n if (!buffer?.length) {\n throw getError({\n error: StaticAssetErrors.FILE_EMPTY,\n message: `Empty file content | name: ${file.originalname}`,\n });\n }\n\n // Authoritative: `buffer.length`, not the client-declared `size`.\n if (maxBytes !== undefined && buffer.length > maxBytes) {\n throw getError({\n error: StaticAssetErrors.UPLOAD_TOO_LARGE,\n message: `File ${file.originalname} of ${buffer.length} bytes exceeds the maximum of ${maxBytes}`,\n });\n }\n\n return {\n originalName: file.originalname,\n mimetype: file.mimetype,\n buffer,\n size: file.size,\n encoding: file.encoding,\n folderPath: folderPath ?? undefined,\n };\n });\n\n // Built per request: the hook is offered the bucket, which only the route knows. With\n // neither hook nor scope, `normalizeNameFn` stays exactly as configured. Under a scope,\n // the component's own default is placed inside it; an application hook's key is\n // checked, never rewritten, because the application may record that key elsewhere.\n const normalizeNameFn =\n resolveObjectName || keyPrefix !== undefined\n ? (naming: { file: TUploadNaming }) => {\n if (\n isScopedDefaultNaming &&\n !helper.isValidSegment({ segment: naming.file.originalName })\n ) {\n throw getError({ message: '[upload] Invalid original file name' });\n }\n\n const defaultKey = options?.normalizeNameFn\n ? options.normalizeNameFn(naming)\n : `${keyPrefix ?? ''}${defaultObjectName(naming)}`;\n\n const key = resolveObjectName\n ? resolveObjectName({\n bucket: { name: bucketName },\n file: naming.file,\n defaultKey,\n })\n : defaultKey;\n\n if (!isKeyInScope({ key, keyPrefix })) {\n throw getError({\n error: StaticAssetErrors.OBJECT_KEY_OUT_OF_SCOPE,\n message: `Object key is outside the key prefix of this controller | key: ${key} | keyPrefix: ${keyPrefix}`,\n });\n }\n\n return key;\n }\n : options?.normalizeNameFn;\n\n uploaded = await helper.upload({\n bucket: { name: bucketName },\n files: modifiedFiles,\n normalizeNameFn,\n normalizeLinkFn,\n // 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.\n maxFolderDepth: objectKeyMaxDepth,\n });\n } finally {\n this.removeSpoolFiles({ paths: spoolPaths });\n }\n\n if (!useMetaLink || !metaLink) {\n return ctx.json(uploaded, HTTP.ResultCodes.RS_2.Ok);\n }\n\n const results: IUploadResult[] = [];\n for (const uploadResult of uploaded) {\n try {\n const fileStat = await helper.getStat({\n bucket: uploadResult.bucket,\n object: uploadResult.object,\n });\n\n const createdMetaLink = await createMetaLinkRow({\n metaLink,\n helper,\n storage,\n uploadResult,\n fileStat,\n query,\n });\n\n results.push({ ...uploadResult, metaLink: { data: createdMetaLink } });\n } catch (error) {\n this.logger\n .for('UPLOAD')\n .error(\n 'Failed to create MetaLink | objectName: %s | Error: %s',\n uploadResult.object.key,\n error,\n );\n results.push({\n ...uploadResult,\n // A CODE, never the driver text. This handler returns 200, so it bypasses the\n // error middleware and `database.handler` - the two places that strip\n // `detail`/`table`/`constraint` - and shipped raw constraint names to the client.\n // The real error is already logged in full immediately above.\n metaLink: { error: META_LINK_CREATE_FAILED },\n });\n }\n }\n return ctx.json(results, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const deleteObjectRoute = readRouteOverride({ route: routes?.deleteObject });\n if (deleteObjectRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.DELETE_OBJECT, ...deleteObjectRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n assertKeyInScope({ key: objectName, keyPrefix });\n\n // Deliberately idempotent: S3 answers 200 for a key that was never there, and consumers\n // already depend on it. `disk` throws instead, so the two are reconciled here, not below.\n try {\n await helper.removeObject({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n } catch (error) {\n if (!isNotFoundError({ error })) {\n throw error;\n }\n }\n\n if (!useMetaLink || !metaLink) {\n return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);\n }\n\n const deleteRepository = await resolveValueAsync({ value: metaLink.repository });\n deleteRepository\n .deleteAll({\n where: {\n bucketName,\n objectName,\n },\n })\n .then(() => {\n this.logger\n .for('DELETE_OBJECT')\n .info('Successfully to delete MetaLink for %s/%s', bucketName, objectName);\n })\n .catch((error) => {\n this.logger\n .for('DELETE_OBJECT')\n .error(\n 'Failed to delete MetaLink | bucket: %s | objectName: %s | Error: %s',\n bucketName,\n objectName,\n error,\n );\n });\n\n return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const listObjectsRoute = readRouteOverride({ route: routes?.listObjects });\n if (listObjectsRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.LIST_OBJECTS, ...listObjectsRoute.override },\n }).to({\n handler: async (ctx) => {\n // A configured bucket drops `params` from this route entirely, so it is read only when it exists.\n const bucketParam = hasConfiguredBucket\n ? undefined\n : ctx.req.valid<TBucketParams>('param').bucketName;\n const bucketName = await resolveBucket({ configured: bucket, param: bucketParam });\n const { prefix, recursive, maxKeys } = ctx.req.valid<TListQuery>('query');\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n // A NaN or 0 maxKeys is silently treated as \"unlimited\" by the storage backends, so an unparsable value must be rejected instead of forwarded.\n let resolvedMaxKeys: number | undefined;\n if (maxKeys !== undefined) {\n resolvedMaxKeys = Number(maxKeys);\n\n if (!Number.isInteger(resolvedMaxKeys) || resolvedMaxKeys < 1) {\n throw getError({\n error: StaticAssetErrors.MAX_KEYS_INVALID,\n message: `Invalid maxKeys | Expected a positive integer | value: ${maxKeys}`,\n });\n }\n }\n\n const scoped = resolveScopedListPrefix({ prefix, keyPrefix });\n if (scoped.isOutOfScope) {\n return ctx.json([], HTTP.ResultCodes.RS_2.Ok);\n }\n\n const objects = await helper.listObjects({\n bucket: { name: bucketName },\n prefix: scoped.prefix,\n useRecursive: recursive === 'true',\n maxKeys: resolvedMaxKeys,\n });\n\n return ctx.json(objects, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n if (directUpload) {\n if (!hasConfiguredBucket) {\n throw getError({\n message: `[${name}] directUpload needs controller.bucket | a policy names one bucket, and a bucket in the URL is a bucket the caller chooses`,\n });\n }\n\n const pendingPrefix = directUpload.pendingPrefix ?? DEFAULT_PENDING_PREFIX;\n // The scope rides inside the pending key, so the commit, which strips `pendingPrefix`, lands inside it.\n const policyKeyPrefix = `${pendingPrefix}${keyPrefix ?? ''}`;\n\n const uploadPolicyRoute = readRouteOverride({ route: routes?.uploadPolicy });\n if (uploadPolicyRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.UPLOAD_POLICY, ...uploadPolicyRoute.override },\n }).to({\n handler: async (ctx) => {\n if (!(await directUpload.authorize({ context: ctx }))) {\n throw getError({ error: StaticAssetErrors.UPLOAD_NOT_AUTHORIZED });\n }\n\n const { files } = ctx.req.valid<TUploadPolicyRequest>('json');\n const bucketName = await resolveBucket({ configured: bucket });\n\n const policies: Array<IPostPolicy & { objectName: string; commitToken: string }> =\n [];\n for (const file of files) {\n if (file.size !== undefined && file.size > directUpload.maxBytes) {\n throw getError({\n error: StaticAssetErrors.UPLOAD_TOO_LARGE,\n message: `File '${file.fileName}' is ${file.size} bytes, over the ${directUpload.maxBytes} the policy allows`,\n });\n }\n\n // Generated, never taken from the caller: a key the caller picks is a key the caller\n // can collide with, and the pending object is the one thing a policy authorizes.\n const objectName = `${policyKeyPrefix}${UuidHelper.getInstance().v4()}/${file.fileName}`;\n const policy = await helper.presignPost({\n bucket: { name: bucketName },\n keyPrefix: policyKeyPrefix,\n maxBytes: directUpload.maxBytes,\n contentType: file.contentType,\n expiresIn: directUpload.expiresIn,\n });\n\n policies.push({\n ...policy,\n objectName,\n commitToken: buildCommitToken({\n payload: {\n bucket: bucketName,\n key: objectName,\n expiresAt: new Date(policy.expiresAt).getTime(),\n },\n secretKey: directUpload.secretKey,\n }),\n });\n }\n\n return ctx.json(policies, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const uploadCommitRoute = readRouteOverride({ route: routes?.uploadCommit });\n if (uploadCommitRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.UPLOAD_COMMIT, ...uploadCommitRoute.override },\n }).to({\n handler: async (ctx) => {\n const commitQuery = ctx.req.query();\n refuseLabelsInQuery({ query: commitQuery, names: COMMIT_LABEL_NAMES });\n refuseLabelsInQuery({\n query: commitQuery,\n names: ['folderPath'],\n reason:\n 'folderPath was decided when the upload policy was issued; the commit route cannot move the object',\n });\n\n const { commitToken, ...labels } = ctx.req.valid<\n { commitToken: string } & TUploadQuery\n >('json');\n\n // Verified BEFORE any storage call. That is what keeps this route from being a name\n // prober: a forged token fails without a round trip, so timing says nothing.\n const payload = readCommitToken({\n token: commitToken,\n secretKey: directUpload.secretKey,\n });\n\n // Labels, not authorization - the token deliberately carries no business fields, so\n // they travel beside it rather than inside it.\n const query = readUploadLabels({ fields: labels });\n\n const bucketRef = { name: payload.bucket };\n const pendingObject = { key: payload.key };\n const object = { key: payload.key.slice(pendingPrefix.length) };\n\n // A token another controller signed with the same secret must not land outside this scope.\n assertKeyInScope({ key: object.key, keyPrefix });\n\n // Before the copy, so a hook that throws leaves the object under the pending prefix\n // for a lifecycle rule, rather than stranding it at the final key.\n await directUpload.onCommit?.({ bucket: bucketRef, pendingObject, object });\n\n await helper.copyObject({\n bucket: bucketRef,\n source: pendingObject,\n destination: object,\n });\n // The copy IS the commit; removing the temporary object is cleanup. A failure here\n // leaves one object for the lifecycle rule, and failing the request would tell the\n // caller their upload did not work when it did.\n await helper\n .removeObject({ bucket: bucketRef, object: pendingObject })\n .catch((error) => {\n this.logger\n .for('UPLOAD_COMMIT')\n .warn(\n 'Committed, but the pending object remains | key: %s | error: %s',\n pendingObject.key,\n error,\n );\n });\n\n const link = buildObjectLink({\n basePath: normalizedBasePath,\n bucket: bucketRef,\n object,\n hasConfiguredBucket,\n rawObjectPath,\n });\n\n // The two paths have to agree: without this a client reading `metaLink` off the\n // response renders an empty state with no error - the failure nobody reports.\n let metaLinkResult: IUploadResult['metaLink'];\n if (useMetaLink && metaLink) {\n try {\n const fileStat = await helper.getStat({ bucket: bucketRef, object });\n const data = await createMetaLinkRow({\n metaLink,\n helper,\n storage,\n uploadResult: buildStoredUploadResult({\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n }),\n fileStat,\n query,\n });\n\n metaLinkResult = { data };\n } catch (error) {\n // The object IS committed by now. A 500 would send the caller back with a token\n // whose source no longer exists, so this rides the body as a code, like UPLOAD.\n this.logger\n .for('UPLOAD_COMMIT')\n .error(\n 'Failed to create MetaLink | objectName: %s | Error: %s',\n object.key,\n error,\n );\n metaLinkResult = { error: META_LINK_CREATE_FAILED };\n }\n }\n\n return ctx.json(\n {\n bucket: bucketRef,\n object,\n link,\n ...(metaLinkResult === undefined ? {} : { metaLink: metaLinkResult }),\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n },\n });\n }\n }\n\n if (useMetaLink && metaLink) {\n const recreateMetaLinkRoute = readRouteOverride({ route: routes?.recreateMetaLink });\n if (recreateMetaLinkRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.RECREATE_METALINK, ...recreateMetaLinkRoute.override },\n }).to({\n handler: async (ctx) => {\n // This route takes no labels anywhere: one in the query would land an unlabelled row.\n refuseLabelsInQuery({\n query: ctx.req.query(),\n reason:\n 'This route recreates a MetaLink for an existing object and takes no labels',\n });\n\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n assertKeyInScope({ key: objectName, keyPrefix });\n\n const bucketRef = { name: bucketName };\n const object = { key: objectName };\n const fileStat = await helper.getStat({ bucket: bucketRef, object });\n\n const link = options?.normalizeLinkFn\n ? options.normalizeLinkFn({ bucket: bucketRef, object })\n : buildObjectLink({\n basePath: normalizedBasePath,\n bucket: bucketRef,\n object,\n hasConfiguredBucket,\n rawObjectPath,\n });\n\n const refreshed = await refreshMetaLinkRows({\n metaLink,\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n });\n\n if (refreshed.count > 0) {\n return ctx.json(\n {\n success: true,\n action: MetaLinkRecreateActions.REFRESHED,\n count: refreshed.count,\n metaLink: refreshed.data[0],\n metaLinks: refreshed.data,\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n }\n\n // Not atomic with the refresh above: two concurrent calls may both create, which the\n // table allows - rows per pair are deliberately not unique.\n const created = await createMetaLinkRow({\n metaLink,\n helper,\n storage,\n uploadResult: buildStoredUploadResult({\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n }),\n fileStat,\n query: {},\n });\n\n return ctx.json(\n {\n success: true,\n action: MetaLinkRecreateActions.CREATED,\n count: 1,\n metaLink: created,\n metaLinks: [created],\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n },\n });\n }\n }\n\n // Last, so a built-in route always wins a path collision with an application's own.\n defineExtraRoutes?.({ controller: this, helper, basePath: normalizedBasePath });\n }\n }\n\n Object.defineProperty(GeneratedStaticAssetController, 'name', {\n value: name,\n configurable: true,\n });\n return GeneratedStaticAssetController;\n }\n}\n"]}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseRestController, type TRouteContext } from '@/base/controllers';\nimport { controller as controllerDecorator } from '@/base/metadata';\nimport {\n BaseStorageHelper,\n RequestUtility,\n StorageUtility,\n type IObjectLocation,\n type IObjectMetadata,\n type IObjectRef,\n type IStorageHelper,\n type IUploadFile,\n type IPostPolicy,\n type IUploadResult,\n type TUploadNaming,\n} from '@venizia/ignis-helpers';\nimport { HTTP, ResolverUtility, type ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport type { AnyType, TValueOrAsyncResolver } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError, UuidHelper } from '@venizia/ignis-helpers/core';\nimport { type Env } from 'hono';\nimport { readFileSync, rmSync } from 'node:fs';\nimport {\n RENDERABLE_CONTENT_TYPES,\n StaticAssetErrors,\n type TBucketParams,\n type TDefineExtraRoutes,\n type TListQuery,\n type TMetaLinkConfig,\n DEFAULT_PENDING_PREFIX,\n META_LINK_CREATE_FAILED,\n type TObjectParams,\n type TUploadPolicyRequest,\n type TObjectNameResolver,\n type TStaticAssetExtraOptions,\n type TStaticAssetsComponentOptions,\n type TStaticAssetStorageType,\n type TUploadQuery,\n WHITELIST_HEADERS,\n} from '../common';\nimport { AssetCommitToken, MetaLinkRecreateActions } from '../common';\nimport { AssetDefinitionBuilder } from './base.definition';\nimport { AssetKeyScope } from './key-scope';\nimport { AssetMetaLink } from './meta-link';\nimport { AssetRouteOptions } from './route-options';\n\nexport interface IAssetControllerOptions {\n controller: TStaticAssetsComponentOptions[string]['controller'];\n storage: TStaticAssetStorageType;\n helper: IStorageHelper;\n useMetaLink?: boolean;\n /** The table is erased at this seam on purpose. The public option types carry the real `Schema` and check it; inside the controller every read and write is on MetaLink COLUMNS, and threading a table type nobody here constrains through 700 lines of handler buys nothing. */\n metaLink?: TMetaLinkConfig<AnyType>;\n options?: TStaticAssetExtraOptions;\n\n /** Decides the stored object name of each uploaded file. Absent leaves the storage helper's own naming untouched. */\n resolveObjectName?: TObjectNameResolver;\n\n /** Registers the application's own routes on the generated controller, after every built-in one. */\n /** Registers the application's own routes BEFORE every built-in one, so a literal path wins over the catch-all `rawObjectPath` produces. */\n defineRoutesBefore?: TDefineExtraRoutes;\n defineExtraRoutes?: TDefineExtraRoutes;\n}\n\n/** 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. */\n/** The upload labels, read off the multipart form. Every value arrives as text, so `sequence` is the one that needs converting. */\n/** One list: the reader below and the stale-caller warning must agree. */\nconst UPLOAD_LABEL_NAMES = [\n 'principalType',\n 'principalId',\n 'variant',\n 'sequence',\n 'folderPath',\n] as const;\n\n/** The body of `AssetControllerFactory.findLabelsInQuery`, callable from the helpers above the class. */\nconst listLabelsInQuery = (opts: {\n query: Record<string, string>;\n names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;\n}): string[] => (opts.names ?? UPLOAD_LABEL_NAMES).filter((name) => opts.query[name] !== undefined);\n\n/** Refused before the body is read: a route that ignored them would store an unlabelled row. */\nconst refuseLabelsInQuery = (opts: {\n query: Record<string, string>;\n names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;\n reason?: string;\n}): void => {\n const names = listLabelsInQuery(opts);\n if (names.length > 0) {\n throw getError({\n error: StaticAssetErrors.LABELS_IN_QUERY,\n message: `${opts.reason ?? 'Upload labels belong in the request body, not the query'} | names: ${names.join(', ')}`,\n });\n }\n};\n\n/** The commit body carries four of the five: the object key - and so `folderPath` - was fixed when the policy was issued. */\nconst COMMIT_LABEL_NAMES = UPLOAD_LABEL_NAMES.filter((name) => name !== 'folderPath');\n\n// A multipart form hands strings; a JSON commit body may hand `sequence` as a number.\nconst readUploadLabels = (opts: {\n fields: Partial<Record<(typeof UPLOAD_LABEL_NAMES)[number], string | number>>;\n}): TUploadQuery => {\n const { fields } = opts;\n const read = (name: (typeof UPLOAD_LABEL_NAMES)[number]) => {\n const value = fields[name];\n return value === undefined || value === '' ? undefined : String(value);\n };\n\n const sequence = read('sequence');\n\n return {\n principalType: read('principalType'),\n principalId: read('principalId'),\n variant: read('variant'),\n sequence: sequence === undefined ? undefined : Number(sequence),\n folderPath: read('folderPath'),\n };\n};\n\nconst readObjectName: (rawObjectName: string) => string = (rawObjectName) => rawObjectName;\n\n/** Encodes an object path into a SINGLE url segment: `{objectName}` matches one segment only, so `/` must be percent-encoded too (Hono decodes it back before the handler reads the param). */\nconst encodeObjectPath: (objectPath: string) => string = (objectPath) => {\n return encodeURIComponent(objectPath);\n};\n\n/** The bucket one request works on: a configured value wins - called on every request, so an application may read an environment variable lazily - else the path param, which is only registered when there is no configured bucket. */\nconst resolveBucket = async (opts: {\n configured?: TValueOrAsyncResolver<string>;\n param?: string;\n}): Promise<string> => {\n const { configured, param } = opts;\n\n if (configured === undefined) {\n return param ?? '';\n }\n\n return ResolverUtility.resolveValueAsync({ value: configured });\n};\n\n/** Mirrors `BaseStorageHelper.normalizeObjectName`, which is protected: `resolveObjectName` is offered the very name the helper would otherwise have written. */\nconst defaultObjectName: (opts: { file: TUploadNaming }) => string = ({ file }) => {\n const { originalName, folderPath } = file;\n const normalizedFileName = originalName.toLowerCase().replace(/ /g, '_');\n\n if (!folderPath) {\n return normalizedFileName;\n }\n\n return `${folderPath.toLowerCase().replace(/ /g, '_')}/${normalizedFileName}`;\n};\n\n/**\n * Reads one `Range` header. Only a single byte range is honoured - multipart ranges need a multipart\n * body no browser asks for here. An unsatisfiable or malformed range returns `null`, and the caller\n * serves the whole object, which is what RFC 9110 allows.\n */\nconst readByteRange = (opts: {\n header: string | undefined;\n size: number;\n}): { start: number; end: number } | null => {\n const { header, size } = opts;\n\n if (!header || size <= 0) {\n return null;\n }\n\n const match = /^bytes=(\\d*)-(\\d*)$/.exec(header.trim());\n if (!match) {\n return null;\n }\n\n const [, rawStart, rawEnd] = match;\n\n // `bytes=-500` means the LAST 500 bytes, not \"from 0 to 500\".\n if (!rawStart) {\n const suffixLength = Number(rawEnd);\n if (!Number.isInteger(suffixLength) || suffixLength <= 0) {\n return null;\n }\n\n return { start: Math.max(size - suffixLength, 0), end: size - 1 };\n }\n\n const start = Number(rawStart);\n const end = rawEnd ? Number(rawEnd) : size - 1;\n\n if (!Number.isInteger(start) || !Number.isInteger(end) || start > end || start >= size) {\n return null;\n }\n\n return { start, end: Math.min(end, size - 1) };\n};\n\n/** Sets whitelisted metadata headers on the response context. `content-type` is not among them. */\nconst applyMetadataHeaders: (opts: {\n ctx: TRouteContext<Env>;\n metadata: IObjectMetadata;\n}) => void = ({ ctx, metadata }) => {\n Object.entries(metadata).forEach(([key, value]) => {\n if (!WHITELIST_HEADERS.includes(key.toLowerCase() as (typeof WHITELIST_HEADERS)[number])) {\n return;\n }\n ctx.header(key.toLowerCase(), String(value).replace(/[\\r\\n]/g, ''));\n });\n};\n\nexport class AssetControllerFactory extends BaseHelper {\n constructor() {\n super({ scope: AssetControllerFactory.name });\n }\n\n /** Names any label a caller put in the query - where the upload routes refuse it. */\n static findLabelsInQuery(opts: {\n query: Record<string, string>;\n names?: ReadonlyArray<(typeof UPLOAD_LABEL_NAMES)[number]>;\n }): string[] {\n return listLabelsInQuery(opts);\n }\n\n /** The URL of one object, in the shape its controller serves: no `/buckets/<name>` with a configured bucket, and a raw path with `rawObjectPath`. */\n static buildObjectLink(\n opts: IObjectLocation & {\n basePath: string;\n hasConfiguredBucket?: boolean;\n rawObjectPath?: boolean;\n },\n ): string {\n const { basePath, bucket, object } = opts;\n const { hasConfiguredBucket = false, rawObjectPath = false } = opts;\n\n const bucketSegment = hasConfiguredBucket ? '' : `/buckets/${bucket.name}`;\n const objectSegment = rawObjectPath ? object.key : encodeObjectPath(object.key);\n\n return `${basePath}${bucketSegment}/objects/${objectSegment}`;\n }\n\n /**\n * The served type comes from the object NAME, never the backend or the uploader: a renderable type on\n * the API origin is stored XSS. Public so a hand-written route makes the same decision - the\n * backend's own content-type is dropped by `WHITELIST_HEADERS`.\n */\n static resolveServedContentType(opts: { helper: IStorageHelper; object: IObjectRef }): {\n contentType: string;\n isRenderable: boolean;\n } {\n const { helper, object } = opts;\n const candidate = helper\n .getMimeType({ filename: object.key })\n .toLowerCase()\n .split(';')[0]\n .trim();\n\n if (!RENDERABLE_CONTENT_TYPES.has(candidate)) {\n return { contentType: HTTP.HeaderValues.APPLICATION_OCTET_STREAM, isRenderable: false };\n }\n\n return { contentType: candidate, isRenderable: true };\n }\n\n static defineAssetController(opts: IAssetControllerOptions) {\n const { controller, helper, options, useMetaLink, metaLink, storage } = opts;\n const { resolveObjectName, defineRoutesBefore, defineExtraRoutes } = opts;\n const { directUpload } = controller;\n const { name, basePath, routes, isStrict = true, bucket, rawObjectPath = false } = controller;\n const maxFolderDepth = options?.maxFolderDepth ?? BaseStorageHelper.DEFAULT_MAX_FOLDER_DEPTH;\n const maxBytes = options?.maxBytes;\n\n const hasConfiguredBucket = bucket !== undefined;\n\n // With the bucket in the URL, the bucket routes stay unscoped and the scope spans every bucket.\n if (controller.keyPrefix !== undefined && !hasConfiguredBucket) {\n throw getError({\n message: `[${name}] keyPrefix needs controller.bucket | a bucket in the URL is a bucket the caller chooses, and the bucket routes cannot be scoped`,\n });\n }\n\n const scope =\n controller.keyPrefix === undefined\n ? undefined\n : AssetKeyScope.normalizePrefix({ keyPrefix: controller.keyPrefix, helper, scope: name });\n const keyPrefix = scope?.keyPrefix;\n // `maxFolderDepth` counts the caller's folders; the scope's own are configuration, not input.\n const objectKeyMaxDepth = maxFolderDepth + (scope?.depth ?? 0);\n // The component's own name under a scope: the original name must stay one segment, as without one.\n const isScopedDefaultNaming =\n keyPrefix !== undefined && !resolveObjectName && !options?.normalizeNameFn;\n const definitions = AssetDefinitionBuilder.build({ hasConfiguredBucket, rawObjectPath });\n\n // The mount path may be declared with or without a leading slash; a link must carry exactly one.\n const normalizedBasePath = basePath.startsWith('/') ? basePath : `/${basePath}`;\n\n /** Only when the URL shape deviates: with neither option the storage helper's own link is left untouched. */\n const shapedLinkFn =\n hasConfiguredBucket || rawObjectPath\n ? (linkOptions: IObjectLocation) =>\n AssetControllerFactory.buildObjectLink({\n basePath: normalizedBasePath,\n bucket: linkOptions.bucket,\n object: linkOptions.object,\n hasConfiguredBucket,\n rawObjectPath,\n })\n : undefined;\n const normalizeLinkFn = options?.normalizeLinkFn ?? shapedLinkFn;\n\n @controllerDecorator({ path: basePath })\n class GeneratedStaticAssetController extends BaseRestController {\n constructor() {\n super({\n scope: name,\n path: basePath,\n isStrict,\n });\n }\n\n /** Clears the multipart spool files written by `parseMultipartBody({ storage: 'disk' })`. */\n removeSpoolFiles(spoolOptions: { paths: string[] }): void {\n for (const filePath of spoolOptions.paths) {\n try {\n rmSync(filePath, { force: true });\n } catch (error) {\n this.logger\n .for('UPLOAD')\n .error('Failed to remove spool file | path: %s | Error: %s', filePath, error);\n }\n }\n }\n\n override binding(): ValueOrPromise<void> {\n // First, so a literal path can win over the built-in catch-all `rawObjectPath` registers.\n defineRoutesBefore?.({ controller: this, helper, basePath: normalizedBasePath });\n\n // A single-bucket application has no reason to expose bucket creation or deletion, so the\n // four bucket-management routes are not registered once `bucket` is configured.\n if (!hasConfiguredBucket) {\n const getBucketsRoute = AssetRouteOptions.readOverride({ route: routes?.getBuckets });\n if (getBucketsRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_BUCKETS, ...getBucketsRoute.override },\n }).to({\n handler: async (ctx) => {\n const buckets = await helper.getBuckets();\n return ctx.json(buckets, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const getBucketByNameRoute = AssetRouteOptions.readOverride({\n route: routes?.getBucketByName,\n });\n if (getBucketByNameRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_BUCKET_BY_NAME, ...getBucketByNameRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const found = await helper.getBucket({ bucket: { name: bucketName } });\n return ctx.json(found, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const createBucketRoute = AssetRouteOptions.readOverride({ route: routes?.createBucket });\n if (createBucketRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.CREATE_BUCKET, ...createBucketRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const createdBucket = await helper.createBucket({ bucket: { name: bucketName } });\n return ctx.json(createdBucket, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const deleteBucketRoute = AssetRouteOptions.readOverride({ route: routes?.deleteBucket });\n if (deleteBucketRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.DELETE_BUCKET, ...deleteBucketRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TBucketParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const isRemovedBucket = await helper.removeBucket({\n bucket: { name: bucketName },\n });\n return ctx.json({ isDeleted: isRemovedBucket }, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n }\n\n const getObjectByNameRoute = AssetRouteOptions.readOverride({\n route: routes?.getObjectByName,\n });\n if (getObjectByNameRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.GET_OBJECT_BY_NAME, ...getObjectByNameRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n AssetKeyScope.assertInScope({ key: objectName, keyPrefix });\n\n const fileStat = await helper.getStat({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n const { size, metadata } = fileStat;\n applyMetadataHeaders({ ctx, metadata });\n\n const served = AssetControllerFactory.resolveServedContentType({\n helper,\n object: { key: objectName },\n });\n ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);\n ctx.header('x-content-type-options', 'nosniff');\n // Sandboxed even when renderable, so an unforeseen renderable type cannot reach this origin.\n ctx.header(HTTP.Headers.CONTENT_SECURITY_POLICY, 'sandbox');\n // Advertised unconditionally: a player only offers seeking once it sees this.\n ctx.header('accept-ranges', 'bytes');\n\n // A type outside the allow-list downloads instead of rendering; that is the XSS boundary.\n if (!served.isRenderable) {\n const inlineName = objectName.split('/').pop() ?? objectName;\n ctx.header(\n HTTP.Headers.CONTENT_DISPOSITION,\n RequestUtility.buildContentDispositionHeader({\n filename: inlineName,\n type: 'attachment',\n }),\n );\n }\n\n const range = readByteRange({ header: ctx.req.header('range'), size });\n\n if (range) {\n ctx.header(HTTP.Headers.CONTENT_LENGTH, String(range.end - range.start + 1));\n ctx.header(HTTP.Headers.CONTENT_RANGE, `bytes ${range.start}-${range.end}/${size}`);\n } else {\n ctx.header(HTTP.Headers.CONTENT_LENGTH, size.toString());\n }\n\n // The web stream is what a Response body wants, so no Node Readable sits in between.\n const stream = await helper.getObjectStream({\n bucket: { name: bucketName },\n object: { key: objectName },\n ...(range ? { range } : {}),\n });\n\n return new Response(stream, {\n headers: ctx.res.headers,\n status: range ? HTTP.ResultCodes.RS_2.PartialContent : HTTP.ResultCodes.RS_2.Ok,\n });\n },\n });\n }\n\n const downloadObjectByNameRoute = AssetRouteOptions.readOverride({\n route: routes?.downloadObjectByName,\n });\n if (downloadObjectByNameRoute.isEnabled) {\n this.bindRoute({\n configs: {\n ...definitions.DOWNLOAD_OBJECT_BY_NAME,\n ...downloadObjectByNameRoute.override,\n },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n AssetKeyScope.assertInScope({ key: objectName, keyPrefix });\n\n const fileStat = await helper.getStat({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n const { size, metadata } = fileStat;\n applyMetadataHeaders({ ctx, metadata });\n\n // Download always attaches, so the served type only has to be honest, never renderable.\n const served = AssetControllerFactory.resolveServedContentType({\n helper,\n object: { key: objectName },\n });\n ctx.header(HTTP.Headers.CONTENT_TYPE, served.contentType);\n ctx.header(HTTP.Headers.CONTENT_LENGTH, size.toString());\n\n const fileName = objectName.split('/').pop() ?? objectName;\n ctx.header(\n HTTP.Headers.CONTENT_DISPOSITION,\n RequestUtility.buildContentDispositionHeader({\n filename: fileName,\n type: 'attachment',\n }),\n );\n ctx.header('x-content-type-options', 'nosniff');\n ctx.header(HTTP.Headers.CONTENT_SECURITY_POLICY, 'sandbox');\n\n const stream = await helper.getObjectStream({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n return new Response(stream, {\n headers: ctx.res.headers,\n status: HTTP.ResultCodes.RS_2.Ok,\n });\n },\n });\n }\n\n const uploadRoute = AssetRouteOptions.readOverride({ route: routes?.upload });\n if (uploadRoute.isEnabled) {\n const uploadMiddleware =\n maxBytes === undefined\n ? uploadRoute.override.middleware\n : AssetRouteOptions.appendLengthGuard({\n middleware: uploadRoute.override.middleware,\n maxBytes,\n });\n\n this.bindRoute({\n configs: {\n ...definitions.UPLOAD,\n ...uploadRoute.override,\n middleware: uploadMiddleware,\n },\n }).to({\n handler: async (ctx) => {\n // A configured bucket drops `params` from this route entirely, so it is read only when it exists.\n const bucketParam = hasConfiguredBucket\n ? undefined\n : ctx.req.valid<TBucketParams>('param').bucketName;\n const bucketName = await resolveBucket({ configured: bucket, param: bucketParam });\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n const validateFolderPath = (folderPath: string) => {\n const normalizedFolder = folderPath.replace(/^\\/+|\\/+$/g, '');\n if (!normalizedFolder) {\n throw getError({ error: StaticAssetErrors.FOLDER_PATH_INVALID });\n }\n // maxFolderDepth excludes the filename, so it is compared directly against segment count.\n const folderSegments = normalizedFolder.split('/');\n if (folderSegments.length > maxFolderDepth) {\n throw getError({\n error: StaticAssetErrors.FOLDER_DEPTH_EXCEEDED,\n message: `Folder path exceeds max depth of ${maxFolderDepth}`,\n });\n }\n const invalidSegmentIndex = folderSegments.findIndex(\n (segment) => !helper.isValidSegment({ segment }),\n );\n if (invalidSegmentIndex !== -1) {\n throw getError({\n error: StaticAssetErrors.FOLDER_SEGMENT_INVALID,\n message: `Invalid folder path segment: ${folderSegments[invalidSegmentIndex]}`,\n });\n }\n };\n\n refuseLabelsInQuery({ query: ctx.req.query() });\n\n const { files: filesArray, fields } = await RequestUtility.parseMultipartBody({\n context: ctx,\n storage: options?.parseMultipartBody?.storage,\n uploadDir: options?.parseMultipartBody?.uploadDir,\n });\n\n // Labels travel with the payload, not the URL, so the folder check waits for the parse.\n const query = readUploadLabels({ fields });\n\n const folderPath = query.folderPath;\n if (folderPath) {\n validateFolderPath(folderPath);\n }\n\n const spoolPaths = filesArray\n .map((file) => file.path)\n .filter((filePath): filePath is string => Boolean(filePath));\n\n let uploaded: IUploadResult[];\n try {\n // `storage: 'disk'` spools the payload to `uploadDir` and returns `path` instead of `buffer`; the storage helpers only ever write `buffer`, so it must be read back.\n const modifiedFiles: IUploadFile[] = filesArray.map((file) => {\n const buffer = file.buffer ?? (file.path ? readFileSync(file.path) : undefined);\n\n if (!buffer?.length) {\n throw getError({\n error: StaticAssetErrors.FILE_EMPTY,\n message: `Empty file content | name: ${file.originalname}`,\n });\n }\n\n // Authoritative: `buffer.length`, not the client-declared `size`.\n if (maxBytes !== undefined && buffer.length > maxBytes) {\n throw getError({\n error: StaticAssetErrors.UPLOAD_TOO_LARGE,\n message: `File ${file.originalname} of ${buffer.length} bytes exceeds the maximum of ${maxBytes}`,\n });\n }\n\n return {\n originalName: file.originalname,\n mimetype: file.mimetype,\n buffer,\n size: file.size,\n encoding: file.encoding,\n folderPath: folderPath ?? undefined,\n };\n });\n\n // Built per request: the hook is offered the bucket, which only the route knows. With\n // neither hook nor scope, `normalizeNameFn` stays exactly as configured. Under a scope,\n // the component's own default is placed inside it; an application hook's key is\n // checked, never rewritten, because the application may record that key elsewhere.\n const normalizeNameFn =\n resolveObjectName || keyPrefix !== undefined\n ? (naming: { file: TUploadNaming }) => {\n if (\n isScopedDefaultNaming &&\n !helper.isValidSegment({ segment: naming.file.originalName })\n ) {\n throw getError({ message: '[upload] Invalid original file name' });\n }\n\n const defaultKey = options?.normalizeNameFn\n ? options.normalizeNameFn(naming)\n : `${keyPrefix ?? ''}${defaultObjectName(naming)}`;\n\n const key = resolveObjectName\n ? resolveObjectName({\n bucket: { name: bucketName },\n file: naming.file,\n defaultKey,\n })\n : defaultKey;\n\n if (!AssetKeyScope.isInScope({ key, keyPrefix })) {\n throw getError({\n error: StaticAssetErrors.OBJECT_KEY_OUT_OF_SCOPE,\n message: `Object key is outside the key prefix of this controller | key: ${key} | keyPrefix: ${keyPrefix}`,\n });\n }\n\n return key;\n }\n : options?.normalizeNameFn;\n\n const result = await helper.upload({\n bucket: { name: bucketName },\n files: modifiedFiles,\n normalizeNameFn,\n normalizeLinkFn,\n // 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.\n maxFolderDepth: objectKeyMaxDepth,\n });\n uploaded = result;\n } finally {\n this.removeSpoolFiles({ paths: spoolPaths });\n }\n\n if (!useMetaLink || !metaLink) {\n return ctx.json(uploaded, HTTP.ResultCodes.RS_2.Ok);\n }\n\n const results: IUploadResult[] = [];\n for (const uploadResult of uploaded) {\n try {\n const fileStat = await helper.getStat({\n bucket: uploadResult.bucket,\n object: uploadResult.object,\n });\n\n const createdMetaLink = await AssetMetaLink.createRow({\n metaLink,\n helper,\n storage,\n uploadResult,\n fileStat,\n query,\n });\n\n results.push({ ...uploadResult, metaLink: { data: createdMetaLink } });\n } catch (error) {\n this.logger\n .for('UPLOAD')\n .error(\n 'Failed to create MetaLink | objectName: %s | Error: %s',\n uploadResult.object.key,\n error,\n );\n results.push({\n ...uploadResult,\n // A CODE, never the driver text. This handler returns 200, so it bypasses the\n // error middleware and `database.handler` - the two places that strip\n // `detail`/`table`/`constraint` - and shipped raw constraint names to the client.\n // The real error is already logged in full immediately above.\n metaLink: { error: META_LINK_CREATE_FAILED },\n });\n }\n }\n return ctx.json(results, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const deleteObjectRoute = AssetRouteOptions.readOverride({ route: routes?.deleteObject });\n if (deleteObjectRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.DELETE_OBJECT, ...deleteObjectRoute.override },\n }).to({\n handler: async (ctx) => {\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n AssetKeyScope.assertInScope({ key: objectName, keyPrefix });\n\n // Deliberately idempotent: S3 answers 200 for a key that was never there, and consumers\n // already depend on it. `disk` throws instead, so the two are reconciled here, not below.\n try {\n await helper.removeObject({\n bucket: { name: bucketName },\n object: { key: objectName },\n });\n } catch (error) {\n if (!StorageUtility.isNotFoundError({ error })) {\n throw error;\n }\n }\n\n if (!useMetaLink || !metaLink) {\n return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);\n }\n\n const deleteRepository = await ResolverUtility.resolveValueAsync({\n value: metaLink.repository,\n });\n deleteRepository\n .deleteAll({\n where: {\n bucketName,\n objectName,\n },\n })\n .then(() => {\n this.logger\n .for('DELETE_OBJECT')\n .info('Successfully to delete MetaLink for %s/%s', bucketName, objectName);\n })\n .catch((error) => {\n this.logger\n .for('DELETE_OBJECT')\n .error(\n 'Failed to delete MetaLink | bucket: %s | objectName: %s | Error: %s',\n bucketName,\n objectName,\n error,\n );\n });\n\n return ctx.json({ success: true }, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const listObjectsRoute = AssetRouteOptions.readOverride({ route: routes?.listObjects });\n if (listObjectsRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.LIST_OBJECTS, ...listObjectsRoute.override },\n }).to({\n handler: async (ctx) => {\n // A configured bucket drops `params` from this route entirely, so it is read only when it exists.\n const bucketParam = hasConfiguredBucket\n ? undefined\n : ctx.req.valid<TBucketParams>('param').bucketName;\n const bucketName = await resolveBucket({ configured: bucket, param: bucketParam });\n const { prefix, recursive, maxKeys } = ctx.req.valid<TListQuery>('query');\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n // A NaN or 0 maxKeys is silently treated as \"unlimited\" by the storage backends, so an unparsable value must be rejected instead of forwarded.\n let resolvedMaxKeys: number | undefined;\n if (maxKeys !== undefined) {\n resolvedMaxKeys = Number(maxKeys);\n\n if (!Number.isInteger(resolvedMaxKeys) || resolvedMaxKeys < 1) {\n throw getError({\n error: StaticAssetErrors.MAX_KEYS_INVALID,\n message: `Invalid maxKeys | Expected a positive integer | value: ${maxKeys}`,\n });\n }\n }\n\n const scoped = AssetKeyScope.resolveListPrefix({ prefix, keyPrefix });\n if (scoped.isOutOfScope) {\n return ctx.json([], HTTP.ResultCodes.RS_2.Ok);\n }\n\n const objects = await helper.listObjects({\n bucket: { name: bucketName },\n prefix: scoped.prefix,\n useRecursive: recursive === 'true',\n maxKeys: resolvedMaxKeys,\n });\n\n return ctx.json(objects, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n if (directUpload) {\n if (!hasConfiguredBucket) {\n throw getError({\n message: `[${name}] directUpload needs controller.bucket | a policy names one bucket, and a bucket in the URL is a bucket the caller chooses`,\n });\n }\n\n const pendingPrefix = directUpload.pendingPrefix ?? DEFAULT_PENDING_PREFIX;\n // The scope rides inside the pending key, so the commit, which strips `pendingPrefix`, lands inside it.\n const policyKeyPrefix = `${pendingPrefix}${keyPrefix ?? ''}`;\n\n const uploadPolicyRoute = AssetRouteOptions.readOverride({ route: routes?.uploadPolicy });\n if (uploadPolicyRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.UPLOAD_POLICY, ...uploadPolicyRoute.override },\n }).to({\n handler: async (ctx) => {\n const result = await directUpload.authorize({ context: ctx });\n if (!result) {\n throw getError({ error: StaticAssetErrors.UPLOAD_NOT_AUTHORIZED });\n }\n\n const { files } = ctx.req.valid<TUploadPolicyRequest>('json');\n const bucketName = await resolveBucket({ configured: bucket });\n\n const policies: Array<IPostPolicy & { objectName: string; commitToken: string }> =\n [];\n for (const file of files) {\n if (file.size !== undefined && file.size > directUpload.maxBytes) {\n throw getError({\n error: StaticAssetErrors.UPLOAD_TOO_LARGE,\n message: `File '${file.fileName}' is ${file.size} bytes, over the ${directUpload.maxBytes} the policy allows`,\n });\n }\n\n // Generated, never taken from the caller: a key the caller picks is a key the caller\n // can collide with, and the pending object is the one thing a policy authorizes.\n const objectName = `${policyKeyPrefix}${UuidHelper.getInstance().v4()}/${file.fileName}`;\n const policy = await helper.presignPost({\n bucket: { name: bucketName },\n keyPrefix: policyKeyPrefix,\n maxBytes: directUpload.maxBytes,\n contentType: file.contentType,\n expiresIn: directUpload.expiresIn,\n });\n\n policies.push({\n ...policy,\n objectName,\n commitToken: AssetCommitToken.build({\n payload: {\n bucket: bucketName,\n key: objectName,\n expiresAt: new Date(policy.expiresAt).getTime(),\n },\n secretKey: directUpload.secretKey,\n }),\n });\n }\n\n return ctx.json(policies, HTTP.ResultCodes.RS_2.Ok);\n },\n });\n }\n\n const uploadCommitRoute = AssetRouteOptions.readOverride({ route: routes?.uploadCommit });\n if (uploadCommitRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.UPLOAD_COMMIT, ...uploadCommitRoute.override },\n }).to({\n handler: async (ctx) => {\n const commitQuery = ctx.req.query();\n refuseLabelsInQuery({ query: commitQuery, names: COMMIT_LABEL_NAMES });\n refuseLabelsInQuery({\n query: commitQuery,\n names: ['folderPath'],\n reason:\n 'folderPath was decided when the upload policy was issued; the commit route cannot move the object',\n });\n\n const { commitToken, ...labels } = ctx.req.valid<\n { commitToken: string } & TUploadQuery\n >('json');\n\n // Verified BEFORE any storage call. That is what keeps this route from being a name\n // prober: a forged token fails without a round trip, so timing says nothing.\n const payload = AssetCommitToken.read({\n token: commitToken,\n secretKey: directUpload.secretKey,\n });\n\n // Labels, not authorization - the token deliberately carries no business fields, so\n // they travel beside it rather than inside it.\n const query = readUploadLabels({ fields: labels });\n\n const bucketRef = { name: payload.bucket };\n const pendingObject = { key: payload.key };\n const object = { key: payload.key.slice(pendingPrefix.length) };\n\n // A token another controller signed with the same secret must not land outside this scope.\n AssetKeyScope.assertInScope({ key: object.key, keyPrefix });\n\n // Before the copy, so a hook that throws leaves the object under the pending prefix\n // for a lifecycle rule, rather than stranding it at the final key.\n await directUpload.onCommit?.({ bucket: bucketRef, pendingObject, object });\n\n await helper.copyObject({\n bucket: bucketRef,\n source: pendingObject,\n destination: object,\n });\n // The copy IS the commit; removing the temporary object is cleanup. A failure here\n // leaves one object for the lifecycle rule, and failing the request would tell the\n // caller their upload did not work when it did.\n await helper\n .removeObject({ bucket: bucketRef, object: pendingObject })\n .catch((error) => {\n this.logger\n .for('UPLOAD_COMMIT')\n .warn(\n 'Committed, but the pending object remains | key: %s | error: %s',\n pendingObject.key,\n error,\n );\n });\n\n const link = AssetControllerFactory.buildObjectLink({\n basePath: normalizedBasePath,\n bucket: bucketRef,\n object,\n hasConfiguredBucket,\n rawObjectPath,\n });\n\n // The two paths have to agree: without this a client reading `metaLink` off the\n // response renders an empty state with no error - the failure nobody reports.\n let metaLinkResult: IUploadResult['metaLink'];\n if (useMetaLink && metaLink) {\n try {\n const fileStat = await helper.getStat({ bucket: bucketRef, object });\n const data = await AssetMetaLink.createRow({\n metaLink,\n helper,\n storage,\n uploadResult: AssetMetaLink.buildStoredUploadResult({\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n }),\n fileStat,\n query,\n });\n\n metaLinkResult = { data };\n } catch (error) {\n // The object IS committed by now. A 500 would send the caller back with a token\n // whose source no longer exists, so this rides the body as a code, like UPLOAD.\n this.logger\n .for('UPLOAD_COMMIT')\n .error(\n 'Failed to create MetaLink | objectName: %s | Error: %s',\n object.key,\n error,\n );\n metaLinkResult = { error: META_LINK_CREATE_FAILED };\n }\n }\n\n return ctx.json(\n {\n bucket: bucketRef,\n object,\n link,\n ...(metaLinkResult === undefined ? {} : { metaLink: metaLinkResult }),\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n },\n });\n }\n }\n\n if (useMetaLink && metaLink) {\n const recreateMetaLinkRoute = AssetRouteOptions.readOverride({\n route: routes?.recreateMetaLink,\n });\n if (recreateMetaLinkRoute.isEnabled) {\n this.bindRoute({\n configs: { ...definitions.RECREATE_METALINK, ...recreateMetaLinkRoute.override },\n }).to({\n handler: async (ctx) => {\n // This route takes no labels anywhere: one in the query would land an unlabelled row.\n refuseLabelsInQuery({\n query: ctx.req.query(),\n reason:\n 'This route recreates a MetaLink for an existing object and takes no labels',\n });\n\n const params = ctx.req.valid<TObjectParams>('param');\n const bucketName = await resolveBucket({\n configured: bucket,\n param: params.bucketName,\n });\n const objectName = readObjectName(params.objectName);\n\n if (!helper.isValidBucketName({ bucket: { name: bucketName } })) {\n throw getError({ error: StaticAssetErrors.BUCKET_NAME_INVALID });\n }\n\n if (\n !helper.isValidObjectKey({\n object: { key: objectName },\n maxDepth: objectKeyMaxDepth,\n })\n ) {\n throw getError({ error: StaticAssetErrors.OBJECT_NAME_INVALID });\n }\n\n // Before any storage call: a key outside the scope must not even be probed.\n AssetKeyScope.assertInScope({ key: objectName, keyPrefix });\n\n const bucketRef = { name: bucketName };\n const object = { key: objectName };\n const fileStat = await helper.getStat({ bucket: bucketRef, object });\n\n const link = options?.normalizeLinkFn\n ? options.normalizeLinkFn({ bucket: bucketRef, object })\n : AssetControllerFactory.buildObjectLink({\n basePath: normalizedBasePath,\n bucket: bucketRef,\n object,\n hasConfiguredBucket,\n rawObjectPath,\n });\n\n const refreshed = await AssetMetaLink.refreshRows({\n metaLink,\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n });\n\n if (refreshed.count > 0) {\n return ctx.json(\n {\n success: true,\n action: MetaLinkRecreateActions.REFRESHED,\n count: refreshed.count,\n metaLink: refreshed.data[0],\n metaLinks: refreshed.data,\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n }\n\n // Not atomic with the refresh above: two concurrent calls may both create, which the\n // table allows - rows per pair are deliberately not unique.\n const created = await AssetMetaLink.createRow({\n metaLink,\n helper,\n storage,\n uploadResult: AssetMetaLink.buildStoredUploadResult({\n helper,\n bucket: bucketRef,\n object,\n link,\n fileStat,\n }),\n fileStat,\n query: {},\n });\n\n return ctx.json(\n {\n success: true,\n action: MetaLinkRecreateActions.CREATED,\n count: 1,\n metaLink: created,\n metaLinks: [created],\n },\n HTTP.ResultCodes.RS_2.Ok,\n );\n },\n });\n }\n }\n\n // Last, so a built-in route always wins a path collision with an application's own.\n defineExtraRoutes?.({ controller: this, helper, basePath: normalizedBasePath });\n }\n }\n\n Object.defineProperty(GeneratedStaticAssetController, 'name', {\n value: name,\n configurable: true,\n });\n return GeneratedStaticAssetController;\n }\n}\n"]}
@@ -1,28 +1,30 @@
1
1
  import { type IStorageHelper } from '@venizia/ignis-helpers';
2
- /** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */
3
- export declare const normalizeKeyPrefix: (opts: {
4
- keyPrefix: string;
5
- helper: IStorageHelper;
6
- scope: string;
7
- }) => {
8
- keyPrefix: string;
9
- depth: number;
10
- };
11
- export declare const isKeyInScope: (opts: {
12
- key: string;
13
- keyPrefix?: string;
14
- }) => boolean;
15
- /** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */
16
- export declare const assertKeyInScope: (opts: {
17
- key: string;
18
- keyPrefix?: string;
19
- }) => void;
20
- /** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */
21
- export declare const resolveScopedListPrefix: (opts: {
22
- prefix?: string;
23
- keyPrefix?: string;
24
- }) => {
25
- prefix?: string;
26
- isOutOfScope: boolean;
27
- };
2
+ export declare class AssetKeyScope {
3
+ /** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */
4
+ static normalizePrefix(opts: {
5
+ keyPrefix: string;
6
+ helper: IStorageHelper;
7
+ scope: string;
8
+ }): {
9
+ keyPrefix: string;
10
+ depth: number;
11
+ };
12
+ static isInScope(opts: {
13
+ key: string;
14
+ keyPrefix?: string;
15
+ }): boolean;
16
+ /** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */
17
+ static assertInScope(opts: {
18
+ key: string;
19
+ keyPrefix?: string;
20
+ }): void;
21
+ /** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */
22
+ static resolveListPrefix(opts: {
23
+ prefix?: string;
24
+ keyPrefix?: string;
25
+ }): {
26
+ prefix?: string;
27
+ isOutOfScope: boolean;
28
+ };
29
+ }
28
30
  //# sourceMappingURL=key-scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-scope.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/key-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG5E,iIAAiI;AACjI,eAAO,MAAM,kBAAkB,GAAI,MAAM;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,KAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAYrC,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,OACJ,CAAC;AAEtE,uHAAuH;AACvH,eAAO,MAAM,gBAAgB,GAAI,MAAM;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,IAS5E,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,uBAAuB,GAAI,MAAM;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,KAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAY3C,CAAC"}
1
+ {"version":3,"file":"key-scope.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/key-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG5E,qBAAa,aAAa;IACxB,iIAAiI;IACjI,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG;QAC1F,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf;IAcD,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO;IAIpE,uHAAuH;IACvH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWrE,mGAAmG;IACnG,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QACvE,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,OAAO,CAAC;KACvB;CAaF"}
@@ -1,37 +1,41 @@
1
1
  import { StorageErrors } from '@venizia/ignis-helpers';
2
2
  import { getError } from '@venizia/ignis-helpers/core';
3
- /** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */
4
- export const normalizeKeyPrefix = (opts) => {
5
- const { keyPrefix, helper, scope } = opts;
6
- const trimmed = keyPrefix.replace(/^\/+|\/+$/g, '');
7
- const segments = trimmed ? trimmed.split('/') : [];
8
- if (segments.length === 0 || segments.some((segment) => !helper.isValidSegment({ segment }))) {
9
- throw getError({
10
- message: `[${scope}] controller.keyPrefix must be one or more valid key segments | value: ${keyPrefix}`,
11
- });
3
+ export class AssetKeyScope {
4
+ /** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */
5
+ static normalizePrefix(opts) {
6
+ const { keyPrefix, helper, scope } = opts;
7
+ const trimmed = keyPrefix.replace(/^\/+|\/+$/g, '');
8
+ const segments = trimmed ? trimmed.split('/') : [];
9
+ if (segments.length === 0 || segments.some((segment) => !helper.isValidSegment({ segment }))) {
10
+ throw getError({
11
+ message: `[${scope}] controller.keyPrefix must be one or more valid key segments | value: ${keyPrefix}`,
12
+ });
13
+ }
14
+ return { keyPrefix: `${trimmed}/`, depth: segments.length };
12
15
  }
13
- return { keyPrefix: `${trimmed}/`, depth: segments.length };
14
- };
15
- export const isKeyInScope = (opts) => opts.keyPrefix === undefined || opts.key.startsWith(opts.keyPrefix);
16
- /** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */
17
- export const assertKeyInScope = (opts) => {
18
- if (isKeyInScope(opts)) {
19
- return;
16
+ static isInScope(opts) {
17
+ return opts.keyPrefix === undefined || opts.key.startsWith(opts.keyPrefix);
20
18
  }
21
- throw getError({
22
- error: StorageErrors.OBJECT_NOT_FOUND,
23
- message: `Object not found | key: ${opts.key}`,
24
- });
25
- };
26
- /** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */
27
- export const resolveScopedListPrefix = (opts) => {
28
- const { prefix, keyPrefix } = opts;
29
- if (keyPrefix === undefined) {
30
- return { prefix, isOutOfScope: false };
19
+ /** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */
20
+ static assertInScope(opts) {
21
+ if (AssetKeyScope.isInScope(opts)) {
22
+ return;
23
+ }
24
+ throw getError({
25
+ error: StorageErrors.OBJECT_NOT_FOUND,
26
+ message: `Object not found | key: ${opts.key}`,
27
+ });
31
28
  }
32
- if (!prefix || keyPrefix.startsWith(prefix)) {
33
- return { prefix: keyPrefix, isOutOfScope: false };
29
+ /** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */
30
+ static resolveListPrefix(opts) {
31
+ const { prefix, keyPrefix } = opts;
32
+ if (keyPrefix === undefined) {
33
+ return { prefix, isOutOfScope: false };
34
+ }
35
+ if (!prefix || keyPrefix.startsWith(prefix)) {
36
+ return { prefix: keyPrefix, isOutOfScope: false };
37
+ }
38
+ return { prefix, isOutOfScope: !prefix.startsWith(keyPrefix) };
34
39
  }
35
- return { prefix, isOutOfScope: !prefix.startsWith(keyPrefix) };
36
- };
40
+ }
37
41
  //# sourceMappingURL=key-scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-scope.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/key-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,iIAAiI;AACjI,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAIlC,EAAwC,EAAE;IACzC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7F,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,IAAI,KAAK,0EAA0E,SAAS,EAAE;SACxG,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAyC,EAAW,EAAE,CACjF,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAEtE,uHAAuH;AACvH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAyC,EAAQ,EAAE;IAClF,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,CAAC;QACb,KAAK,EAAE,aAAa,CAAC,gBAAgB;QACrC,OAAO,EAAE,2BAA2B,IAAI,CAAC,GAAG,EAAE;KAC/C,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,mGAAmG;AACnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAGvC,EAA8C,EAAE;IAC/C,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAEnC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IACpD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;AACjE,CAAC,CAAC","sourcesContent":["import { StorageErrors, type IStorageHelper } from '@venizia/ignis-helpers';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */\nexport const normalizeKeyPrefix = (opts: {\n keyPrefix: string;\n helper: IStorageHelper;\n scope: string;\n}): { keyPrefix: string; depth: number } => {\n const { keyPrefix, helper, scope } = opts;\n const trimmed = keyPrefix.replace(/^\\/+|\\/+$/g, '');\n const segments = trimmed ? trimmed.split('/') : [];\n\n if (segments.length === 0 || segments.some((segment) => !helper.isValidSegment({ segment }))) {\n throw getError({\n message: `[${scope}] controller.keyPrefix must be one or more valid key segments | value: ${keyPrefix}`,\n });\n }\n\n return { keyPrefix: `${trimmed}/`, depth: segments.length };\n};\n\nexport const isKeyInScope = (opts: { key: string; keyPrefix?: string }): boolean =>\n opts.keyPrefix === undefined || opts.key.startsWith(opts.keyPrefix);\n\n/** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */\nexport const assertKeyInScope = (opts: { key: string; keyPrefix?: string }): void => {\n if (isKeyInScope(opts)) {\n return;\n }\n\n throw getError({\n error: StorageErrors.OBJECT_NOT_FOUND,\n message: `Object not found | key: ${opts.key}`,\n });\n};\n\n/** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */\nexport const resolveScopedListPrefix = (opts: {\n prefix?: string;\n keyPrefix?: string;\n}): { prefix?: string; isOutOfScope: boolean } => {\n const { prefix, keyPrefix } = opts;\n\n if (keyPrefix === undefined) {\n return { prefix, isOutOfScope: false };\n }\n\n if (!prefix || keyPrefix.startsWith(prefix)) {\n return { prefix: keyPrefix, isOutOfScope: false };\n }\n\n return { prefix, isOutOfScope: !prefix.startsWith(keyPrefix) };\n};\n"]}
1
+ {"version":3,"file":"key-scope.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/key-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,MAAM,OAAO,aAAa;IACxB,iIAAiI;IACjI,MAAM,CAAC,eAAe,CAAC,IAAkE;QAIvF,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;YAC7F,MAAM,QAAQ,CAAC;gBACb,OAAO,EAAE,IAAI,KAAK,0EAA0E,SAAS,EAAE;aACxG,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,IAAyC;QACxD,OAAO,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,uHAAuH;IACvH,MAAM,CAAC,aAAa,CAAC,IAAyC;QAC5D,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,CAAC;YACb,KAAK,EAAE,aAAa,CAAC,gBAAgB;YACrC,OAAO,EAAE,2BAA2B,IAAI,CAAC,GAAG,EAAE;SAC/C,CAAC,CAAC;IACL,CAAC;IAED,mGAAmG;IACnG,MAAM,CAAC,iBAAiB,CAAC,IAA6C;QAIpE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QAEnC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QACpD,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;IACjE,CAAC;CACF","sourcesContent":["import { StorageErrors, type IStorageHelper } from '@venizia/ignis-helpers';\nimport { getError } from '@venizia/ignis-helpers/core';\n\nexport class AssetKeyScope {\n /** `tenant-a`, `/tenant-a` and `tenant-a/` all become `tenant-a/`: without the slash, `tenant-a` would also own `tenant-ab/`. */\n static normalizePrefix(opts: { keyPrefix: string; helper: IStorageHelper; scope: string }): {\n keyPrefix: string;\n depth: number;\n } {\n const { keyPrefix, helper, scope } = opts;\n const trimmed = keyPrefix.replace(/^\\/+|\\/+$/g, '');\n const segments = trimmed ? trimmed.split('/') : [];\n\n if (segments.length === 0 || segments.some((segment) => !helper.isValidSegment({ segment }))) {\n throw getError({\n message: `[${scope}] controller.keyPrefix must be one or more valid key segments | value: ${keyPrefix}`,\n });\n }\n\n return { keyPrefix: `${trimmed}/`, depth: segments.length };\n }\n\n static isInScope(opts: { key: string; keyPrefix?: string }): boolean {\n return opts.keyPrefix === undefined || opts.key.startsWith(opts.keyPrefix);\n }\n\n /** A key outside the scope answers as a missing object does, so a caller learns nothing about keys it does not own. */\n static assertInScope(opts: { key: string; keyPrefix?: string }): void {\n if (AssetKeyScope.isInScope(opts)) {\n return;\n }\n\n throw getError({\n error: StorageErrors.OBJECT_NOT_FOUND,\n message: `Object not found | key: ${opts.key}`,\n });\n }\n\n /** A caller prefix wider than the scope is narrowed to it; one wholly outside it lists nothing. */\n static resolveListPrefix(opts: { prefix?: string; keyPrefix?: string }): {\n prefix?: string;\n isOutOfScope: boolean;\n } {\n const { prefix, keyPrefix } = opts;\n\n if (keyPrefix === undefined) {\n return { prefix, isOutOfScope: false };\n }\n\n if (!prefix || keyPrefix.startsWith(prefix)) {\n return { prefix: keyPrefix, isOutOfScope: false };\n }\n\n return { prefix, isOutOfScope: !prefix.startsWith(keyPrefix) };\n }\n}\n"]}