@modern-admin/feature-upload 0.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 (66) hide show
  1. package/dist/graphql.d.ts +36 -0
  2. package/dist/graphql.d.ts.map +1 -0
  3. package/dist/graphql.js +141 -0
  4. package/dist/graphql.js.map +1 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +12 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/nest/index.d.ts +3 -0
  10. package/dist/nest/index.d.ts.map +1 -0
  11. package/dist/nest/index.js +4 -0
  12. package/dist/nest/index.js.map +1 -0
  13. package/dist/nest/upload-sweeper.service.d.ts +32 -0
  14. package/dist/nest/upload-sweeper.service.d.ts.map +1 -0
  15. package/dist/nest/upload-sweeper.service.js +68 -0
  16. package/dist/nest/upload-sweeper.service.js.map +1 -0
  17. package/dist/nest/upload.controller.d.ts +51 -0
  18. package/dist/nest/upload.controller.d.ts.map +1 -0
  19. package/dist/nest/upload.controller.js +220 -0
  20. package/dist/nest/upload.controller.js.map +1 -0
  21. package/dist/nest/upload.module.d.ts +28 -0
  22. package/dist/nest/upload.module.d.ts.map +1 -0
  23. package/dist/nest/upload.module.js +51 -0
  24. package/dist/nest/upload.module.js.map +1 -0
  25. package/dist/nest/upload.tokens.d.ts +23 -0
  26. package/dist/nest/upload.tokens.d.ts.map +1 -0
  27. package/dist/nest/upload.tokens.js +6 -0
  28. package/dist/nest/upload.tokens.js.map +1 -0
  29. package/dist/pending-registry.d.ts +60 -0
  30. package/dist/pending-registry.d.ts.map +1 -0
  31. package/dist/pending-registry.js +106 -0
  32. package/dist/pending-registry.js.map +1 -0
  33. package/dist/providers/local.d.ts +36 -0
  34. package/dist/providers/local.d.ts.map +1 -0
  35. package/dist/providers/local.js +44 -0
  36. package/dist/providers/local.js.map +1 -0
  37. package/dist/providers/s3.d.ts +96 -0
  38. package/dist/providers/s3.d.ts.map +1 -0
  39. package/dist/providers/s3.js +164 -0
  40. package/dist/providers/s3.js.map +1 -0
  41. package/dist/registry.d.ts +27 -0
  42. package/dist/registry.d.ts.map +1 -0
  43. package/dist/registry.js +25 -0
  44. package/dist/registry.js.map +1 -0
  45. package/dist/types.d.ts +130 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +9 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/upload-feature.d.ts +31 -0
  50. package/dist/upload-feature.d.ts.map +1 -0
  51. package/dist/upload-feature.js +170 -0
  52. package/dist/upload-feature.js.map +1 -0
  53. package/package.json +94 -0
  54. package/src/graphql.ts +185 -0
  55. package/src/index.ts +22 -0
  56. package/src/nest/index.ts +4 -0
  57. package/src/nest/upload-sweeper.service.ts +52 -0
  58. package/src/nest/upload.controller.ts +228 -0
  59. package/src/nest/upload.module.ts +44 -0
  60. package/src/nest/upload.tokens.ts +24 -0
  61. package/src/pending-registry.ts +115 -0
  62. package/src/providers/local.ts +63 -0
  63. package/src/providers/s3.ts +226 -0
  64. package/src/registry.ts +39 -0
  65. package/src/types.ts +137 -0
  66. package/src/upload-feature.ts +208 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/providers/s3.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Process-level upload provider registry.
3
+ *
4
+ * `uploadFeature()` registers upload configs here (keyed by a generated id) at
5
+ * feature application time. The NestJS `UploadController` looks up configs by
6
+ * the id stored in the property's `custom.uploadProviderId` field.
7
+ *
8
+ * The registry is intentionally a module-level singleton so it is available
9
+ * before the NestJS DI container is initialised — the same pattern used by
10
+ * `ModernAdminFeatureRegistry` in `@modern-admin/nest`.
11
+ */
12
+ import type { IUploadProvider } from './types.js';
13
+ /** Everything stored per upload property registration. */
14
+ export interface RegisteredUploadConfig {
15
+ provider: IUploadProvider;
16
+ /** Optional custom key generator (from `UploadPropertyConfig.uploadPath`). */
17
+ uploadPath?: (filename: string) => string;
18
+ /** True for multi-file properties — controller will accept N files per request. */
19
+ isArray?: boolean;
20
+ }
21
+ export declare const UploadProviderRegistry: {
22
+ register(id: string, config: RegisteredUploadConfig): void;
23
+ get(id: string): RegisteredUploadConfig | undefined;
24
+ /** For test cleanup. */
25
+ clear(): void;
26
+ };
27
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,eAAe,CAAA;IACzB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;IACzC,mFAAmF;IACnF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAID,eAAO,MAAM,sBAAsB;iBACpB,MAAM,UAAU,sBAAsB,GAAG,IAAI;YAIlD,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAInD,wBAAwB;aACf,IAAI;CAGd,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Process-level upload provider registry.
3
+ *
4
+ * `uploadFeature()` registers upload configs here (keyed by a generated id) at
5
+ * feature application time. The NestJS `UploadController` looks up configs by
6
+ * the id stored in the property's `custom.uploadProviderId` field.
7
+ *
8
+ * The registry is intentionally a module-level singleton so it is available
9
+ * before the NestJS DI container is initialised — the same pattern used by
10
+ * `ModernAdminFeatureRegistry` in `@modern-admin/nest`.
11
+ */
12
+ const _registry = new Map();
13
+ export const UploadProviderRegistry = {
14
+ register(id, config) {
15
+ _registry.set(id, config);
16
+ },
17
+ get(id) {
18
+ return _registry.get(id);
19
+ },
20
+ /** For test cleanup. */
21
+ clear() {
22
+ _registry.clear();
23
+ },
24
+ };
25
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkC,CAAA;AAE3D,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ,CAAC,EAAU,EAAE,MAA8B;QACjD,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC3B,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,wBAAwB;IACxB,KAAK;QACH,SAAS,CAAC,KAAK,EAAE,CAAA;IACnB,CAAC;CACF,CAAA"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Core types for the upload feature plugin.
3
+ *
4
+ * `IUploadProvider` is the single port contract that upload backends must
5
+ * implement. `LocalUploadProvider` and `S3UploadProvider` ship as built-in
6
+ * adapters; custom providers only need to implement these four methods.
7
+ */
8
+ /** Parsed file data received from a multipart request. */
9
+ export interface UploadedFile {
10
+ /** Original filename from the client. */
11
+ originalName: string;
12
+ /** MIME type reported by the client (e.g. 'image/jpeg'). */
13
+ mimeType: string;
14
+ /** File size in bytes. */
15
+ size: number;
16
+ /** Raw file bytes. */
17
+ buffer: Buffer;
18
+ }
19
+ /** Metadata returned by the upload endpoint. */
20
+ export interface UploadedFileInfo {
21
+ /** Storage key (relative path or object key). Stored in the DB field. */
22
+ key: string;
23
+ /** Public URL for browser display / download. */
24
+ url: string;
25
+ /** Original filename. */
26
+ name: string;
27
+ /** Size in bytes. */
28
+ size: number;
29
+ /** MIME type. */
30
+ mimeType: string;
31
+ }
32
+ /**
33
+ * Upload provider port. Implement this interface to add a new storage backend.
34
+ *
35
+ * @example
36
+ * class GcsUploadProvider implements IUploadProvider {
37
+ * async upload(file) { ... }
38
+ * getUrl(key) { ... }
39
+ * async delete(key) { ... }
40
+ * }
41
+ */
42
+ export interface IUploadProvider {
43
+ /**
44
+ * Upload a file and return its storage key.
45
+ * The key is the value that will be persisted in the database field.
46
+ *
47
+ * @param file Parsed file data from the multipart request.
48
+ * @param key Optional pre-computed storage key (from `uploadPath`). When
49
+ * omitted the provider generates a key internally (UUID + extension).
50
+ */
51
+ upload(file: UploadedFile, key?: string): Promise<string>;
52
+ /**
53
+ * Compute the public URL for a stored key. May be sync or async.
54
+ * Used both by the upload endpoint (to return the URL) and by the frontend
55
+ * URL template when `urlTemplate()` is not implemented.
56
+ */
57
+ getUrl(key: string): string | Promise<string>;
58
+ /**
59
+ * Delete the file identified by `key`. Must not throw if the file does not
60
+ * exist (e.g. was already deleted or was never stored).
61
+ */
62
+ delete(key: string): Promise<void>;
63
+ /**
64
+ * Optional URL template string for the frontend to construct display URLs
65
+ * from stored keys without calling the backend.
66
+ * Use `{key}` as the placeholder, e.g. `'https://cdn.example.com/{key}'`.
67
+ * Return `undefined` (or omit the method) when URLs cannot be statically
68
+ * computed (e.g. signed/pre-signed S3 URLs — each URL is unique and time-limited).
69
+ */
70
+ urlTemplate?(): string | undefined;
71
+ }
72
+ /** Per-property upload configuration passed to `uploadFeature()`. */
73
+ export interface UploadPropertyConfig {
74
+ /** Storage provider for this property. */
75
+ provider: IUploadProvider;
76
+ /**
77
+ * Allowed MIME type patterns (same syntax as the HTML `accept` attribute).
78
+ * Examples: `['image/*']`, `['image/jpeg', 'application/pdf']`.
79
+ * Enforcement is advisory on the frontend; the controller does not re-validate.
80
+ */
81
+ mimeTypes?: string[];
82
+ /** Maximum upload size in bytes. Advisory (frontend warning only). */
83
+ maxSize?: number;
84
+ /**
85
+ * Treat the property as an array of file keys (multi-file upload).
86
+ * When true, the property is stored as `string[]`, the editor allows
87
+ * uploading multiple files (a single multipart request can include several),
88
+ * and the action hooks diff arrays on edit and delete every key on delete.
89
+ */
90
+ isArray?: boolean;
91
+ /**
92
+ * Custom storage key generator. Receives the original filename from the
93
+ * client and returns the key to use for storage.
94
+ *
95
+ * Use this to organise files into sub-directories, include the resource
96
+ * name, add timestamps, etc. The provider's internal UUID generator is
97
+ * used when this is omitted.
98
+ *
99
+ * @example
100
+ * // avatars/2024/01/uuid.jpg
101
+ * uploadPath: (filename) => {
102
+ * const ext = filename.split('.').pop()
103
+ * const d = new Date()
104
+ * return `avatars/${d.getFullYear()}/${String(d.getMonth()+1).padStart(2,'0')}/${uuidv7()}.${ext}`
105
+ * }
106
+ *
107
+ * @example
108
+ * // resource-specific prefix
109
+ * uploadPath: (filename) => `products/images/${uuidv7()}-${filename}`
110
+ */
111
+ uploadPath?: (filename: string) => string;
112
+ }
113
+ /** Options passed to `uploadFeature()`. */
114
+ export interface UploadFeatureOptions {
115
+ /**
116
+ * Map from property path to its upload configuration.
117
+ * Each entry makes the property a `type: 'file'` field wired to the
118
+ * specified provider.
119
+ *
120
+ * @example
121
+ * uploadFeature({
122
+ * properties: {
123
+ * avatar: { provider: new LocalUploadProvider({ uploadDir: './uploads', baseUrl: '/uploads' }) },
124
+ * resume: { provider: new S3UploadProvider({ bucket: 'my-bucket', region: 'us-east-1' }), mimeTypes: ['application/pdf'] },
125
+ * },
126
+ * })
127
+ */
128
+ properties: Record<string, UploadPropertyConfig>;
129
+ }
130
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAA;IAChB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAA;IACX,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEzD;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAE7C;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElC;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,0CAA0C;IAC1C,QAAQ,EAAE,eAAe,CAAA;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;CAC1C;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;OAYG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;CACjD"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Core types for the upload feature plugin.
3
+ *
4
+ * `IUploadProvider` is the single port contract that upload backends must
5
+ * implement. `LocalUploadProvider` and `S3UploadProvider` ship as built-in
6
+ * adapters; custom providers only need to implement these four methods.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `uploadFeature` — resource plugin that wires file upload into any resource.
3
+ *
4
+ * Returns a `FeatureFn` that, when applied to a resource's `ResourceOptions`,
5
+ * marks the configured properties as `type: 'file'` (with `isArray` when
6
+ * configured), registers the upload providers in `UploadProviderRegistry`, and
7
+ * installs action hooks that:
8
+ *
9
+ * - on `new.after` / `edit.after` — confirm freshly-uploaded keys against
10
+ * `PendingUploadsRegistry` so the orphan sweeper leaves them alone;
11
+ * - on `edit.after` — delete files whose key was replaced or removed
12
+ * (single-value: old !== new; array: keys present in old but missing
13
+ * from new);
14
+ * - on `delete.after` — delete every file referenced by the deleted record.
15
+ *
16
+ * Hooks are **chained**, not replaced: if the incoming `ResourceOptions`
17
+ * already has hooks (e.g. from another feature), the upload hooks are
18
+ * appended so all hooks run in order.
19
+ *
20
+ * @example
21
+ * uploadFeature({
22
+ * properties: {
23
+ * thumbnail: { provider: localProvider, mimeTypes: ['image/*'] },
24
+ * gallery: { provider: localProvider, isArray: true, mimeTypes: ['image/*'] },
25
+ * },
26
+ * })
27
+ */
28
+ import { type FeatureFn } from '@modern-admin/core';
29
+ import type { UploadFeatureOptions } from './types.js';
30
+ export declare function uploadFeature(options: UploadFeatureOptions): FeatureFn;
31
+ //# sourceMappingURL=upload-feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-feature.d.ts","sourceRoot":"","sources":["../src/upload-feature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAmD,KAAK,SAAS,EAAwB,MAAM,oBAAoB,CAAA;AAC1H,OAAO,KAAK,EAAE,oBAAoB,EAAwB,MAAM,YAAY,CAAA;AAiD5E,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAiItE"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * `uploadFeature` — resource plugin that wires file upload into any resource.
3
+ *
4
+ * Returns a `FeatureFn` that, when applied to a resource's `ResourceOptions`,
5
+ * marks the configured properties as `type: 'file'` (with `isArray` when
6
+ * configured), registers the upload providers in `UploadProviderRegistry`, and
7
+ * installs action hooks that:
8
+ *
9
+ * - on `new.after` / `edit.after` — confirm freshly-uploaded keys against
10
+ * `PendingUploadsRegistry` so the orphan sweeper leaves them alone;
11
+ * - on `edit.after` — delete files whose key was replaced or removed
12
+ * (single-value: old !== new; array: keys present in old but missing
13
+ * from new);
14
+ * - on `delete.after` — delete every file referenced by the deleted record.
15
+ *
16
+ * Hooks are **chained**, not replaced: if the incoming `ResourceOptions`
17
+ * already has hooks (e.g. from another feature), the upload hooks are
18
+ * appended so all hooks run in order.
19
+ *
20
+ * @example
21
+ * uploadFeature({
22
+ * properties: {
23
+ * thumbnail: { provider: localProvider, mimeTypes: ['image/*'] },
24
+ * gallery: { provider: localProvider, isArray: true, mimeTypes: ['image/*'] },
25
+ * },
26
+ * })
27
+ */
28
+ import { uuidv7 } from '@modern-admin/core';
29
+ import { UploadProviderRegistry } from './registry.js';
30
+ import { PendingUploadsRegistry } from './pending-registry.js';
31
+ /** Normalise a hook value (fn | fn[] | undefined) into an array. */
32
+ function toArray(hook) {
33
+ if (!hook)
34
+ return [];
35
+ return Array.isArray(hook) ? hook : [hook];
36
+ }
37
+ /**
38
+ * Merge `after` hooks from an existing action override with new hooks,
39
+ * producing an array that runs all of them in order.
40
+ * If `existing` already defines `after`, the new hooks are appended.
41
+ */
42
+ function mergeAfterHook(existing, newHook) {
43
+ const existing_after = toArray(existing?.after);
44
+ return [...existing_after, newHook];
45
+ }
46
+ // ─── Value helpers ────────────────────────────────────────────────────────────
47
+ /** Return non-empty file keys for the given value (handles single + array). */
48
+ function toKeys(value) {
49
+ if (value == null || value === '')
50
+ return [];
51
+ if (Array.isArray(value)) {
52
+ return value.flatMap((v) => (v == null || v === '' ? [] : [String(v)]));
53
+ }
54
+ return [String(value)];
55
+ }
56
+ // ─── Feature function ─────────────────────────────────────────────────────────
57
+ export function uploadFeature(options) {
58
+ // Register configs immediately — before the FeatureFn is called.
59
+ const registered = new Map();
60
+ for (const [propPath, config] of Object.entries(options.properties)) {
61
+ const providerId = `up_${uuidv7().replace(/-/g, '')}`;
62
+ UploadProviderRegistry.register(providerId, {
63
+ provider: config.provider,
64
+ uploadPath: config.uploadPath,
65
+ isArray: config.isArray ?? false,
66
+ });
67
+ registered.set(propPath, { providerId, config });
68
+ }
69
+ return (resourceOptions) => {
70
+ // --- Property overrides ---
71
+ const propOverrides = {};
72
+ for (const [propPath, { providerId, config }] of registered) {
73
+ // S3 with signed URLs has no static URL template.
74
+ const urlTmpl = config.provider.urlTemplate?.() ?? null;
75
+ propOverrides[propPath] = {
76
+ type: 'file',
77
+ ...(config.isArray ? { isArray: true } : {}),
78
+ custom: {
79
+ uploadProviderId: providerId,
80
+ uploadUrlTemplate: urlTmpl,
81
+ uploadMimeTypes: config.mimeTypes ?? null,
82
+ uploadMaxSize: config.maxSize ?? null,
83
+ },
84
+ };
85
+ }
86
+ // --- Action hooks ---
87
+ // After new: confirm every freshly-uploaded key against the pending registry.
88
+ const newAfterHook = (response, _request, _context) => {
89
+ const rec = response;
90
+ const params = rec.record?.params ?? {};
91
+ const newKeys = [];
92
+ for (const propPath of registered.keys()) {
93
+ newKeys.push(...toKeys(params[propPath]));
94
+ }
95
+ if (newKeys.length > 0)
96
+ PendingUploadsRegistry.confirm(newKeys);
97
+ return response;
98
+ };
99
+ // After edit: delete keys that disappeared and confirm keys that arrived.
100
+ const editAfterHook = async (response, _request, context) => {
101
+ const ctx = context;
102
+ const rec = response;
103
+ const params = rec.record?.params ?? {};
104
+ for (const [propPath, { config }] of registered) {
105
+ const oldKeys = new Set(toKeys(ctx.record?.get(propPath)));
106
+ const newKeys = toKeys(params[propPath]);
107
+ // Confirm new keys (possibly fresh uploads).
108
+ if (newKeys.length > 0)
109
+ PendingUploadsRegistry.confirm(newKeys);
110
+ // Delete keys that were present before and are gone now.
111
+ const newSet = new Set(newKeys);
112
+ for (const k of oldKeys) {
113
+ if (!newSet.has(k)) {
114
+ try {
115
+ await config.provider.delete(k);
116
+ }
117
+ catch {
118
+ // Non-fatal — don't break the action response.
119
+ }
120
+ }
121
+ }
122
+ }
123
+ return response;
124
+ };
125
+ // After delete: delete every file referenced by the (now-removed) record.
126
+ const deleteAfterHook = async (response, _request, context) => {
127
+ const ctx = context;
128
+ for (const [propPath, { config }] of registered) {
129
+ const keys = toKeys(ctx.record?.get(propPath));
130
+ for (const k of keys) {
131
+ try {
132
+ await config.provider.delete(k);
133
+ }
134
+ catch {
135
+ // Non-fatal.
136
+ }
137
+ }
138
+ }
139
+ return response;
140
+ };
141
+ // Retrieve any existing action overrides so we can chain, not replace.
142
+ const existingActions = resourceOptions.actions;
143
+ const existingNew = existingActions?.['new'];
144
+ const existingEdit = existingActions?.['edit'];
145
+ const existingDelete = existingActions?.['delete'];
146
+ const actionOverrides = {
147
+ new: {
148
+ ...existingNew,
149
+ after: mergeAfterHook(existingNew, newAfterHook),
150
+ },
151
+ edit: {
152
+ ...existingEdit,
153
+ after: mergeAfterHook(existingEdit, editAfterHook),
154
+ },
155
+ delete: {
156
+ ...existingDelete,
157
+ after: mergeAfterHook(existingDelete, deleteAfterHook),
158
+ },
159
+ };
160
+ return {
161
+ ...resourceOptions,
162
+ properties: { ...resourceOptions.properties, ...propOverrides },
163
+ actions: {
164
+ ...(resourceOptions.actions ?? {}),
165
+ ...actionOverrides,
166
+ },
167
+ };
168
+ };
169
+ }
170
+ //# sourceMappingURL=upload-feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-feature.js","sourceRoot":"","sources":["../src/upload-feature.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@modern-admin/feature-upload",
3
+ "version": "0.1.0",
4
+ "description": "File upload feature plugin for Modern Admin (local + S3 providers).",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/modern-admin/modern-admin.git",
10
+ "directory": "packages/feature-upload"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./nest": {
20
+ "types": "./dist/nest/index.d.ts",
21
+ "default": "./dist/nest/index.js"
22
+ },
23
+ "./graphql": {
24
+ "types": "./dist/graphql.d.ts",
25
+ "default": "./dist/graphql.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "src"
31
+ ],
32
+ "publishConfig": {
33
+ "registry": "https://registry.npmjs.org",
34
+ "access": "public",
35
+ "main": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "default": "./dist/index.js"
41
+ },
42
+ "./nest": {
43
+ "types": "./dist/nest/index.d.ts",
44
+ "default": "./dist/nest/index.js"
45
+ },
46
+ "./graphql": {
47
+ "types": "./dist/graphql.d.ts",
48
+ "default": "./dist/graphql.js"
49
+ }
50
+ }
51
+ },
52
+ "dependencies": {
53
+ "@modern-admin/core": "0.1.0",
54
+ "@nestjs/common": "^11.1.19",
55
+ "@nestjs/core": "^11.1.19",
56
+ "busboy": "^1.6.0",
57
+ "reflect-metadata": "^0.2.2",
58
+ "rxjs": "^7.8.2"
59
+ },
60
+ "devDependencies": {
61
+ "@modern-admin/graphql": "0.1.0",
62
+ "@modern-admin/nest": "0.1.0",
63
+ "@modern-admin/tsconfig": "0.1.0",
64
+ "@nestjs/swagger": "^11.4.2",
65
+ "@types/bun": "^1.3.13",
66
+ "@types/busboy": "^1.5.4",
67
+ "graphql": "^16.11.0",
68
+ "typescript": "^6.0.3"
69
+ },
70
+ "peerDependencies": {
71
+ "@aws-sdk/client-s3": "^3.0.0",
72
+ "@modern-admin/graphql": "0.1.0",
73
+ "@modern-admin/nest": "0.1.0",
74
+ "@nestjs/swagger": "^11.4.2",
75
+ "graphql": "^16.0.0"
76
+ },
77
+ "peerDependenciesMeta": {
78
+ "@aws-sdk/client-s3": {
79
+ "optional": true
80
+ },
81
+ "@modern-admin/graphql": {
82
+ "optional": true
83
+ },
84
+ "@modern-admin/nest": {
85
+ "optional": true
86
+ },
87
+ "@nestjs/swagger": {
88
+ "optional": true
89
+ },
90
+ "graphql": {
91
+ "optional": true
92
+ }
93
+ }
94
+ }