@strapi/upload 5.47.0 → 5.48.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 (126) hide show
  1. package/dist/admin/components/EditAssetDialog/EditAssetContent.js +12 -2
  2. package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
  3. package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +12 -2
  4. package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
  5. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js +1 -0
  6. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
  7. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs +1 -0
  8. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
  9. package/dist/admin/future/components/Drawer.js +7 -2
  10. package/dist/admin/future/components/Drawer.js.map +1 -1
  11. package/dist/admin/future/components/Drawer.mjs +7 -2
  12. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  13. package/dist/admin/future/components/UploadProgressDialog.js +33 -29
  14. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  15. package/dist/admin/future/components/UploadProgressDialog.mjs +36 -32
  16. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  17. package/dist/admin/future/pages/Assets/AssetsPage.js +2 -2
  18. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/AssetsPage.mjs +3 -3
  20. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +733 -148
  22. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  23. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +737 -155
  24. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  25. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +25 -5
  26. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +25 -5
  28. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -1
  29. package/dist/admin/future/services/api.js +124 -200
  30. package/dist/admin/future/services/api.js.map +1 -1
  31. package/dist/admin/future/services/api.mjs +124 -200
  32. package/dist/admin/future/services/api.mjs.map +1 -1
  33. package/dist/admin/future/services/assets.js +88 -1
  34. package/dist/admin/future/services/assets.js.map +1 -1
  35. package/dist/admin/future/services/assets.mjs +86 -2
  36. package/dist/admin/future/services/assets.mjs.map +1 -1
  37. package/dist/admin/future/services/folders.js +33 -1
  38. package/dist/admin/future/services/folders.js.map +1 -1
  39. package/dist/admin/future/services/folders.mjs +33 -2
  40. package/dist/admin/future/services/folders.mjs.map +1 -1
  41. package/dist/admin/future/services/settings.js +18 -0
  42. package/dist/admin/future/services/settings.js.map +1 -0
  43. package/dist/admin/future/services/settings.mjs +16 -0
  44. package/dist/admin/future/services/settings.mjs.map +1 -0
  45. package/dist/admin/future/services/uploadFileViaXHR.js +92 -0
  46. package/dist/admin/future/services/uploadFileViaXHR.js.map +1 -0
  47. package/dist/admin/future/services/uploadFileViaXHR.mjs +88 -0
  48. package/dist/admin/future/services/uploadFileViaXHR.mjs.map +1 -0
  49. package/dist/admin/future/store/uploadProgress.js +32 -26
  50. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  51. package/dist/admin/future/store/uploadProgress.mjs +32 -27
  52. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  53. package/dist/admin/future/utils/createRafBatcher.js +42 -0
  54. package/dist/admin/future/utils/createRafBatcher.js.map +1 -0
  55. package/dist/admin/future/utils/createRafBatcher.mjs +40 -0
  56. package/dist/admin/future/utils/createRafBatcher.mjs.map +1 -0
  57. package/dist/admin/future/utils/downloadFile.js +19 -0
  58. package/dist/admin/future/utils/downloadFile.js.map +1 -0
  59. package/dist/admin/future/utils/downloadFile.mjs +17 -0
  60. package/dist/admin/future/utils/downloadFile.mjs.map +1 -0
  61. package/dist/admin/hooks/useAssets.js +5 -3
  62. package/dist/admin/hooks/useAssets.js.map +1 -1
  63. package/dist/admin/hooks/useAssets.mjs +5 -3
  64. package/dist/admin/hooks/useAssets.mjs.map +1 -1
  65. package/dist/admin/index.js +1 -1
  66. package/dist/admin/index.mjs +1 -1
  67. package/dist/admin/src/components/EditAssetDialog/EditAssetContent.d.ts +2 -1
  68. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +22 -0
  69. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.d.ts +4 -1
  70. package/dist/admin/src/future/services/api.d.ts +9 -8
  71. package/dist/admin/src/future/services/assets.d.ts +11 -2
  72. package/dist/admin/src/future/services/folders.d.ts +1 -1
  73. package/dist/admin/src/future/services/uploadFileViaXHR.d.ts +34 -0
  74. package/dist/admin/src/future/store/uploadProgress.d.ts +17 -4
  75. package/dist/admin/src/future/utils/createRafBatcher.d.ts +23 -0
  76. package/dist/admin/src/future/utils/downloadFile.d.ts +6 -0
  77. package/dist/admin/translations/{dk.json.js → da.json.js} +3 -3
  78. package/dist/admin/translations/{dk.json.js.map → da.json.js.map} +1 -1
  79. package/dist/admin/translations/{dk.json.mjs → da.json.mjs} +3 -3
  80. package/dist/admin/translations/{dk.json.mjs.map → da.json.mjs.map} +1 -1
  81. package/dist/admin/translations/en.json.js +26 -1
  82. package/dist/admin/translations/en.json.js.map +1 -1
  83. package/dist/admin/translations/en.json.mjs +26 -1
  84. package/dist/admin/translations/en.json.mjs.map +1 -1
  85. package/dist/server/bootstrap.js +0 -3
  86. package/dist/server/bootstrap.js.map +1 -1
  87. package/dist/server/bootstrap.mjs +0 -3
  88. package/dist/server/bootstrap.mjs.map +1 -1
  89. package/dist/server/controllers/admin-upload.js +69 -118
  90. package/dist/server/controllers/admin-upload.js.map +1 -1
  91. package/dist/server/controllers/admin-upload.mjs +69 -118
  92. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  93. package/dist/server/routes/admin.js +2 -2
  94. package/dist/server/routes/admin.js.map +1 -1
  95. package/dist/server/routes/admin.mjs +2 -2
  96. package/dist/server/routes/admin.mjs.map +1 -1
  97. package/dist/server/services/ai-metadata-jobs.js +0 -23
  98. package/dist/server/services/ai-metadata-jobs.js.map +1 -1
  99. package/dist/server/services/ai-metadata-jobs.mjs +0 -23
  100. package/dist/server/services/ai-metadata-jobs.mjs.map +1 -1
  101. package/dist/server/services/image-manipulation.js +16 -8
  102. package/dist/server/services/image-manipulation.js.map +1 -1
  103. package/dist/server/services/image-manipulation.mjs +16 -8
  104. package/dist/server/services/image-manipulation.mjs.map +1 -1
  105. package/dist/server/services/upload.js +1 -1
  106. package/dist/server/services/upload.js.map +1 -1
  107. package/dist/server/services/upload.mjs +1 -1
  108. package/dist/server/services/upload.mjs.map +1 -1
  109. package/dist/server/src/bootstrap.d.ts.map +1 -1
  110. package/dist/server/src/controllers/admin-upload.d.ts +6 -8
  111. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  112. package/dist/server/src/controllers/index.d.ts +1 -1
  113. package/dist/server/src/index.d.ts +1 -2
  114. package/dist/server/src/index.d.ts.map +1 -1
  115. package/dist/server/src/services/ai-metadata-jobs.d.ts +0 -1
  116. package/dist/server/src/services/ai-metadata-jobs.d.ts.map +1 -1
  117. package/dist/server/src/services/image-manipulation.d.ts +5 -0
  118. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  119. package/dist/server/src/services/index.d.ts +0 -1
  120. package/dist/server/src/services/index.d.ts.map +1 -1
  121. package/dist/server/src/services/upload.d.ts.map +1 -1
  122. package/dist/server/src/types.d.ts +2 -2
  123. package/dist/server/src/types.d.ts.map +1 -1
  124. package/dist/shared/contracts/files.d.ts +19 -2
  125. package/dist/shared/contracts/files.d.ts.map +1 -1
  126. package/package.json +8 -8
@@ -69,11 +69,98 @@ const assetsApi = api.uploadApi.injectEndpoints({
69
69
  id
70
70
  }
71
71
  ]
72
+ }),
73
+ /**
74
+ * Update the editable metadata of an existing asset.
75
+ * Hits the legacy `POST /upload?id=<id>` endpoint which dispatches to
76
+ * `admin-upload.updateFileInfo`.
77
+ */ updateAsset: builder.mutation({
78
+ query: ({ id, fileInfo })=>{
79
+ const formData = new FormData();
80
+ formData.append('fileInfo', JSON.stringify(fileInfo));
81
+ return {
82
+ url: '/upload',
83
+ method: 'POST',
84
+ data: formData,
85
+ config: {
86
+ params: {
87
+ id
88
+ }
89
+ }
90
+ };
91
+ },
92
+ invalidatesTags: (_result, _error, { id })=>[
93
+ {
94
+ type: 'Asset',
95
+ id
96
+ },
97
+ {
98
+ type: 'Asset',
99
+ id: 'LIST'
100
+ }
101
+ ]
102
+ }),
103
+ /**
104
+ * Replace the binary content of an existing asset.
105
+ * Hits `POST /upload?id=<id>` with a multipart body — the controller
106
+ * dispatches to `admin-upload.replaceFile` when a `files` part is present.
107
+ * Uses the standard axios baseQuery (no streaming) since we only ever
108
+ * replace one file at a time and don't need per-byte progress here.
109
+ */ replaceAsset: builder.mutation({
110
+ query: ({ id, file, fileInfo })=>{
111
+ const formData = new FormData();
112
+ formData.append('files', file);
113
+ if (fileInfo) {
114
+ formData.append('fileInfo', JSON.stringify(fileInfo));
115
+ }
116
+ return {
117
+ url: '/upload',
118
+ method: 'POST',
119
+ data: formData,
120
+ config: {
121
+ params: {
122
+ id
123
+ }
124
+ }
125
+ };
126
+ },
127
+ invalidatesTags: (_result, _error, { id })=>[
128
+ {
129
+ type: 'Asset',
130
+ id
131
+ },
132
+ {
133
+ type: 'Asset',
134
+ id: 'LIST'
135
+ }
136
+ ]
137
+ }),
138
+ /**
139
+ * Permanently delete an asset by id. Hits the same endpoint as the legacy
140
+ * `useRemoveAsset` hook so server behaviour is unchanged.
141
+ */ deleteAsset: builder.mutation({
142
+ query: (id)=>({
143
+ url: `/upload/files/${id}`,
144
+ method: 'DELETE'
145
+ }),
146
+ invalidatesTags: (_result, _error, id)=>[
147
+ {
148
+ type: 'Asset',
149
+ id
150
+ },
151
+ {
152
+ type: 'Asset',
153
+ id: 'LIST'
154
+ }
155
+ ]
72
156
  })
73
157
  })
74
158
  });
75
- const { useGetAssetsQuery, useGetAssetQuery } = assetsApi;
159
+ const { useGetAssetsQuery, useGetAssetQuery, useUpdateAssetMutation, useReplaceAssetMutation, useDeleteAssetMutation } = assetsApi;
76
160
 
161
+ exports.useDeleteAssetMutation = useDeleteAssetMutation;
77
162
  exports.useGetAssetQuery = useGetAssetQuery;
78
163
  exports.useGetAssetsQuery = useGetAssetsQuery;
164
+ exports.useReplaceAssetMutation = useReplaceAssetMutation;
165
+ exports.useUpdateAssetMutation = useUpdateAssetMutation;
79
166
  //# sourceMappingURL=assets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assets.js","sources":["../../../../admin/src/future/services/assets.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n GetFiles,\n File,\n Pagination,\n AssetWithPopulatedCreatedBy,\n} from '../../../../shared/contracts/files';\n\ninterface GetAssetsParams {\n page?: number;\n pageSize?: number;\n folder?: number | null;\n sort?: string;\n}\n\ninterface GetAssetsResponse {\n results: File[];\n pagination: Pagination;\n}\n\nconst assetsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getAssets: builder.query<GetAssetsResponse, GetAssetsParams | void>({\n query: (params = {}) => {\n const { folder, ...rest } = params as GetAssetsParams;\n\n const queryParams: Record<string, unknown> = { ...rest };\n\n if (folder != null) {\n queryParams['filters'] = {\n $and: [{ folder: { id: folder } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ folder: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/files',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFiles.Response['data']) => response,\n providesTags: (result) =>\n result\n ? [\n ...result.results.map(({ id }) => ({ type: 'Asset' as const, id })),\n { type: 'Asset', id: 'LIST' },\n ]\n : [{ type: 'Asset', id: 'LIST' }],\n }),\n getAsset: builder.query<AssetWithPopulatedCreatedBy, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'GET',\n }),\n providesTags: (_result, _error, id) => [{ type: 'Asset' as const, id }],\n }),\n }),\n});\n\nexport const { useGetAssetsQuery, useGetAssetQuery } = assetsApi;\n"],"names":["assetsApi","uploadApi","injectEndpoints","endpoints","builder","getAssets","query","params","folder","rest","queryParams","$and","id","$null","url","method","config","transformResponse","response","providesTags","result","results","map","type","getAsset","_result","_error","useGetAssetsQuery","useGetAssetQuery"],"mappings":";;;;AAqBA,MAAMA,SAAAA,GAAYC,aAAAA,CAAUC,eAAe,CAAC;IAC1CC,SAAAA,EAAW,CAACC,WAAa;YACvBC,SAAAA,EAAWD,OAAAA,CAAQE,KAAK,CAA4C;gBAClEA,KAAAA,EAAO,CAACC,MAAAA,GAAS,EAAE,GAAA;AACjB,oBAAA,MAAM,EAAEC,MAAM,EAAE,GAAGC,MAAM,GAAGF,MAAAA;AAE5B,oBAAA,MAAMG,WAAAA,GAAuC;AAAE,wBAAA,GAAGD;AAAK,qBAAA;AAEvD,oBAAA,IAAID,UAAU,IAAA,EAAM;wBAClBE,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEH,MAAAA,EAAQ;wCAAEI,EAAAA,EAAIJ;AAAO;AAAE;AAAE;AACpC,yBAAA;oBACF,CAAA,MAAO;wBACLE,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEH,MAAAA,EAAQ;wCAAEI,EAAAA,EAAI;4CAAEC,KAAAA,EAAO;AAAK;AAAE;AAAE;AAAE;AAC7C,yBAAA;AACF,oBAAA;oBAEA,OAAO;wBACLC,GAAAA,EAAK,eAAA;wBACLC,MAAAA,EAAQ,KAAA;wBACRC,MAAAA,EAAQ;4BAAET,MAAAA,EAAQG;AAAY;AAChC,qBAAA;AACF,gBAAA,CAAA;AACAO,gBAAAA,iBAAAA,EAAmB,CAACC,QAAAA,GAAwCA,QAAAA;gBAC5DC,YAAAA,EAAc,CAACC,SACbA,MAAAA,GACI;2BACKA,MAAAA,CAAOC,OAAO,CAACC,GAAG,CAAC,CAAC,EAAEV,EAAE,EAAE,IAAM;gCAAEW,IAAAA,EAAM,OAAA;AAAkBX,gCAAAA;6BAAG,CAAA,CAAA;AAChE,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;4BAASX,EAAAA,EAAI;AAAO;qBAC7B,GACD;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;4BAASX,EAAAA,EAAI;AAAO;AAAE;AACvC,aAAA,CAAA;YACAY,QAAAA,EAAUpB,OAAAA,CAAQE,KAAK,CAAsC;gBAC3DA,KAAAA,EAAO,CAACM,MAAQ;wBACdE,GAAAA,EAAK,CAAC,cAAc,EAAEF,EAAAA,CAAAA,CAAI;wBAC1BG,MAAAA,EAAQ;qBACV,CAAA;gBACAI,YAAAA,EAAc,CAACM,OAAAA,EAASC,MAAAA,EAAQd,EAAAA,GAAO;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;AAAkBX,4BAAAA;AAAG;AAAE;AACzE,aAAA;SACF;AACF,CAAA,CAAA;MAEa,EAAEe,iBAAiB,EAAEC,gBAAgB,EAAE,GAAG5B;;;;;"}
1
+ {"version":3,"file":"assets.js","sources":["../../../../admin/src/future/services/assets.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n GetFiles,\n File,\n Pagination,\n UploadFileInfo,\n AssetWithPopulatedCreatedBy,\n} from '../../../../shared/contracts/files';\n\ninterface GetAssetsParams {\n page?: number;\n pageSize?: number;\n folder?: number | null;\n sort?: string;\n}\n\ninterface GetAssetsResponse {\n results: File[];\n pagination: Pagination;\n}\n\ninterface UpdateAssetArgs {\n id: number;\n fileInfo: Partial<UploadFileInfo>;\n}\n\ninterface ReplaceAssetArgs {\n id: number;\n // `File` is shadowed in this module by the asset-file contract type; the\n // global browser File is what we need for FormData.\n file: globalThis.File;\n fileInfo?: Partial<UploadFileInfo>;\n}\n\nconst assetsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getAssets: builder.query<GetAssetsResponse, GetAssetsParams | void>({\n query: (params = {}) => {\n const { folder, ...rest } = params as GetAssetsParams;\n\n const queryParams: Record<string, unknown> = { ...rest };\n\n if (folder != null) {\n queryParams['filters'] = {\n $and: [{ folder: { id: folder } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ folder: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/files',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFiles.Response['data']) => response,\n providesTags: (result) =>\n result\n ? [\n ...result.results.map(({ id }) => ({ type: 'Asset' as const, id })),\n { type: 'Asset', id: 'LIST' },\n ]\n : [{ type: 'Asset', id: 'LIST' }],\n }),\n getAsset: builder.query<AssetWithPopulatedCreatedBy, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'GET',\n }),\n providesTags: (_result, _error, id) => [{ type: 'Asset' as const, id }],\n }),\n /**\n * Update the editable metadata of an existing asset.\n * Hits the legacy `POST /upload?id=<id>` endpoint which dispatches to\n * `admin-upload.updateFileInfo`.\n */\n updateAsset: builder.mutation<AssetWithPopulatedCreatedBy, UpdateAssetArgs>({\n query: ({ id, fileInfo }) => {\n const formData = new FormData();\n formData.append('fileInfo', JSON.stringify(fileInfo));\n\n return {\n url: '/upload',\n method: 'POST',\n data: formData,\n config: { params: { id } },\n };\n },\n invalidatesTags: (_result, _error, { id }) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n /**\n * Replace the binary content of an existing asset.\n * Hits `POST /upload?id=<id>` with a multipart body — the controller\n * dispatches to `admin-upload.replaceFile` when a `files` part is present.\n * Uses the standard axios baseQuery (no streaming) since we only ever\n * replace one file at a time and don't need per-byte progress here.\n */\n replaceAsset: builder.mutation<AssetWithPopulatedCreatedBy, ReplaceAssetArgs>({\n query: ({ id, file, fileInfo }) => {\n const formData = new FormData();\n formData.append('files', file);\n if (fileInfo) {\n formData.append('fileInfo', JSON.stringify(fileInfo));\n }\n return {\n url: '/upload',\n method: 'POST',\n data: formData,\n config: { params: { id } },\n };\n },\n invalidatesTags: (_result, _error, { id }) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n /**\n * Permanently delete an asset by id. Hits the same endpoint as the legacy\n * `useRemoveAsset` hook so server behaviour is unchanged.\n */\n deleteAsset: builder.mutation<unknown, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'DELETE',\n }),\n invalidatesTags: (_result, _error, id) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n }),\n});\n\nexport const {\n useGetAssetsQuery,\n useGetAssetQuery,\n useUpdateAssetMutation,\n useReplaceAssetMutation,\n useDeleteAssetMutation,\n} = assetsApi;\n"],"names":["assetsApi","uploadApi","injectEndpoints","endpoints","builder","getAssets","query","params","folder","rest","queryParams","$and","id","$null","url","method","config","transformResponse","response","providesTags","result","results","map","type","getAsset","_result","_error","updateAsset","mutation","fileInfo","formData","FormData","append","JSON","stringify","data","invalidatesTags","replaceAsset","file","deleteAsset","useGetAssetsQuery","useGetAssetQuery","useUpdateAssetMutation","useReplaceAssetMutation","useDeleteAssetMutation"],"mappings":"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"}
@@ -67,10 +67,94 @@ const assetsApi = uploadApi.injectEndpoints({
67
67
  id
68
68
  }
69
69
  ]
70
+ }),
71
+ /**
72
+ * Update the editable metadata of an existing asset.
73
+ * Hits the legacy `POST /upload?id=<id>` endpoint which dispatches to
74
+ * `admin-upload.updateFileInfo`.
75
+ */ updateAsset: builder.mutation({
76
+ query: ({ id, fileInfo })=>{
77
+ const formData = new FormData();
78
+ formData.append('fileInfo', JSON.stringify(fileInfo));
79
+ return {
80
+ url: '/upload',
81
+ method: 'POST',
82
+ data: formData,
83
+ config: {
84
+ params: {
85
+ id
86
+ }
87
+ }
88
+ };
89
+ },
90
+ invalidatesTags: (_result, _error, { id })=>[
91
+ {
92
+ type: 'Asset',
93
+ id
94
+ },
95
+ {
96
+ type: 'Asset',
97
+ id: 'LIST'
98
+ }
99
+ ]
100
+ }),
101
+ /**
102
+ * Replace the binary content of an existing asset.
103
+ * Hits `POST /upload?id=<id>` with a multipart body — the controller
104
+ * dispatches to `admin-upload.replaceFile` when a `files` part is present.
105
+ * Uses the standard axios baseQuery (no streaming) since we only ever
106
+ * replace one file at a time and don't need per-byte progress here.
107
+ */ replaceAsset: builder.mutation({
108
+ query: ({ id, file, fileInfo })=>{
109
+ const formData = new FormData();
110
+ formData.append('files', file);
111
+ if (fileInfo) {
112
+ formData.append('fileInfo', JSON.stringify(fileInfo));
113
+ }
114
+ return {
115
+ url: '/upload',
116
+ method: 'POST',
117
+ data: formData,
118
+ config: {
119
+ params: {
120
+ id
121
+ }
122
+ }
123
+ };
124
+ },
125
+ invalidatesTags: (_result, _error, { id })=>[
126
+ {
127
+ type: 'Asset',
128
+ id
129
+ },
130
+ {
131
+ type: 'Asset',
132
+ id: 'LIST'
133
+ }
134
+ ]
135
+ }),
136
+ /**
137
+ * Permanently delete an asset by id. Hits the same endpoint as the legacy
138
+ * `useRemoveAsset` hook so server behaviour is unchanged.
139
+ */ deleteAsset: builder.mutation({
140
+ query: (id)=>({
141
+ url: `/upload/files/${id}`,
142
+ method: 'DELETE'
143
+ }),
144
+ invalidatesTags: (_result, _error, id)=>[
145
+ {
146
+ type: 'Asset',
147
+ id
148
+ },
149
+ {
150
+ type: 'Asset',
151
+ id: 'LIST'
152
+ }
153
+ ]
70
154
  })
71
155
  })
72
156
  });
73
- const { useGetAssetsQuery, useGetAssetQuery } = assetsApi;
157
+ const { useGetAssetsQuery, useGetAssetQuery, useUpdateAssetMutation, useReplaceAssetMutation, useDeleteAssetMutation } = assetsApi;
74
158
 
75
- export { useGetAssetQuery, useGetAssetsQuery };
159
+ export { useDeleteAssetMutation, useGetAssetQuery, useGetAssetsQuery, useReplaceAssetMutation, useUpdateAssetMutation };
76
160
  //# sourceMappingURL=assets.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"assets.mjs","sources":["../../../../admin/src/future/services/assets.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n GetFiles,\n File,\n Pagination,\n AssetWithPopulatedCreatedBy,\n} from '../../../../shared/contracts/files';\n\ninterface GetAssetsParams {\n page?: number;\n pageSize?: number;\n folder?: number | null;\n sort?: string;\n}\n\ninterface GetAssetsResponse {\n results: File[];\n pagination: Pagination;\n}\n\nconst assetsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getAssets: builder.query<GetAssetsResponse, GetAssetsParams | void>({\n query: (params = {}) => {\n const { folder, ...rest } = params as GetAssetsParams;\n\n const queryParams: Record<string, unknown> = { ...rest };\n\n if (folder != null) {\n queryParams['filters'] = {\n $and: [{ folder: { id: folder } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ folder: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/files',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFiles.Response['data']) => response,\n providesTags: (result) =>\n result\n ? [\n ...result.results.map(({ id }) => ({ type: 'Asset' as const, id })),\n { type: 'Asset', id: 'LIST' },\n ]\n : [{ type: 'Asset', id: 'LIST' }],\n }),\n getAsset: builder.query<AssetWithPopulatedCreatedBy, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'GET',\n }),\n providesTags: (_result, _error, id) => [{ type: 'Asset' as const, id }],\n }),\n }),\n});\n\nexport const { useGetAssetsQuery, useGetAssetQuery } = assetsApi;\n"],"names":["assetsApi","uploadApi","injectEndpoints","endpoints","builder","getAssets","query","params","folder","rest","queryParams","$and","id","$null","url","method","config","transformResponse","response","providesTags","result","results","map","type","getAsset","_result","_error","useGetAssetsQuery","useGetAssetQuery"],"mappings":";;AAqBA,MAAMA,SAAAA,GAAYC,SAAAA,CAAUC,eAAe,CAAC;IAC1CC,SAAAA,EAAW,CAACC,WAAa;YACvBC,SAAAA,EAAWD,OAAAA,CAAQE,KAAK,CAA4C;gBAClEA,KAAAA,EAAO,CAACC,MAAAA,GAAS,EAAE,GAAA;AACjB,oBAAA,MAAM,EAAEC,MAAM,EAAE,GAAGC,MAAM,GAAGF,MAAAA;AAE5B,oBAAA,MAAMG,WAAAA,GAAuC;AAAE,wBAAA,GAAGD;AAAK,qBAAA;AAEvD,oBAAA,IAAID,UAAU,IAAA,EAAM;wBAClBE,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEH,MAAAA,EAAQ;wCAAEI,EAAAA,EAAIJ;AAAO;AAAE;AAAE;AACpC,yBAAA;oBACF,CAAA,MAAO;wBACLE,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEH,MAAAA,EAAQ;wCAAEI,EAAAA,EAAI;4CAAEC,KAAAA,EAAO;AAAK;AAAE;AAAE;AAAE;AAC7C,yBAAA;AACF,oBAAA;oBAEA,OAAO;wBACLC,GAAAA,EAAK,eAAA;wBACLC,MAAAA,EAAQ,KAAA;wBACRC,MAAAA,EAAQ;4BAAET,MAAAA,EAAQG;AAAY;AAChC,qBAAA;AACF,gBAAA,CAAA;AACAO,gBAAAA,iBAAAA,EAAmB,CAACC,QAAAA,GAAwCA,QAAAA;gBAC5DC,YAAAA,EAAc,CAACC,SACbA,MAAAA,GACI;2BACKA,MAAAA,CAAOC,OAAO,CAACC,GAAG,CAAC,CAAC,EAAEV,EAAE,EAAE,IAAM;gCAAEW,IAAAA,EAAM,OAAA;AAAkBX,gCAAAA;6BAAG,CAAA,CAAA;AAChE,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;4BAASX,EAAAA,EAAI;AAAO;qBAC7B,GACD;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;4BAASX,EAAAA,EAAI;AAAO;AAAE;AACvC,aAAA,CAAA;YACAY,QAAAA,EAAUpB,OAAAA,CAAQE,KAAK,CAAsC;gBAC3DA,KAAAA,EAAO,CAACM,MAAQ;wBACdE,GAAAA,EAAK,CAAC,cAAc,EAAEF,EAAAA,CAAAA,CAAI;wBAC1BG,MAAAA,EAAQ;qBACV,CAAA;gBACAI,YAAAA,EAAc,CAACM,OAAAA,EAASC,MAAAA,EAAQd,EAAAA,GAAO;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,OAAA;AAAkBX,4BAAAA;AAAG;AAAE;AACzE,aAAA;SACF;AACF,CAAA,CAAA;MAEa,EAAEe,iBAAiB,EAAEC,gBAAgB,EAAE,GAAG5B;;;;"}
1
+ {"version":3,"file":"assets.mjs","sources":["../../../../admin/src/future/services/assets.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n GetFiles,\n File,\n Pagination,\n UploadFileInfo,\n AssetWithPopulatedCreatedBy,\n} from '../../../../shared/contracts/files';\n\ninterface GetAssetsParams {\n page?: number;\n pageSize?: number;\n folder?: number | null;\n sort?: string;\n}\n\ninterface GetAssetsResponse {\n results: File[];\n pagination: Pagination;\n}\n\ninterface UpdateAssetArgs {\n id: number;\n fileInfo: Partial<UploadFileInfo>;\n}\n\ninterface ReplaceAssetArgs {\n id: number;\n // `File` is shadowed in this module by the asset-file contract type; the\n // global browser File is what we need for FormData.\n file: globalThis.File;\n fileInfo?: Partial<UploadFileInfo>;\n}\n\nconst assetsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getAssets: builder.query<GetAssetsResponse, GetAssetsParams | void>({\n query: (params = {}) => {\n const { folder, ...rest } = params as GetAssetsParams;\n\n const queryParams: Record<string, unknown> = { ...rest };\n\n if (folder != null) {\n queryParams['filters'] = {\n $and: [{ folder: { id: folder } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ folder: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/files',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFiles.Response['data']) => response,\n providesTags: (result) =>\n result\n ? [\n ...result.results.map(({ id }) => ({ type: 'Asset' as const, id })),\n { type: 'Asset', id: 'LIST' },\n ]\n : [{ type: 'Asset', id: 'LIST' }],\n }),\n getAsset: builder.query<AssetWithPopulatedCreatedBy, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'GET',\n }),\n providesTags: (_result, _error, id) => [{ type: 'Asset' as const, id }],\n }),\n /**\n * Update the editable metadata of an existing asset.\n * Hits the legacy `POST /upload?id=<id>` endpoint which dispatches to\n * `admin-upload.updateFileInfo`.\n */\n updateAsset: builder.mutation<AssetWithPopulatedCreatedBy, UpdateAssetArgs>({\n query: ({ id, fileInfo }) => {\n const formData = new FormData();\n formData.append('fileInfo', JSON.stringify(fileInfo));\n\n return {\n url: '/upload',\n method: 'POST',\n data: formData,\n config: { params: { id } },\n };\n },\n invalidatesTags: (_result, _error, { id }) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n /**\n * Replace the binary content of an existing asset.\n * Hits `POST /upload?id=<id>` with a multipart body — the controller\n * dispatches to `admin-upload.replaceFile` when a `files` part is present.\n * Uses the standard axios baseQuery (no streaming) since we only ever\n * replace one file at a time and don't need per-byte progress here.\n */\n replaceAsset: builder.mutation<AssetWithPopulatedCreatedBy, ReplaceAssetArgs>({\n query: ({ id, file, fileInfo }) => {\n const formData = new FormData();\n formData.append('files', file);\n if (fileInfo) {\n formData.append('fileInfo', JSON.stringify(fileInfo));\n }\n return {\n url: '/upload',\n method: 'POST',\n data: formData,\n config: { params: { id } },\n };\n },\n invalidatesTags: (_result, _error, { id }) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n /**\n * Permanently delete an asset by id. Hits the same endpoint as the legacy\n * `useRemoveAsset` hook so server behaviour is unchanged.\n */\n deleteAsset: builder.mutation<unknown, number>({\n query: (id) => ({\n url: `/upload/files/${id}`,\n method: 'DELETE',\n }),\n invalidatesTags: (_result, _error, id) => [\n { type: 'Asset' as const, id },\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n }),\n});\n\nexport const {\n useGetAssetsQuery,\n useGetAssetQuery,\n useUpdateAssetMutation,\n useReplaceAssetMutation,\n useDeleteAssetMutation,\n} = assetsApi;\n"],"names":["assetsApi","uploadApi","injectEndpoints","endpoints","builder","getAssets","query","params","folder","rest","queryParams","$and","id","$null","url","method","config","transformResponse","response","providesTags","result","results","map","type","getAsset","_result","_error","updateAsset","mutation","fileInfo","formData","FormData","append","JSON","stringify","data","invalidatesTags","replaceAsset","file","deleteAsset","useGetAssetsQuery","useGetAssetQuery","useUpdateAssetMutation","useReplaceAssetMutation","useDeleteAssetMutation"],"mappings":"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"}
@@ -76,6 +76,37 @@ const foldersApi = api.uploadApi.injectEndpoints({
76
76
  }
77
77
  ]
78
78
  }),
79
+ /**
80
+ * Flat list of every folder, used to populate the "Location" select in the
81
+ * asset details drawer. No parent filter — we want the entire tree in one
82
+ * query so the select can render any destination folder.
83
+ */ getAllFolders: builder.query({
84
+ query: ()=>({
85
+ url: '/upload/folders',
86
+ method: 'GET'
87
+ }),
88
+ transformResponse: (response)=>response?.data ?? response ?? [],
89
+ providesTags: (results)=>{
90
+ if (results) {
91
+ return [
92
+ ...results.map(({ id })=>({
93
+ type: 'Folder',
94
+ id
95
+ })),
96
+ {
97
+ type: 'Folder',
98
+ id: 'LIST'
99
+ }
100
+ ];
101
+ }
102
+ return [
103
+ {
104
+ type: 'Folder',
105
+ id: 'LIST'
106
+ }
107
+ ];
108
+ }
109
+ }),
79
110
  getFolder: builder.query({
80
111
  query: ({ id })=>({
81
112
  url: `/upload/folders/${id}`,
@@ -108,9 +139,10 @@ const foldersApi = api.uploadApi.injectEndpoints({
108
139
  })
109
140
  })
110
141
  });
111
- const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery } = foldersApi;
142
+ const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery, useGetAllFoldersQuery } = foldersApi;
112
143
 
113
144
  exports.useCreateFolderMutation = useCreateFolderMutation;
145
+ exports.useGetAllFoldersQuery = useGetAllFoldersQuery;
114
146
  exports.useGetFolderQuery = useGetFolderQuery;
115
147
  exports.useGetFoldersQuery = useGetFoldersQuery;
116
148
  //# sourceMappingURL=folders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"folders.js","sources":["../../../../admin/src/future/services/folders.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n Folder,\n CreateFolders,\n GetFolder,\n GetFolders,\n} from '../../../../shared/contracts/folders';\n\nexport type FolderWithCounts = Omit<Folder, 'children' | 'files'> & {\n children?: { count: number };\n files?: { count: number };\n};\n\ninterface GetFoldersParams {\n parentId?: number | null;\n}\n\nconst foldersApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getFolders: builder.query<Folder[], GetFoldersParams | void>({\n query: (params = {}) => {\n const { parentId } = params as GetFoldersParams;\n\n const queryParams: Record<string, unknown> = {};\n\n if (parentId != null) {\n queryParams['filters'] = {\n $and: [{ parent: { id: parentId } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ parent: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/folders',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFolders.Response['data']) =>\n // TODO dont want this cast\n (response as any).data,\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder', id: 'LIST' },\n ];\n }\n return [{ type: 'Folder', id: 'LIST' }];\n },\n }),\n createFolder: builder.mutation<CreateFolders.Response['data'], CreateFolders.Request['body']>({\n query: (body) => ({\n url: '/upload/folders',\n method: 'POST',\n data: body,\n }),\n transformResponse: (response: CreateFolders.Response) => response.data,\n invalidatesTags: [{ type: 'Folder', id: 'LIST' }],\n }),\n getFolder: builder.query<FolderWithCounts, { id: number }>({\n query: ({ id }) => ({\n url: `/upload/folders/${id}`,\n method: 'GET',\n config: {\n params: {\n populate: {\n parent: {\n populate: {\n parent: '*',\n },\n },\n children: { count: true },\n files: { count: true },\n },\n },\n },\n }),\n transformResponse: (response: GetFolder.Response) =>\n response.data as unknown as FolderWithCounts,\n providesTags: (_result, _error, { id }) => [{ type: 'Folder', id }],\n }),\n }),\n});\n\nexport const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery } = foldersApi;\n"],"names":["foldersApi","uploadApi","injectEndpoints","endpoints","builder","getFolders","query","params","parentId","queryParams","$and","parent","id","$null","url","method","config","transformResponse","response","data","providesTags","results","map","type","createFolder","mutation","body","invalidatesTags","getFolder","populate","children","count","files","_result","_error","useCreateFolderMutation","useGetFoldersQuery","useGetFolderQuery"],"mappings":"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"}
1
+ {"version":3,"file":"folders.js","sources":["../../../../admin/src/future/services/folders.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n Folder,\n CreateFolders,\n GetFolder,\n GetFolders,\n} from '../../../../shared/contracts/folders';\n\nexport type FolderWithCounts = Omit<Folder, 'children' | 'files'> & {\n children?: { count: number };\n files?: { count: number };\n};\n\ninterface GetFoldersParams {\n parentId?: number | null;\n}\n\nconst foldersApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getFolders: builder.query<Folder[], GetFoldersParams | void>({\n query: (params = {}) => {\n const { parentId } = params as GetFoldersParams;\n\n const queryParams: Record<string, unknown> = {};\n\n if (parentId != null) {\n queryParams['filters'] = {\n $and: [{ parent: { id: parentId } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ parent: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/folders',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFolders.Response['data']) =>\n // TODO dont want this cast\n (response as any).data,\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder', id: 'LIST' },\n ];\n }\n return [{ type: 'Folder', id: 'LIST' }];\n },\n }),\n createFolder: builder.mutation<CreateFolders.Response['data'], CreateFolders.Request['body']>({\n query: (body) => ({\n url: '/upload/folders',\n method: 'POST',\n data: body,\n }),\n transformResponse: (response: CreateFolders.Response) => response.data,\n invalidatesTags: [{ type: 'Folder', id: 'LIST' }],\n }),\n /**\n * Flat list of every folder, used to populate the \"Location\" select in the\n * asset details drawer. No parent filter — we want the entire tree in one\n * query so the select can render any destination folder.\n */\n getAllFolders: builder.query<Folder[], void>({\n query: () => ({\n url: '/upload/folders',\n method: 'GET',\n }),\n transformResponse: (response: GetFolders.Response['data']) =>\n ((response as any)?.data ?? response ?? []) as Folder[],\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder' as const, id: 'LIST' },\n ];\n }\n return [{ type: 'Folder' as const, id: 'LIST' }];\n },\n }),\n getFolder: builder.query<FolderWithCounts, { id: number }>({\n query: ({ id }) => ({\n url: `/upload/folders/${id}`,\n method: 'GET',\n config: {\n params: {\n populate: {\n parent: {\n populate: {\n parent: '*',\n },\n },\n children: { count: true },\n files: { count: true },\n },\n },\n },\n }),\n transformResponse: (response: GetFolder.Response) =>\n response.data as unknown as FolderWithCounts,\n providesTags: (_result, _error, { id }) => [{ type: 'Folder', id }],\n }),\n }),\n});\n\nexport const {\n useCreateFolderMutation,\n useGetFoldersQuery,\n useGetFolderQuery,\n useGetAllFoldersQuery,\n} = foldersApi;\n"],"names":["foldersApi","uploadApi","injectEndpoints","endpoints","builder","getFolders","query","params","parentId","queryParams","$and","parent","id","$null","url","method","config","transformResponse","response","data","providesTags","results","map","type","createFolder","mutation","body","invalidatesTags","getAllFolders","getFolder","populate","children","count","files","_result","_error","useCreateFolderMutation","useGetFoldersQuery","useGetFolderQuery","useGetAllFoldersQuery"],"mappings":"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"}
@@ -74,6 +74,37 @@ const foldersApi = uploadApi.injectEndpoints({
74
74
  }
75
75
  ]
76
76
  }),
77
+ /**
78
+ * Flat list of every folder, used to populate the "Location" select in the
79
+ * asset details drawer. No parent filter — we want the entire tree in one
80
+ * query so the select can render any destination folder.
81
+ */ getAllFolders: builder.query({
82
+ query: ()=>({
83
+ url: '/upload/folders',
84
+ method: 'GET'
85
+ }),
86
+ transformResponse: (response)=>response?.data ?? response ?? [],
87
+ providesTags: (results)=>{
88
+ if (results) {
89
+ return [
90
+ ...results.map(({ id })=>({
91
+ type: 'Folder',
92
+ id
93
+ })),
94
+ {
95
+ type: 'Folder',
96
+ id: 'LIST'
97
+ }
98
+ ];
99
+ }
100
+ return [
101
+ {
102
+ type: 'Folder',
103
+ id: 'LIST'
104
+ }
105
+ ];
106
+ }
107
+ }),
77
108
  getFolder: builder.query({
78
109
  query: ({ id })=>({
79
110
  url: `/upload/folders/${id}`,
@@ -106,7 +137,7 @@ const foldersApi = uploadApi.injectEndpoints({
106
137
  })
107
138
  })
108
139
  });
109
- const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery } = foldersApi;
140
+ const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery, useGetAllFoldersQuery } = foldersApi;
110
141
 
111
- export { useCreateFolderMutation, useGetFolderQuery, useGetFoldersQuery };
142
+ export { useCreateFolderMutation, useGetAllFoldersQuery, useGetFolderQuery, useGetFoldersQuery };
112
143
  //# sourceMappingURL=folders.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"folders.mjs","sources":["../../../../admin/src/future/services/folders.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n Folder,\n CreateFolders,\n GetFolder,\n GetFolders,\n} from '../../../../shared/contracts/folders';\n\nexport type FolderWithCounts = Omit<Folder, 'children' | 'files'> & {\n children?: { count: number };\n files?: { count: number };\n};\n\ninterface GetFoldersParams {\n parentId?: number | null;\n}\n\nconst foldersApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getFolders: builder.query<Folder[], GetFoldersParams | void>({\n query: (params = {}) => {\n const { parentId } = params as GetFoldersParams;\n\n const queryParams: Record<string, unknown> = {};\n\n if (parentId != null) {\n queryParams['filters'] = {\n $and: [{ parent: { id: parentId } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ parent: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/folders',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFolders.Response['data']) =>\n // TODO dont want this cast\n (response as any).data,\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder', id: 'LIST' },\n ];\n }\n return [{ type: 'Folder', id: 'LIST' }];\n },\n }),\n createFolder: builder.mutation<CreateFolders.Response['data'], CreateFolders.Request['body']>({\n query: (body) => ({\n url: '/upload/folders',\n method: 'POST',\n data: body,\n }),\n transformResponse: (response: CreateFolders.Response) => response.data,\n invalidatesTags: [{ type: 'Folder', id: 'LIST' }],\n }),\n getFolder: builder.query<FolderWithCounts, { id: number }>({\n query: ({ id }) => ({\n url: `/upload/folders/${id}`,\n method: 'GET',\n config: {\n params: {\n populate: {\n parent: {\n populate: {\n parent: '*',\n },\n },\n children: { count: true },\n files: { count: true },\n },\n },\n },\n }),\n transformResponse: (response: GetFolder.Response) =>\n response.data as unknown as FolderWithCounts,\n providesTags: (_result, _error, { id }) => [{ type: 'Folder', id }],\n }),\n }),\n});\n\nexport const { useCreateFolderMutation, useGetFoldersQuery, useGetFolderQuery } = foldersApi;\n"],"names":["foldersApi","uploadApi","injectEndpoints","endpoints","builder","getFolders","query","params","parentId","queryParams","$and","parent","id","$null","url","method","config","transformResponse","response","data","providesTags","results","map","type","createFolder","mutation","body","invalidatesTags","getFolder","populate","children","count","files","_result","_error","useCreateFolderMutation","useGetFoldersQuery","useGetFolderQuery"],"mappings":"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"}
1
+ {"version":3,"file":"folders.mjs","sources":["../../../../admin/src/future/services/folders.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type {\n Folder,\n CreateFolders,\n GetFolder,\n GetFolders,\n} from '../../../../shared/contracts/folders';\n\nexport type FolderWithCounts = Omit<Folder, 'children' | 'files'> & {\n children?: { count: number };\n files?: { count: number };\n};\n\ninterface GetFoldersParams {\n parentId?: number | null;\n}\n\nconst foldersApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getFolders: builder.query<Folder[], GetFoldersParams | void>({\n query: (params = {}) => {\n const { parentId } = params as GetFoldersParams;\n\n const queryParams: Record<string, unknown> = {};\n\n if (parentId != null) {\n queryParams['filters'] = {\n $and: [{ parent: { id: parentId } }],\n };\n } else {\n queryParams['filters'] = {\n $and: [{ parent: { id: { $null: true } } }],\n };\n }\n\n return {\n url: '/upload/folders',\n method: 'GET',\n config: { params: queryParams },\n };\n },\n transformResponse: (response: GetFolders.Response['data']) =>\n // TODO dont want this cast\n (response as any).data,\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder', id: 'LIST' },\n ];\n }\n return [{ type: 'Folder', id: 'LIST' }];\n },\n }),\n createFolder: builder.mutation<CreateFolders.Response['data'], CreateFolders.Request['body']>({\n query: (body) => ({\n url: '/upload/folders',\n method: 'POST',\n data: body,\n }),\n transformResponse: (response: CreateFolders.Response) => response.data,\n invalidatesTags: [{ type: 'Folder', id: 'LIST' }],\n }),\n /**\n * Flat list of every folder, used to populate the \"Location\" select in the\n * asset details drawer. No parent filter — we want the entire tree in one\n * query so the select can render any destination folder.\n */\n getAllFolders: builder.query<Folder[], void>({\n query: () => ({\n url: '/upload/folders',\n method: 'GET',\n }),\n transformResponse: (response: GetFolders.Response['data']) =>\n ((response as any)?.data ?? response ?? []) as Folder[],\n providesTags: (results) => {\n if (results) {\n return [\n ...results.map(({ id }) => ({ type: 'Folder' as const, id })),\n { type: 'Folder' as const, id: 'LIST' },\n ];\n }\n return [{ type: 'Folder' as const, id: 'LIST' }];\n },\n }),\n getFolder: builder.query<FolderWithCounts, { id: number }>({\n query: ({ id }) => ({\n url: `/upload/folders/${id}`,\n method: 'GET',\n config: {\n params: {\n populate: {\n parent: {\n populate: {\n parent: '*',\n },\n },\n children: { count: true },\n files: { count: true },\n },\n },\n },\n }),\n transformResponse: (response: GetFolder.Response) =>\n response.data as unknown as FolderWithCounts,\n providesTags: (_result, _error, { id }) => [{ type: 'Folder', id }],\n }),\n }),\n});\n\nexport const {\n useCreateFolderMutation,\n useGetFoldersQuery,\n useGetFolderQuery,\n useGetAllFoldersQuery,\n} = foldersApi;\n"],"names":["foldersApi","uploadApi","injectEndpoints","endpoints","builder","getFolders","query","params","parentId","queryParams","$and","parent","id","$null","url","method","config","transformResponse","response","data","providesTags","results","map","type","createFolder","mutation","body","invalidatesTags","getAllFolders","getFolder","populate","children","count","files","_result","_error","useCreateFolderMutation","useGetFoldersQuery","useGetFolderQuery","useGetAllFoldersQuery"],"mappings":";;AAkBA,MAAMA,UAAAA,GAAaC,SAAAA,CAAUC,eAAe,CAAC;IAC3CC,SAAAA,EAAW,CAACC,WAAa;YACvBC,UAAAA,EAAYD,OAAAA,CAAQE,KAAK,CAAoC;gBAC3DA,KAAAA,EAAO,CAACC,MAAAA,GAAS,EAAE,GAAA;oBACjB,MAAM,EAAEC,QAAQ,EAAE,GAAGD,MAAAA;AAErB,oBAAA,MAAME,cAAuC,EAAC;AAE9C,oBAAA,IAAID,YAAY,IAAA,EAAM;wBACpBC,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEC,MAAAA,EAAQ;wCAAEC,EAAAA,EAAIJ;AAAS;AAAE;AAAE;AACtC,yBAAA;oBACF,CAAA,MAAO;wBACLC,WAAW,CAAC,UAAU,GAAG;4BACvBC,IAAAA,EAAM;AAAC,gCAAA;oCAAEC,MAAAA,EAAQ;wCAAEC,EAAAA,EAAI;4CAAEC,KAAAA,EAAO;AAAK;AAAE;AAAE;AAAE;AAC7C,yBAAA;AACF,oBAAA;oBAEA,OAAO;wBACLC,GAAAA,EAAK,iBAAA;wBACLC,MAAAA,EAAQ,KAAA;wBACRC,MAAAA,EAAQ;4BAAET,MAAAA,EAAQE;AAAY;AAChC,qBAAA;AACF,gBAAA,CAAA;gBACAQ,iBAAAA,EAAmB,CAACC,QAAAA;AAEjBA,oBAAAA,QAAAA,CAAiBC,IAAI;AACxBC,gBAAAA,YAAAA,EAAc,CAACC,OAAAA,GAAAA;AACb,oBAAA,IAAIA,OAAAA,EAAS;wBACX,OAAO;AACFA,4BAAAA,GAAAA,OAAAA,CAAQC,GAAG,CAAC,CAAC,EAAEV,EAAE,EAAE,IAAM;oCAAEW,IAAAA,EAAM,QAAA;AAAmBX,oCAAAA;iCAAG,CAAA,CAAA;AAC1D,4BAAA;gCAAEW,IAAAA,EAAM,QAAA;gCAAUX,EAAAA,EAAI;AAAO;AAC9B,yBAAA;AACH,oBAAA;oBACA,OAAO;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,QAAA;4BAAUX,EAAAA,EAAI;AAAO;AAAE,qBAAA;AACzC,gBAAA;AACF,aAAA,CAAA;YACAY,YAAAA,EAAcpB,OAAAA,CAAQqB,QAAQ,CAAgE;gBAC5FnB,KAAAA,EAAO,CAACoB,QAAU;wBAChBZ,GAAAA,EAAK,iBAAA;wBACLC,MAAAA,EAAQ,MAAA;wBACRI,IAAAA,EAAMO;qBACR,CAAA;gBACAT,iBAAAA,EAAmB,CAACC,QAAAA,GAAqCA,QAAAA,CAASC,IAAI;gBACtEQ,eAAAA,EAAiB;AAAC,oBAAA;wBAAEJ,IAAAA,EAAM,QAAA;wBAAUX,EAAAA,EAAI;AAAO;AAAE;AACnD,aAAA,CAAA;AACA;;;;QAKAgB,aAAAA,EAAexB,OAAAA,CAAQE,KAAK,CAAiB;AAC3CA,gBAAAA,KAAAA,EAAO,KAAO;wBACZQ,GAAAA,EAAK,iBAAA;wBACLC,MAAAA,EAAQ;qBACV,CAAA;AACAE,gBAAAA,iBAAAA,EAAmB,CAACC,QAAAA,GAChBA,QAAAA,EAAkBC,IAAAA,IAAQD,YAAY,EAAE;AAC5CE,gBAAAA,YAAAA,EAAc,CAACC,OAAAA,GAAAA;AACb,oBAAA,IAAIA,OAAAA,EAAS;wBACX,OAAO;AACFA,4BAAAA,GAAAA,OAAAA,CAAQC,GAAG,CAAC,CAAC,EAAEV,EAAE,EAAE,IAAM;oCAAEW,IAAAA,EAAM,QAAA;AAAmBX,oCAAAA;iCAAG,CAAA,CAAA;AAC1D,4BAAA;gCAAEW,IAAAA,EAAM,QAAA;gCAAmBX,EAAAA,EAAI;AAAO;AACvC,yBAAA;AACH,oBAAA;oBACA,OAAO;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,QAAA;4BAAmBX,EAAAA,EAAI;AAAO;AAAE,qBAAA;AAClD,gBAAA;AACF,aAAA,CAAA;YACAiB,SAAAA,EAAWzB,OAAAA,CAAQE,KAAK,CAAmC;AACzDA,gBAAAA,KAAAA,EAAO,CAAC,EAAEM,EAAE,EAAE,IAAM;wBAClBE,GAAAA,EAAK,CAAC,gBAAgB,EAAEF,EAAAA,CAAAA,CAAI;wBAC5BG,MAAAA,EAAQ,KAAA;wBACRC,MAAAA,EAAQ;4BACNT,MAAAA,EAAQ;gCACNuB,QAAAA,EAAU;oCACRnB,MAAAA,EAAQ;wCACNmB,QAAAA,EAAU;4CACRnB,MAAAA,EAAQ;AACV;AACF,qCAAA;oCACAoB,QAAAA,EAAU;wCAAEC,KAAAA,EAAO;AAAK,qCAAA;oCACxBC,KAAAA,EAAO;wCAAED,KAAAA,EAAO;AAAK;AACvB;AACF;AACF;qBACF,CAAA;gBACAf,iBAAAA,EAAmB,CAACC,QAAAA,GAClBA,QAAAA,CAASC,IAAI;AACfC,gBAAAA,YAAAA,EAAc,CAACc,OAAAA,EAASC,MAAAA,EAAQ,EAAEvB,EAAE,EAAE,GAAK;AAAC,wBAAA;4BAAEW,IAAAA,EAAM,QAAA;AAAUX,4BAAAA;AAAG;AAAE;AACrE,aAAA;SACF;AACF,CAAA,CAAA;AAEO,MAAM,EACXwB,uBAAuB,EACvBC,kBAAkB,EAClBC,iBAAiB,EACjBC,qBAAqB,EACtB,GAAGvC;;;;"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var api = require('./api.js');
4
+
5
+ const settingsApi = api.uploadApi.injectEndpoints({
6
+ endpoints: (builder)=>({
7
+ getSettings: builder.query({
8
+ query: ()=>({
9
+ url: '/upload/settings',
10
+ method: 'GET'
11
+ })
12
+ })
13
+ })
14
+ });
15
+ const { useGetSettingsQuery } = settingsApi;
16
+
17
+ exports.useGetSettingsQuery = useGetSettingsQuery;
18
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sources":["../../../../admin/src/future/services/settings.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type { GetSettings } from '../../../../shared/contracts/settings';\n\nconst settingsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getSettings: builder.query<GetSettings.Response['data'], void>({\n query: () => ({\n url: '/upload/settings',\n method: 'GET',\n }),\n }),\n }),\n});\n\nconst { useGetSettingsQuery } = settingsApi;\n\nexport { useGetSettingsQuery };\n"],"names":["settingsApi","uploadApi","injectEndpoints","endpoints","builder","getSettings","query","url","method","useGetSettingsQuery"],"mappings":";;;;AAIA,MAAMA,WAAAA,GAAcC,aAAAA,CAAUC,eAAe,CAAC;IAC5CC,SAAAA,EAAW,CAACC,WAAa;YACvBC,WAAAA,EAAaD,OAAAA,CAAQE,KAAK,CAAqC;AAC7DA,gBAAAA,KAAAA,EAAO,KAAO;wBACZC,GAAAA,EAAK,kBAAA;wBACLC,MAAAA,EAAQ;qBACV;AACF,aAAA;SACF;AACF,CAAA,CAAA;AAEA,MAAM,EAAEC,mBAAmB,EAAE,GAAGT;;;;"}
@@ -0,0 +1,16 @@
1
+ import { uploadApi } from './api.mjs';
2
+
3
+ const settingsApi = uploadApi.injectEndpoints({
4
+ endpoints: (builder)=>({
5
+ getSettings: builder.query({
6
+ query: ()=>({
7
+ url: '/upload/settings',
8
+ method: 'GET'
9
+ })
10
+ })
11
+ })
12
+ });
13
+ const { useGetSettingsQuery } = settingsApi;
14
+
15
+ export { useGetSettingsQuery };
16
+ //# sourceMappingURL=settings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.mjs","sources":["../../../../admin/src/future/services/settings.ts"],"sourcesContent":["import { uploadApi } from './api';\n\nimport type { GetSettings } from '../../../../shared/contracts/settings';\n\nconst settingsApi = uploadApi.injectEndpoints({\n endpoints: (builder) => ({\n getSettings: builder.query<GetSettings.Response['data'], void>({\n query: () => ({\n url: '/upload/settings',\n method: 'GET',\n }),\n }),\n }),\n});\n\nconst { useGetSettingsQuery } = settingsApi;\n\nexport { useGetSettingsQuery };\n"],"names":["settingsApi","uploadApi","injectEndpoints","endpoints","builder","getSettings","query","url","method","useGetSettingsQuery"],"mappings":";;AAIA,MAAMA,WAAAA,GAAcC,SAAAA,CAAUC,eAAe,CAAC;IAC5CC,SAAAA,EAAW,CAACC,WAAa;YACvBC,WAAAA,EAAaD,OAAAA,CAAQE,KAAK,CAAqC;AAC7DA,gBAAAA,KAAAA,EAAO,KAAO;wBACZC,GAAAA,EAAK,kBAAA;wBACLC,MAAAA,EAAQ;qBACV;AACF,aAAA;SACF;AACF,CAAA,CAAA;AAEA,MAAM,EAAEC,mBAAmB,EAAE,GAAGT;;;;"}
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Thrown when an upload is aborted via its `AbortSignal`.
5
+ * Distinct from {@link UploadFileError} so callers can tell cancellation apart
6
+ * from a genuine failure.
7
+ */ class UploadAbortedError extends Error {
8
+ constructor(message = 'Upload aborted'){
9
+ super(message);
10
+ this.name = 'UploadAbortedError';
11
+ }
12
+ }
13
+ /**
14
+ * Thrown when an upload fails (non-2xx response, network error, or unparseable body).
15
+ */ class UploadFileError extends Error {
16
+ constructor(message, status){
17
+ super(message);
18
+ this.name = 'UploadFileError';
19
+ this.status = status;
20
+ }
21
+ }
22
+ /**
23
+ * Uploads a single file via `XMLHttpRequest`, exposing real byte-level upload
24
+ * progress through {@link XMLHttpRequest.upload}'s `progress` event.
25
+ *
26
+ * This is the only place raw XHR lives. `fetch()` is intentionally avoided here
27
+ * because it does not surface upload progress.
28
+ *
29
+ * @param url - The full endpoint URL to POST to.
30
+ * @param token - Admin auth token; the `Authorization` header is only set when present.
31
+ * @param formData - Prebuilt multipart body containing the single file and its `fileInfo`.
32
+ * @param signal - Aborts the in-flight request when triggered.
33
+ * @param onProgress - Called with `(loaded, total)` bytes as the upload progresses.
34
+ * @returns The parsed, signed `File` on a 2xx response.
35
+ * @throws {UploadAbortedError} When the signal aborts.
36
+ * @throws {UploadFileError} On a non-2xx response or network error.
37
+ */ const uploadFileViaXHR = (url, token, formData, signal, onProgress)=>{
38
+ return new Promise((resolve, reject)=>{
39
+ if (signal.aborted) {
40
+ reject(new UploadAbortedError());
41
+ return;
42
+ }
43
+ const xhr = new XMLHttpRequest();
44
+ xhr.open('POST', url);
45
+ if (token) {
46
+ xhr.setRequestHeader('Authorization', `Bearer ${token}`);
47
+ }
48
+ const handleAbort = ()=>xhr.abort();
49
+ signal.addEventListener('abort', handleAbort);
50
+ const cleanup = ()=>signal.removeEventListener('abort', handleAbort);
51
+ if (onProgress) {
52
+ xhr.upload.onprogress = (event)=>{
53
+ if (event.lengthComputable) {
54
+ onProgress(event.loaded, event.total);
55
+ }
56
+ };
57
+ }
58
+ xhr.onload = ()=>{
59
+ cleanup();
60
+ if (xhr.status >= 200 && xhr.status < 300) {
61
+ try {
62
+ resolve(JSON.parse(xhr.responseText));
63
+ } catch {
64
+ reject(new UploadFileError('Failed to parse upload response'));
65
+ }
66
+ return;
67
+ }
68
+ let message = `Upload failed with status ${xhr.status}`;
69
+ try {
70
+ const parsed = JSON.parse(xhr.responseText);
71
+ message = parsed?.error?.message || parsed?.message || message;
72
+ } catch {
73
+ // Keep the default status-based message.
74
+ }
75
+ reject(new UploadFileError(message, xhr.status));
76
+ };
77
+ xhr.onerror = ()=>{
78
+ cleanup();
79
+ reject(new UploadFileError('Network error occurred'));
80
+ };
81
+ xhr.onabort = ()=>{
82
+ cleanup();
83
+ reject(new UploadAbortedError());
84
+ };
85
+ xhr.send(formData);
86
+ });
87
+ };
88
+
89
+ exports.UploadAbortedError = UploadAbortedError;
90
+ exports.UploadFileError = UploadFileError;
91
+ exports.uploadFileViaXHR = uploadFileViaXHR;
92
+ //# sourceMappingURL=uploadFileViaXHR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadFileViaXHR.js","sources":["../../../../admin/src/future/services/uploadFileViaXHR.ts"],"sourcesContent":["import type { File } from '../../../../shared/contracts/files';\n\n/**\n * Thrown when an upload is aborted via its `AbortSignal`.\n * Distinct from {@link UploadFileError} so callers can tell cancellation apart\n * from a genuine failure.\n */\nexport class UploadAbortedError extends Error {\n constructor(message = 'Upload aborted') {\n super(message);\n this.name = 'UploadAbortedError';\n }\n}\n\n/**\n * Thrown when an upload fails (non-2xx response, network error, or unparseable body).\n */\nexport class UploadFileError extends Error {\n status?: number;\n\n constructor(message: string, status?: number) {\n super(message);\n this.name = 'UploadFileError';\n this.status = status;\n }\n}\n\nexport type UploadProgressCallback = (bytes: number, total: number) => void;\n\n/**\n * Uploads a single file via `XMLHttpRequest`, exposing real byte-level upload\n * progress through {@link XMLHttpRequest.upload}'s `progress` event.\n *\n * This is the only place raw XHR lives. `fetch()` is intentionally avoided here\n * because it does not surface upload progress.\n *\n * @param url - The full endpoint URL to POST to.\n * @param token - Admin auth token; the `Authorization` header is only set when present.\n * @param formData - Prebuilt multipart body containing the single file and its `fileInfo`.\n * @param signal - Aborts the in-flight request when triggered.\n * @param onProgress - Called with `(loaded, total)` bytes as the upload progresses.\n * @returns The parsed, signed `File` on a 2xx response.\n * @throws {UploadAbortedError} When the signal aborts.\n * @throws {UploadFileError} On a non-2xx response or network error.\n */\nexport const uploadFileViaXHR = (\n url: string,\n token: string | null | undefined,\n formData: FormData,\n signal: AbortSignal,\n onProgress?: UploadProgressCallback\n): Promise<File> => {\n return new Promise<File>((resolve, reject) => {\n if (signal.aborted) {\n reject(new UploadAbortedError());\n return;\n }\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', url);\n\n if (token) {\n xhr.setRequestHeader('Authorization', `Bearer ${token}`);\n }\n\n const handleAbort = () => xhr.abort();\n signal.addEventListener('abort', handleAbort);\n\n const cleanup = () => signal.removeEventListener('abort', handleAbort);\n\n if (onProgress) {\n xhr.upload.onprogress = (event: ProgressEvent) => {\n if (event.lengthComputable) {\n onProgress(event.loaded, event.total);\n }\n };\n }\n\n xhr.onload = () => {\n cleanup();\n\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText) as File);\n } catch {\n reject(new UploadFileError('Failed to parse upload response'));\n }\n return;\n }\n\n let message = `Upload failed with status ${xhr.status}`;\n try {\n const parsed = JSON.parse(xhr.responseText);\n message = parsed?.error?.message || parsed?.message || message;\n } catch {\n // Keep the default status-based message.\n }\n reject(new UploadFileError(message, xhr.status));\n };\n\n xhr.onerror = () => {\n cleanup();\n reject(new UploadFileError('Network error occurred'));\n };\n\n xhr.onabort = () => {\n cleanup();\n reject(new UploadAbortedError());\n };\n\n xhr.send(formData);\n });\n};\n"],"names":["UploadAbortedError","Error","message","name","UploadFileError","status","uploadFileViaXHR","url","token","formData","signal","onProgress","Promise","resolve","reject","aborted","xhr","XMLHttpRequest","open","setRequestHeader","handleAbort","abort","addEventListener","cleanup","removeEventListener","upload","onprogress","event","lengthComputable","loaded","total","onload","JSON","parse","responseText","parsed","error","onerror","onabort","send"],"mappings":"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"}