@dimah-s3/server 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +7 -3
  2. package/dist/adapters/express.js +16 -9
  3. package/dist/adapters/express.js.map +1 -1
  4. package/dist/adapters/fastify.js +16 -9
  5. package/dist/adapters/fastify.js.map +1 -1
  6. package/dist/adapters/hono.d.ts +1 -1
  7. package/dist/adapters/hono.js.map +1 -1
  8. package/dist/adapters/node.d.ts +1 -1
  9. package/dist/adapters/node.js +16 -9
  10. package/dist/adapters/node.js.map +1 -1
  11. package/dist/api/index.js +742 -388
  12. package/dist/api/index.js.map +1 -1
  13. package/dist/api/router.d.ts.map +1 -1
  14. package/dist/api/routes/catalog.d.ts +9 -0
  15. package/dist/api/routes/catalog.d.ts.map +1 -0
  16. package/dist/api/routes/confirm.d.ts +3 -4
  17. package/dist/api/routes/confirm.d.ts.map +1 -1
  18. package/dist/api/routes/delete-batch.d.ts +14 -0
  19. package/dist/api/routes/delete-batch.d.ts.map +1 -0
  20. package/dist/api/routes/delete.d.ts +2 -2
  21. package/dist/api/routes/delete.d.ts.map +1 -1
  22. package/dist/api/routes/download.d.ts +8 -8
  23. package/dist/api/routes/download.d.ts.map +1 -1
  24. package/dist/api/routes/file.d.ts +20 -0
  25. package/dist/api/routes/file.d.ts.map +1 -0
  26. package/dist/api/routes/index.d.ts +76 -50
  27. package/dist/api/routes/index.d.ts.map +1 -1
  28. package/dist/api/routes/multipart/abort.d.ts +2 -2
  29. package/dist/api/routes/multipart/abort.d.ts.map +1 -1
  30. package/dist/api/routes/multipart/complete.d.ts +2 -2
  31. package/dist/api/routes/multipart/complete.d.ts.map +1 -1
  32. package/dist/api/routes/multipart/init.d.ts +10 -12
  33. package/dist/api/routes/multipart/init.d.ts.map +1 -1
  34. package/dist/api/routes/multipart/list-parts.d.ts +2 -2
  35. package/dist/api/routes/multipart/list-parts.d.ts.map +1 -1
  36. package/dist/api/routes/multipart/part.d.ts +4 -6
  37. package/dist/api/routes/multipart/part.d.ts.map +1 -1
  38. package/dist/api/routes/upload.d.ts +10 -14
  39. package/dist/api/routes/upload.d.ts.map +1 -1
  40. package/dist/dimah-s3.d.ts +19 -8
  41. package/dist/dimah-s3.d.ts.map +1 -1
  42. package/dist/errors.d.ts +5 -4
  43. package/dist/errors.d.ts.map +1 -1
  44. package/dist/helpers/best-effort.d.ts +6 -0
  45. package/dist/helpers/best-effort.d.ts.map +1 -0
  46. package/dist/helpers/constraints.d.ts +16 -0
  47. package/dist/helpers/constraints.d.ts.map +1 -0
  48. package/dist/helpers/expires.d.ts +2 -2
  49. package/dist/helpers/features.d.ts +12 -29
  50. package/dist/helpers/features.d.ts.map +1 -1
  51. package/dist/helpers/finalize-confirmed.d.ts +19 -0
  52. package/dist/helpers/finalize-confirmed.d.ts.map +1 -0
  53. package/dist/helpers/head-object.d.ts.map +1 -1
  54. package/dist/helpers/hooks.d.ts +7 -1
  55. package/dist/helpers/hooks.d.ts.map +1 -1
  56. package/dist/helpers/index.d.ts +12 -9
  57. package/dist/helpers/index.d.ts.map +1 -1
  58. package/dist/helpers/list-parts.d.ts +5 -0
  59. package/dist/helpers/list-parts.d.ts.map +1 -1
  60. package/dist/helpers/logger.d.ts +4 -0
  61. package/dist/helpers/logger.d.ts.map +1 -0
  62. package/dist/helpers/previous-key.d.ts +5 -0
  63. package/dist/helpers/previous-key.d.ts.map +1 -0
  64. package/dist/helpers/resolve-route.d.ts +36 -0
  65. package/dist/helpers/resolve-route.d.ts.map +1 -0
  66. package/dist/helpers/resolve-target.d.ts +25 -14
  67. package/dist/helpers/resolve-target.d.ts.map +1 -1
  68. package/dist/index.d.ts +7 -2
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +1017 -477
  71. package/dist/index.js.map +1 -1
  72. package/dist/plugin/apply-plugins.d.ts +9 -4
  73. package/dist/plugin/apply-plugins.d.ts.map +1 -1
  74. package/dist/plugin/hook-registry.d.ts +13 -4
  75. package/dist/plugin/hook-registry.d.ts.map +1 -1
  76. package/dist/plugin/index.d.ts +1 -2
  77. package/dist/plugin/index.d.ts.map +1 -1
  78. package/dist/plugin/types.d.ts +12 -7
  79. package/dist/plugin/types.d.ts.map +1 -1
  80. package/dist/plugins.d.ts +5 -3
  81. package/dist/plugins.d.ts.map +1 -1
  82. package/dist/plugins.js +951 -475
  83. package/dist/plugins.js.map +1 -1
  84. package/dist/put.d.ts +15 -0
  85. package/dist/put.d.ts.map +1 -0
  86. package/dist/route.d.ts +13 -0
  87. package/dist/route.d.ts.map +1 -0
  88. package/dist/types/config.d.ts +194 -89
  89. package/dist/types/config.d.ts.map +1 -1
  90. package/dist/types/hook-contexts.d.ts +126 -85
  91. package/dist/types/hook-contexts.d.ts.map +1 -1
  92. package/dist/types/index.d.ts +3 -2
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/package.json +11 -11
  95. package/dist/api/assert-feature-enabled.d.ts +0 -5
  96. package/dist/api/assert-feature-enabled.d.ts.map +0 -1
  97. package/dist/helpers/resolve-object-acl.d.ts +0 -10
  98. package/dist/helpers/resolve-object-acl.d.ts.map +0 -1
  99. package/dist/helpers/resolve-request-acl.d.ts +0 -10
  100. package/dist/helpers/resolve-request-acl.d.ts.map +0 -1
@@ -1,87 +1,181 @@
1
1
  import type { S3Client } from "@aws-sdk/client-s3";
2
2
  import type { S3ObjectAcl, UploadPresignMethod } from "@dimah-s3/core";
3
- import type { DeleteGuardContext, DeleteOnDeletedContext, DownloadOnPresignedContext, DownloadPresignGuardContext, GuardContext, MultipartAbortGuardContext, MultipartCompleteGuardContext, MultipartInitGuardContext, MultipartListGuardContext, MultipartOnAbortContext, MultipartOnCompleteContext, MultipartOnInitContext, MultipartOnListContext, MultipartPartGuardContext, ResolveKeyContext, UploadConfirmGuardContext, UploadOnConfirmedContext, UploadOnPresignedContext, UploadPresignGuardContext } from "./hook-contexts";
3
+ import type { DeleteGuardContext, DeleteOnDeletedContext, DownloadGuardContext, DownloadOnPresignedContext, DownloadResolveInfo, GuardContext, MultipartGuardContext, MultipartOnAbortContext, MultipartOnInitContext, MultipartOnListContext, RouteGuardContext, UploadConfirmGuardContext, UploadGuardContext, UploadObjectContext, UploadObjectInfo, UploadOnConfirmedContext, UploadOnPresignedContext } from "./hook-contexts";
4
4
  import type { DimahS3Plugin } from "../plugin/types";
5
- export type { ResolveKeyContext };
6
- /** String prefix or async factory used by {@link resolveObjectKey}. */
7
- export type KeyPrefix = string | ((context: ResolveKeyContext) => string | Promise<string>);
8
- export type KeyPolicy = {
5
+ export type { UploadObjectContext, UploadObjectInfo, DownloadResolveInfo };
6
+ /** The three nested features on a named route. */
7
+ export declare const ROUTE_FEATURES: readonly ["upload", "download", "delete"];
8
+ export type RouteFeature = (typeof ROUTE_FEATURES)[number];
9
+ /**
10
+ * Endpoint operations. Multipart is nested under upload — it is not a
11
+ * fourth route feature.
12
+ */
13
+ export declare const ROUTE_OPERATIONS: readonly ["upload", "download", "delete", "multipart"];
14
+ export type RouteOperation = (typeof ROUTE_OPERATIONS)[number];
15
+ /** `true` or an options object enables the feature; omit or `false` disables it. */
16
+ export type FeatureToggle<T> = boolean | T;
17
+ /** Optional structured logger on {@link DimahS3Config}. */
18
+ export type DimahS3Logger = {
19
+ debug?: (message: string, ...args: unknown[]) => void;
20
+ info?: (message: string, ...args: unknown[]) => void;
21
+ warn?: (message: string, ...args: unknown[]) => void;
22
+ error?: (message: string, ...args: unknown[]) => void;
23
+ };
24
+ export type DisabledFeature = {
25
+ enabled: false;
26
+ };
27
+ export type EnabledFeature<T extends object> = T & {
28
+ enabled: true;
29
+ };
30
+ export type ResolvedFeature<T extends object> = EnabledFeature<T> | DisabledFeature;
31
+ /**
32
+ * Multipart-only hooks. Init shares `upload.guard` / `onInit`. Complete
33
+ * runs `guard` (`action: "complete"`) then `upload.confirmGuard` /
34
+ * `upload.onConfirmed`.
35
+ */
36
+ export type MultipartConfig = {
37
+ /** After `CreateMultipartUpload` — persist `uploadId` for resume. */
38
+ onInit?: (context: MultipartOnInitContext) => Promise<void> | void;
39
+ /** Authorize part, list, abort, and complete. Branch on `action` if needed. */
40
+ guard?: (context: MultipartGuardContext) => Promise<void> | void;
41
+ onAbort?: (context: MultipartOnAbortContext) => Promise<void> | void;
42
+ onList?: (context: MultipartOnListContext) => Promise<void> | void;
43
+ };
44
+ /** Upload feature: constraints, object identity, and lifecycle hooks. */
45
+ export type UploadConfig = {
46
+ /** HTML `accept` tokens (`image/*`, `.pdf`, `application/pdf`). */
47
+ fileTypes?: string[];
9
48
  /**
10
- * Prepended to the client-proposed key. Already-prefixed keys are left
11
- * unchanged so confirm / download of the stored key still work.
49
+ * Max declared size, signed part size, listed multipart total, and
50
+ * HeadObject size in bytes.
12
51
  */
13
- prefix?: KeyPrefix;
14
- /** Full control over the object key. Wins over {@link prefix}. */
15
- resolveKey?: (context: ResolveKeyContext) => string | Promise<string>;
16
- };
17
- export type AclPolicy = {
52
+ maxFileSize?: number;
18
53
  /**
19
- * Server-forced ACL. When set, the client `acl` is ignored.
20
- * @default "private" (when omitted)
54
+ * Server-owned object identity. Return `folder` for a directory under
55
+ * the route `keyPrefix`, `key` for the rest of the key (also nested
56
+ * under `keyPrefix`), plus optional S3 `metadata` and `acl`.
57
+ * Runs on upload / multipart init only. Default key is
58
+ * `{keyPrefix}/{uuid}/{name}` (`keyPrefix` defaults to the route name).
59
+ * `keyPrefix: false` generates `{uuid}/{name}` and skips the follow-up
60
+ * namespace check.
21
61
  */
22
- acl?: S3ObjectAcl;
62
+ object?: (context: UploadObjectContext) => UploadObjectInfo | void | Promise<UploadObjectInfo | void>;
23
63
  /**
24
- * Honor a client-sent `acl` (`private` | `public-read`). Off by default
25
- * uploads are `private` unless {@link acl} is set.
64
+ * Server-forced ACL when `object` does not return one.
65
+ * @default "private"
26
66
  */
27
- allowClientAcl?: boolean;
28
- };
29
- /** Upload feature. A config object (or `true`) enables the feature. */
30
- export type UploadConfig = KeyPolicy & AclPolicy & {
67
+ acl?: S3ObjectAcl;
68
+ /** Presign verb. Use `"PUT"` on R2 (no Presigned POST). @default "POST" */
31
69
  method?: UploadPresignMethod;
32
- requireFileSize?: boolean;
33
- guard?: (context: UploadPresignGuardContext) => Promise<void> | void;
70
+ /** Presign TTL in seconds. Clamped by instance `maxExpiresIn`. */
71
+ expiresIn?: number;
72
+ /**
73
+ * Require a SHA-256 `checksum` on the presign body and lock it into the
74
+ * signed PUT/POST.
75
+ */
76
+ checksum?: boolean;
77
+ /**
78
+ * Overwrite an existing object at the resolved key without flipping a
79
+ * `db()` row from `active` to `pending` during the new upload.
80
+ */
81
+ replace?: "overwrite";
82
+ /** Presign and multipart init. */
83
+ guard?: (context: UploadGuardContext) => Promise<void> | void;
84
+ /** After a single-shot URL is signed. Multipart uses `multipart.onInit`. */
34
85
  onPresigned?: (context: UploadOnPresignedContext) => Promise<void> | void;
86
+ /** Confirm and multipart complete. */
35
87
  confirmGuard?: (context: UploadConfirmGuardContext) => Promise<void> | void;
88
+ /** After HeadObject on confirm and multipart complete. */
36
89
  onConfirmed?: (context: UploadOnConfirmedContext) => Promise<void> | void;
90
+ /** Opt-in multipart. Default off. */
91
+ multipart?: FeatureToggle<MultipartConfig>;
37
92
  };
38
93
  /** Download feature. A config object (or `true`) enables the feature. */
39
- export type DownloadConfig = KeyPolicy & {
40
- guard?: (context: DownloadPresignGuardContext) => Promise<void> | void;
94
+ export type DownloadConfig = {
95
+ /**
96
+ * Presign TTL in seconds. Defaults to `S3_DEFAULT_EXPIRES_IN` (600).
97
+ * Independent of {@link UploadConfig.expiresIn}.
98
+ */
99
+ expiresIn?: number;
100
+ /**
101
+ * Default Content-Disposition. @default "attachment"
102
+ */
103
+ disposition?: "inline" | "attachment";
104
+ /**
105
+ * `"presign"` (default) returns an S3 URL. `"proxy"` returns a
106
+ * same-origin `/file` URL that streams through the server.
107
+ */
108
+ mode?: "presign" | "proxy";
109
+ /**
110
+ * Per-request download options. Return values override route defaults.
111
+ * The client `disposition` / `fileName` query is a fallback.
112
+ */
113
+ resolve?: (context: DownloadGuardContext) => DownloadResolveInfo | void | Promise<DownloadResolveInfo | void>;
114
+ guard?: (context: DownloadGuardContext) => Promise<void> | void;
41
115
  onPresigned?: (context: DownloadOnPresignedContext) => Promise<void> | void;
42
116
  };
43
117
  /** Delete feature. A config object (or `true`) enables the feature. */
44
- export type DeleteConfig = KeyPolicy & {
118
+ export type DeleteConfig = {
45
119
  guard?: (context: DeleteGuardContext) => Promise<void> | void;
46
120
  onDeleted?: (context: DeleteOnDeletedContext) => Promise<void> | void;
47
121
  };
48
- /** Multipart feature. On automatically when upload is on, unless set to `false`. */
49
- export type MultipartConfig = KeyPolicy & AclPolicy & {
50
- requireFileSize?: boolean;
51
- initGuard?: (context: MultipartInitGuardContext) => Promise<void> | void;
52
- partGuard?: (context: MultipartPartGuardContext) => Promise<void> | void;
53
- completeGuard?: (context: MultipartCompleteGuardContext) => Promise<void> | void;
54
- abortGuard?: (context: MultipartAbortGuardContext) => Promise<void> | void;
55
- listGuard?: (context: MultipartListGuardContext) => Promise<void> | void;
56
- onInit?: (context: MultipartOnInitContext) => Promise<void> | void;
57
- onComplete?: (context: MultipartOnCompleteContext) => Promise<void> | void;
58
- onAbort?: (context: MultipartOnAbortContext) => Promise<void> | void;
59
- onList?: (context: MultipartOnListContext) => Promise<void> | void;
122
+ /**
123
+ * Named file route a mini {@link DimahS3Config} under `routes`.
124
+ * Upload, download, delete, and `upload.multipart` are off until set.
125
+ * Prefer one feature per route; combine only when those callers share
126
+ * the key namespace.
127
+ */
128
+ export type DimahS3RouteConfig = {
129
+ /** Override the instance S3 client for this route. */
130
+ client?: S3Client;
131
+ /** Override the instance bucket for this route. */
132
+ bucket?: string;
133
+ /**
134
+ * Object-key namespace. Generated keys and follow-up ops (confirm,
135
+ * download, delete, multipart) must stay under it.
136
+ * Defaults to the route name. `false` disables the bound.
137
+ */
138
+ keyPrefix?: string | false;
139
+ /** Runs before every operation on this route. */
140
+ guard?: (context: RouteGuardContext) => Promise<void> | void;
141
+ /**
142
+ * Opt out of instance plugins by id (`{ db: false }`).
143
+ * Hooks from opted-out plugins are not merged onto this route.
144
+ */
145
+ plugins?: {
146
+ readonly [pluginId: string]: false;
147
+ };
148
+ upload?: FeatureToggle<UploadConfig>;
149
+ download?: FeatureToggle<DownloadConfig>;
150
+ delete?: FeatureToggle<DeleteConfig>;
60
151
  };
61
- /** `true` or an options object enables the feature; omit or `false` disables it. */
62
- export type FeatureToggle<T> = boolean | T;
63
152
  /**
64
153
  * Options for {@link dimahS3}.
65
154
  *
66
155
  * @example
67
156
  * ```ts
68
- * export const awsS3 = new S3Client({ ... });
69
157
  * export const s3 = dimahS3({
70
158
  * client: awsS3,
71
159
  * bucket: "my-bucket",
72
- * upload: true,
160
+ * routes: {
161
+ * uploads: route({
162
+ * upload: { fileTypes: ["image/*"], multipart: true },
163
+ * }),
164
+ * },
73
165
  * });
74
166
  * ```
75
167
  */
76
168
  export type DimahS3Config = {
77
- /** AWS SDK v3 `S3Client`. Export it as `awsS3` so scripts and a custom backend can reuse it. */
78
- client: S3Client;
79
169
  /**
80
- * Default bucket. Used when the request omits `bucket`, and whenever a
81
- * client-sent bucket is ignored (the default). Hooks may still send
82
- * `bucket`; it only wins with {@link allowClientBucket} or {@link buckets}.
170
+ * Default AWS SDK v3 `S3Client`. Required unless every route sets
171
+ * {@link DimahS3RouteConfig.client}.
83
172
  */
84
- bucket: string;
173
+ client?: S3Client;
174
+ /**
175
+ * Default bucket. Required unless every route sets
176
+ * {@link DimahS3RouteConfig.bucket}.
177
+ */
178
+ bucket?: string;
85
179
  /**
86
180
  * API path prefix for the HTTP `handler`.
87
181
  * Must match `createS3Client({ basePath })` on the client.
@@ -89,56 +183,67 @@ export type DimahS3Config = {
89
183
  */
90
184
  basePath?: string;
91
185
  /**
92
- * When enabled, confirmation procedures call GetObjectAcl to infer whether
93
- * the object is public-read or private.
94
- *
95
- * Keep disabled unless you need ACL inference in responses/hooks —
96
- * it adds one extra S3 request per upload confirmation.
97
- *
98
- * @default false
99
- */
100
- resolveObjectAcl?: boolean;
101
- /**
102
- * Allow the client to pick any bucket. Off by default — the request `bucket`
103
- * is ignored and {@link bucket} is used.
104
- *
105
- * Mutually exclusive with {@link buckets}.
106
- */
107
- allowClientBucket?: boolean;
108
- /**
109
- * Allowlist of buckets the client may send. When set, a request bucket
110
- * outside this list is rejected. {@link bucket} should be included.
111
- *
112
- * Mutually exclusive with {@link allowClientBucket}.
113
- */
114
- buckets?: string[];
115
- /**
116
- * Upper bound for client `expiresIn` (seconds). Requests above this are
117
- * clamped. The protocol maximum is 7 days (604800).
186
+ * Upper bound for `upload.expiresIn` and `download.expiresIn` (seconds).
187
+ * The protocol maximum is 7 days (604800).
118
188
  * @default 604800
119
189
  */
120
190
  maxExpiresIn?: number;
121
- /** Runs before every operation. Throw to reject. */
191
+ /**
192
+ * Structured logs for lifecycle failures and unmatched router errors.
193
+ * `false` silences the default `console.error`.
194
+ */
195
+ logger?: DimahS3Logger | false;
196
+ /** Called after an unexpected throw is mapped to `INTERNAL_ERROR`. */
197
+ onError?: (error: unknown, context: {
198
+ request?: Request;
199
+ }) => void;
200
+ /** Runs before every operation, before route lookup. Throw to reject. */
122
201
  guard?: (context: GuardContext) => Promise<void> | void;
123
- upload?: FeatureToggle<UploadConfig>;
124
- download?: FeatureToggle<DownloadConfig>;
125
- delete?: FeatureToggle<DeleteConfig>;
126
- multipart?: FeatureToggle<MultipartConfig>;
127
202
  /**
128
203
  * Optional server plugins (e.g. `db()` from `@dimah-s3/db`).
129
- * Plugin hooks merge ahead of user hooks; contexts land on `s3.context[id]`
130
- * and are flattened onto the instance (`s3[id]`).
204
+ * Plugin hooks merge onto each route unless the route opts out.
131
205
  */
132
206
  plugins?: readonly DimahS3Plugin[];
207
+ /** Named file routes. At least one is required. */
208
+ routes: Record<string, DimahS3RouteConfig>;
209
+ };
210
+ type UploadFields = Omit<UploadConfig, "multipart">;
211
+ export type EnabledUploadConfig = EnabledFeature<UploadFields> & {
212
+ multipart: ResolvedFeature<MultipartConfig>;
133
213
  };
134
- type ResolvedFeature<T> = T & {
135
- enabled: boolean;
214
+ export type ResolvedUploadConfig = EnabledUploadConfig | (DisabledFeature & {
215
+ multipart: DisabledFeature;
216
+ });
217
+ /** One named route after {@link dimahS3} normalizes toggles and plugin hooks. */
218
+ export type ResolvedRoute = {
219
+ name: string;
220
+ client: S3Client;
221
+ bucket: string;
222
+ /** `false` means follow-up keys are not namespace-checked. */
223
+ keyPrefix: string | false;
224
+ guard?: DimahS3RouteConfig["guard"];
225
+ skippedPluginIds: ReadonlySet<string>;
226
+ upload: ResolvedUploadConfig;
227
+ download: ResolvedFeature<DownloadConfig>;
228
+ delete: ResolvedFeature<DeleteConfig>;
136
229
  };
137
- /** Feature flags after {@link dimahS3} normalizes booleans and defaults. */
138
- export type ResolvedDimahS3Config = Omit<DimahS3Config, "upload" | "download" | "delete" | "multipart" | "plugins"> & {
139
- upload?: ResolvedFeature<UploadConfig>;
140
- download?: ResolvedFeature<DownloadConfig>;
141
- delete?: ResolvedFeature<DeleteConfig>;
142
- multipart?: ResolvedFeature<MultipartConfig>;
230
+ /**
231
+ * A {@link ResolvedRoute} after the named operation has been asserted on.
232
+ * `route.upload.fileTypes` is typed as present only after opening `"upload"`.
233
+ */
234
+ export type OpenedRoute<F extends RouteOperation> = F extends "multipart" ? ResolvedRoute & {
235
+ upload: EnabledUploadConfig & {
236
+ multipart: EnabledFeature<MultipartConfig>;
237
+ };
238
+ } : F extends "upload" ? ResolvedRoute & {
239
+ upload: EnabledUploadConfig;
240
+ } : F extends "download" ? ResolvedRoute & {
241
+ download: EnabledFeature<DownloadConfig>;
242
+ } : F extends "delete" ? ResolvedRoute & {
243
+ delete: EnabledFeature<DeleteConfig>;
244
+ } : never;
245
+ /** Instance config after {@link dimahS3} normalizes routes and plugins. */
246
+ export type ResolvedDimahS3Config = Omit<DimahS3Config, "routes" | "plugins"> & {
247
+ routes: Record<string, ResolvedRoute>;
143
248
  };
144
249
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,117 @@
1
1
  import type { MultipartCompletedPartRef, MultipartPartInfo, S3ObjectAcl } from "@dimah-s3/core";
2
- /** Context for the global `guard` hook. */
2
+ /** Context for the instance `guard` hook. */
3
3
  export type GuardContext = {
4
4
  /** The incoming HTTP request. */
5
5
  request: Request;
6
6
  };
7
- type ObjectContext = GuardContext & {
7
+ /** Context for a route-level `guard` (every operation on that route). */
8
+ export type RouteGuardContext = GuardContext & {
9
+ /** Named file route. */
10
+ route: string;
11
+ };
12
+ /**
13
+ * Shared hook context once an object key is assigned — generated on
14
+ * upload / multipart init, or supplied on confirm / download / delete /
15
+ * multipart session ops.
16
+ */
17
+ export type StoredObjectContext = RouteGuardContext & {
8
18
  /** S3 object key. */
9
19
  key: string;
10
20
  /** Target bucket. */
11
21
  bucket: string;
12
22
  };
13
- /** Input to `prefix` / `resolveKey` on a feature config. */
14
- export type ResolveKeyContext = {
23
+ /** Declared file on upload / multipart init. */
24
+ export type ObjectFile = {
25
+ name: string;
26
+ size?: number;
27
+ type?: string;
28
+ };
29
+ /**
30
+ * Input to `upload.object` on presign / multipart init.
31
+ * `clientMetadata` is what the client sent — it is not written to S3
32
+ * unless `object` copies it into {@link UploadObjectInfo.metadata}.
33
+ */
34
+ export type UploadObjectContext = {
15
35
  request: Request;
16
- /** Key the client sent. */
17
- proposedKey: string;
18
- fileName?: string;
19
- contentType?: string;
36
+ route: string;
37
+ file: ObjectFile;
20
38
  bucket: string;
39
+ /**
40
+ * Namespace this route writes under. `false` skips the follow-up
41
+ * namespace check and generates `{uuid}/{name}` when `object` omits
42
+ * `folder` / `key`.
43
+ */
44
+ keyPrefix: string | false;
45
+ clientMetadata?: Record<string, string>;
21
46
  };
22
- /** Context for `upload.guard`. Client-declared values are not verified by S3. */
23
- export type UploadPresignGuardContext = ObjectContext & {
24
- /** MIME type the client sent — not verified until `onConfirmed`. */
25
- contentType?: string;
26
- /** Size the client sent — not verified until `onConfirmed`. */
27
- fileSize?: number;
28
- /** Custom object metadata. */
47
+ /** Server-owned S3 object identity from `upload.object`. */
48
+ export type UploadObjectInfo = {
49
+ /**
50
+ * Extra folder under the route {@link UploadObjectContext.keyPrefix}.
51
+ * Nested as `{keyPrefix}/{folder}/{uuid}/{name}` unless `keyPrefix` is
52
+ * `false` (`{folder}/{uuid}/{name}`). Ignored when {@link key} is set.
53
+ */
54
+ folder?: string;
55
+ /**
56
+ * Object key, nested under {@link UploadObjectContext.keyPrefix} unless
57
+ * the key is already inside that prefix or `keyPrefix` is `false`.
58
+ * If omitted, `{keyPrefix}/{folder}/{uuid}/{name}` is used
59
+ * (`{uuid}/{name}` when `keyPrefix` is `false` and `folder` is omitted).
60
+ */
61
+ key?: string;
62
+ /** S3 user metadata (`x-amz-meta-*`). */
29
63
  metadata?: Record<string, string>;
30
- /** Requested ACL. */
64
+ /** Override the route ACL for this object. */
31
65
  acl?: S3ObjectAcl;
32
- /** Original filename for `Content-Disposition`. */
33
- fileName?: string;
66
+ /**
67
+ * After confirm succeeds, delete this key (must stay under the route
68
+ * `keyPrefix`). Use with a new generated key to rotate avatars.
69
+ */
70
+ previousKey?: string;
34
71
  };
35
- /** Context for `upload.onPresigned`. */
36
- export type UploadOnPresignedContext = UploadPresignGuardContext & {
72
+ /**
73
+ * Context for `upload.guard`.
74
+ * Runs on single-shot presign and multipart init **after** `upload.object`
75
+ * so `key` is already assigned (plugins like `db()` check ownership here).
76
+ * Client-declared values are not verified by S3.
77
+ */
78
+ export type UploadGuardContext = StoredObjectContext & {
79
+ /** Declared file from the presign body — same shape as `upload.object`. */
80
+ file: ObjectFile;
81
+ /** S3 object metadata from route `object`. */
82
+ metadata?: Record<string, string>;
83
+ /** Client extras from the request — not written to S3 automatically. */
84
+ clientMetadata?: Record<string, string>;
85
+ /** Resolved ACL. */
86
+ acl?: S3ObjectAcl;
87
+ /** Route `upload.replace`. */
88
+ replace?: "overwrite";
89
+ };
90
+ /** Context for `upload.onPresigned` (single-shot only). */
91
+ export type UploadOnPresignedContext = UploadGuardContext & {
37
92
  /** Presigned upload URL. */
38
93
  url: string;
39
94
  /** Validity in seconds. */
40
95
  expiresIn: number;
41
96
  };
42
- /** Context for `upload.confirmGuard`. */
43
- export type UploadConfirmGuardContext = ObjectContext;
97
+ /**
98
+ * Context for `upload.confirmGuard`.
99
+ * Runs on single-shot confirm and multipart complete.
100
+ */
101
+ export type UploadConfirmGuardContext = StoredObjectContext & {
102
+ /** Present on multipart complete. */
103
+ uploadId?: string;
104
+ /** Parts to assemble. Present on multipart complete. */
105
+ parts?: MultipartCompletedPartRef[];
106
+ /** Route `upload.replace`. */
107
+ replace?: "overwrite";
108
+ };
44
109
  /**
45
110
  * Context for `upload.onConfirmed`.
46
111
  * `contentLength` and `eTag` are verified by S3 via HeadObject.
112
+ * Runs after single-shot confirm and multipart complete.
47
113
  */
48
- export type UploadOnConfirmedContext = GuardContext & {
49
- /** S3 object key. */
50
- key: string;
51
- /** Target bucket. */
52
- bucket: string;
114
+ export type UploadOnConfirmedContext = StoredObjectContext & {
53
115
  /** MIME type from HeadObject. */
54
116
  contentType?: string;
55
117
  /** Size from HeadObject — trust this, not the presign `fileSize`. */
@@ -58,7 +120,7 @@ export type UploadOnConfirmedContext = GuardContext & {
58
120
  eTag?: string;
59
121
  /** Object metadata. */
60
122
  metadata?: Record<string, string>;
61
- /** Resolved ACL. Omitted when ACL lookup is disabled or unsupported. */
123
+ /** ACL from the upload policy (`upload.acl` / `object`). */
62
124
  acl?: S3ObjectAcl;
63
125
  /** Stored filename. */
64
126
  fileName?: string;
@@ -66,87 +128,66 @@ export type UploadOnConfirmedContext = GuardContext & {
66
128
  versionId?: string;
67
129
  /** Last modified timestamp. */
68
130
  lastModified?: string;
131
+ /** Present after multipart complete. */
132
+ uploadId?: string;
69
133
  };
70
134
  /** Context for `download.guard`. */
71
- export type DownloadPresignGuardContext = ObjectContext & {
135
+ export type DownloadGuardContext = StoredObjectContext & {
72
136
  /** Download filename for Content-Disposition. */
73
137
  fileName?: string;
138
+ /** Client-requested or route default disposition. */
139
+ disposition?: "inline" | "attachment";
140
+ };
141
+ /** Per-request overrides from `download.resolve`. */
142
+ export type DownloadResolveInfo = {
143
+ disposition?: "inline" | "attachment";
144
+ expiresIn?: number;
145
+ fileName?: string;
74
146
  };
75
147
  /** Context for `download.onPresigned`. */
76
- export type DownloadOnPresignedContext = DownloadPresignGuardContext & {
148
+ export type DownloadOnPresignedContext = DownloadGuardContext & {
77
149
  /** Presigned GET URL. */
78
150
  url: string;
79
151
  /** Validity in seconds. */
80
152
  expiresIn: number;
81
153
  };
82
154
  /** Context for `delete.guard`. */
83
- export type DeleteGuardContext = ObjectContext;
155
+ export type DeleteGuardContext = StoredObjectContext;
84
156
  /** Context for `delete.onDeleted`. */
85
- export type DeleteOnDeletedContext = ObjectContext;
157
+ export type DeleteOnDeletedContext = StoredObjectContext;
86
158
  /** Shared base for multipart operations that already have an upload id. */
87
- export type MultipartUploadContext = ObjectContext & {
159
+ export type MultipartUploadContext = StoredObjectContext & {
88
160
  /** Multipart upload ID. */
89
161
  uploadId: string;
90
162
  };
91
- /** Context for `multipart.initGuard`. */
92
- export type MultipartInitGuardContext = ObjectContext & {
93
- /** Declared byte size of the file — available during init only. */
94
- fileSize?: number;
95
- /** MIME type the client sent — not verified until `onComplete`. */
96
- contentType?: string;
97
- /** Custom object metadata. */
98
- metadata?: Record<string, string>;
99
- /** Resolved ACL that will be applied at init. */
100
- acl?: S3ObjectAcl;
101
- /** Original filename for `Content-Disposition`. */
102
- fileName?: string;
163
+ /** Context for `upload.multipart.onInit`. */
164
+ export type MultipartOnInitContext = UploadGuardContext & {
165
+ /** Multipart upload ID. */
166
+ uploadId: string;
103
167
  };
104
- /** Context for `multipart.partGuard`. */
105
- export type MultipartPartGuardContext = MultipartUploadContext & {
168
+ /**
169
+ * Context for `upload.multipart.guard`.
170
+ * Runs on part, list, abort, and complete (init uses `upload.guard`).
171
+ * Complete also runs `upload.confirmGuard`.
172
+ */
173
+ export type MultipartGuardContext = (MultipartUploadContext & {
174
+ action: "part";
106
175
  /** 1-based part number. */
107
176
  partNumber: number;
108
177
  /** Byte size locked into the presigned URL signature. */
109
- partSize?: number;
110
- };
111
- /** Context for `multipart.completeGuard`. */
112
- export type MultipartCompleteGuardContext = MultipartUploadContext & {
113
- /** Parts to assemble. */
114
- parts: MultipartCompletedPartRef[];
115
- };
116
- /** Context for `multipart.abortGuard`. */
117
- export type MultipartAbortGuardContext = MultipartUploadContext;
118
- /** Context for `multipart.listGuard`. */
119
- export type MultipartListGuardContext = MultipartUploadContext;
120
- /** Context for `multipart.onInit`. */
121
- export type MultipartOnInitContext = MultipartInitGuardContext & {
122
- /** Multipart upload ID. */
123
- uploadId: string;
124
- };
125
- /** Context for `multipart.onComplete`. */
126
- export type MultipartOnCompleteContext = MultipartUploadContext & {
127
- /** Verified size in bytes. */
128
- contentLength: number;
129
- /** MIME type from HeadObject. */
130
- contentType?: string;
131
- /** ETag from HeadObject. */
132
- eTag?: string;
133
- /** Object metadata. */
134
- metadata: Record<string, string>;
135
- /** Resolved ACL. Omitted when ACL lookup is disabled or unsupported. */
136
- acl?: S3ObjectAcl;
137
- /** Stored filename. */
138
- fileName?: string;
139
- /** S3 version ID. */
140
- versionId?: string;
141
- /** Last modified timestamp. */
142
- lastModified?: string;
143
- };
144
- /** Context for `multipart.onAbort`. */
178
+ partSize: number;
179
+ }) | (MultipartUploadContext & {
180
+ action: "list";
181
+ }) | (MultipartUploadContext & {
182
+ action: "abort";
183
+ }) | (MultipartUploadContext & {
184
+ action: "complete";
185
+ });
186
+ /** Context for `upload.multipart.onAbort`. */
145
187
  export type MultipartOnAbortContext = MultipartUploadContext;
146
- /** Context for `multipart.onList`. */
188
+ /** Context for `upload.multipart.onList`. */
147
189
  export type MultipartOnListContext = MultipartUploadContext & {
148
190
  /** Parts already uploaded to S3. */
149
191
  parts: MultipartPartInfo[];
150
192
  };
151
- export {};
152
193
  //# sourceMappingURL=hook-contexts.d.ts.map