@strapi/upload 5.53.0 → 5.54.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.
- package/dist/admin/future/components/UploadProgressDialog.js +9 -8
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +9 -8
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.js +0 -2
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +0 -2
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +7 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +7 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +4 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +4 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -1
- package/dist/admin/future/services/api.js +17 -0
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +18 -1
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +31 -22
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +31 -22
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/index.js +11 -10
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +11 -10
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/future/store/uploadProgress.d.ts +14 -20
- package/dist/admin/translations/en.json.js +0 -3
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +0 -3
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/bootstrap.js +11 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +11 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +31 -1
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +31 -1
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/controllers/utils/find-entity-and-check-permissions.js +15 -4
- package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
- package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs +15 -4
- package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs.map +1 -1
- package/dist/server/controllers/utils/folders.js +1 -1
- package/dist/server/controllers/utils/folders.js.map +1 -1
- package/dist/server/controllers/utils/folders.mjs +1 -1
- package/dist/server/controllers/utils/folders.mjs.map +1 -1
- package/dist/server/mcp/ambient-instance.js +46 -0
- package/dist/server/mcp/ambient-instance.js.map +1 -0
- package/dist/server/mcp/ambient-instance.mjs +43 -0
- package/dist/server/mcp/ambient-instance.mjs.map +1 -0
- package/dist/server/mcp/handlers/constants.js +60 -0
- package/dist/server/mcp/handlers/constants.js.map +1 -0
- package/dist/server/mcp/handlers/constants.mjs +45 -0
- package/dist/server/mcp/handlers/constants.mjs.map +1 -0
- package/dist/server/mcp/handlers/folder-handlers.js +308 -0
- package/dist/server/mcp/handlers/folder-handlers.js.map +1 -0
- package/dist/server/mcp/handlers/folder-handlers.mjs +303 -0
- package/dist/server/mcp/handlers/folder-handlers.mjs.map +1 -0
- package/dist/server/mcp/handlers/read-handlers.js +134 -0
- package/dist/server/mcp/handlers/read-handlers.js.map +1 -0
- package/dist/server/mcp/handlers/read-handlers.mjs +130 -0
- package/dist/server/mcp/handlers/read-handlers.mjs.map +1 -0
- package/dist/server/mcp/handlers/write-handlers.js +315 -0
- package/dist/server/mcp/handlers/write-handlers.js.map +1 -0
- package/dist/server/mcp/handlers/write-handlers.mjs +311 -0
- package/dist/server/mcp/handlers/write-handlers.mjs.map +1 -0
- package/dist/server/mcp/permissions.js +36 -0
- package/dist/server/mcp/permissions.js.map +1 -0
- package/dist/server/mcp/permissions.mjs +33 -0
- package/dist/server/mcp/permissions.mjs.map +1 -0
- package/dist/server/mcp/register-upload-mcp-tools.js +235 -0
- package/dist/server/mcp/register-upload-mcp-tools.js.map +1 -0
- package/dist/server/mcp/register-upload-mcp-tools.mjs +232 -0
- package/dist/server/mcp/register-upload-mcp-tools.mjs.map +1 -0
- package/dist/server/mcp/sanitizers/sanitize-media.js +97 -0
- package/dist/server/mcp/sanitizers/sanitize-media.js.map +1 -0
- package/dist/server/mcp/sanitizers/sanitize-media.mjs +93 -0
- package/dist/server/mcp/sanitizers/sanitize-media.mjs.map +1 -0
- package/dist/server/mcp/schemas/input-schemas.js +206 -0
- package/dist/server/mcp/schemas/input-schemas.js.map +1 -0
- package/dist/server/mcp/schemas/input-schemas.mjs +190 -0
- package/dist/server/mcp/schemas/input-schemas.mjs.map +1 -0
- package/dist/server/mcp/schemas/output-schemas.js +158 -0
- package/dist/server/mcp/schemas/output-schemas.js.map +1 -0
- package/dist/server/mcp/schemas/output-schemas.mjs +142 -0
- package/dist/server/mcp/schemas/output-schemas.mjs.map +1 -0
- package/dist/server/mcp/utils.js +14 -0
- package/dist/server/mcp/utils.js.map +1 -0
- package/dist/server/mcp/utils.mjs +12 -0
- package/dist/server/mcp/utils.mjs.map +1 -0
- package/dist/server/media-library-default-notice.js +42 -0
- package/dist/server/media-library-default-notice.js.map +1 -0
- package/dist/server/media-library-default-notice.mjs +40 -0
- package/dist/server/media-library-default-notice.mjs.map +1 -0
- package/dist/server/register.js +5 -0
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +5 -0
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/upload.js +14 -2
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +14 -2
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +1 -0
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts +14 -1
- package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/folders.d.ts +2 -1
- package/dist/server/src/controllers/utils/folders.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +8 -2
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts +65 -0
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/constants.d.ts +48 -0
- package/dist/server/src/mcp/handlers/constants.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/folder-handlers.d.ts +49 -0
- package/dist/server/src/mcp/handlers/folder-handlers.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/index.d.ts +5 -0
- package/dist/server/src/mcp/handlers/index.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/read-handlers.d.ts +35 -0
- package/dist/server/src/mcp/handlers/read-handlers.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/write-handlers.d.ts +66 -0
- package/dist/server/src/mcp/handlers/write-handlers.d.ts.map +1 -0
- package/dist/server/src/mcp/index.d.ts +3 -0
- package/dist/server/src/mcp/index.d.ts.map +1 -0
- package/dist/server/src/mcp/permissions.d.ts +22 -0
- package/dist/server/src/mcp/permissions.d.ts.map +1 -0
- package/dist/server/src/mcp/register-upload-mcp-tools.d.ts +29 -0
- package/dist/server/src/mcp/register-upload-mcp-tools.d.ts.map +1 -0
- package/dist/server/src/mcp/sanitizers/sanitize-media.d.ts +63 -0
- package/dist/server/src/mcp/sanitizers/sanitize-media.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/index.d.ts +3 -0
- package/dist/server/src/mcp/schemas/index.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/input-schemas.d.ts +148 -0
- package/dist/server/src/mcp/schemas/input-schemas.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/output-schemas.d.ts +276 -0
- package/dist/server/src/mcp/schemas/output-schemas.d.ts.map +1 -0
- package/dist/server/src/mcp/types.d.ts +19 -0
- package/dist/server/src/mcp/types.d.ts.map +1 -0
- package/dist/server/src/mcp/utils.d.ts +4 -0
- package/dist/server/src/mcp/utils.d.ts.map +1 -0
- package/dist/server/src/media-library-default-notice.d.ts +19 -0
- package/dist/server/src/media-library-default-notice.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/folder.d.ts +6 -2
- package/dist/server/src/services/folder.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +8 -2
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts +8 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +2 -2
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -1
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/utils/index.js +2 -2
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs +2 -2
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/contracts/files.d.ts +22 -0
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/package.json +7 -6
- package/dist/admin/future/components/BetaNotice.js +0 -72
- package/dist/admin/future/components/BetaNotice.js.map +0 -1
- package/dist/admin/future/components/BetaNotice.mjs +0 -70
- package/dist/admin/future/components/BetaNotice.mjs.map +0 -1
- package/dist/admin/src/future/components/BetaNotice.d.ts +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadProgress.mjs","sources":["../../../../admin/src/future/store/uploadProgress.ts"],"sourcesContent":["import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit';\n\nimport type { File } from '../../../../shared/contracts/files';\n\nexport interface FileUploadError {\n name: string;\n message: string;\n}\n\nexport type FileProgressStatus = 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n\n/**\n * AI metadata generation phase for a single row, tracked independently from the\n * upload status: a metadata failure never turns a successful upload into an error.\n * `undefined` means the row has no metadata phase at all, i.e. AI metadata is\n * disabled — non-images do get a phase and come back `skipped` from the server.\n */\nexport type FileMetadataStatus = 'generating' | 'generated' | 'skipped' | 'failed';\n\nexport type FileMetadataResultStatus = Exclude<FileMetadataStatus, 'generating'>;\n\nexport interface FileProgress {\n name: string;\n index: number;\n status: FileProgressStatus;\n size: number;\n uploadedBytes: number;\n file?: File;\n /** When the server confirmed the upload. Set with the row's asset. */\n completedAt?: number;\n error?: string;\n metadataStatus?: FileMetadataStatus;\n}\n\nexport interface UploadProgressState {\n isVisible: boolean;\n isMinimized: boolean;\n totalFiles: number;\n files: FileProgress[];\n errors: FileUploadError[];\n uploadId: number;\n /**\n * Whether this batch reports transferred bytes at all. The direct-file flow streams\n * byte counts from XHR; the URL flow leaves the fetch to the server and gets none back\n * so its byte-weighted aggregate is stuck at 0%.\n */\n reportsByteProgress: boolean;\n}\n\nexport interface RootState {\n uploadProgress: UploadProgressState;\n}\n\nconst initialState: UploadProgressState = {\n isVisible: false,\n isMinimized: false,\n totalFiles: 0,\n files: [],\n errors: [],\n uploadId: 0,\n reportsByteProgress: false,\n};\n\nconst uploadProgressSlice = createSlice({\n name: 'uploadProgress',\n initialState,\n reducers: {\n openUploadProgress(\n state,\n action: PayloadAction<{\n totalFiles: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n state.isVisible = true;\n state.isMinimized = false;\n\n // Create pending files for upload\n const pendingFiles: FileProgress[] = action.payload.fileNames.map((name, index) => ({\n name,\n index,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[index] ?? 0,\n uploadedBytes: 0,\n }));\n\n state.files = pendingFiles;\n state.totalFiles = action.payload.totalFiles;\n state.errors = [];\n state.uploadId += 1;\n // Known sizes == the direct-file flow == the flow that streams bytes.\n state.reportsByteProgress = action.payload.fileSizes !== undefined;\n },\n /**\n * Rows for a second drop, joined to the batch already uploading. Indices\n * continue from the current length so the earlier drop's in-flight uploads\n * keep addressing their own rows.\n */\n appendUploadFiles(\n state,\n action: PayloadAction<{\n uploadId: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n if (action.payload.uploadId !== state.uploadId) {\n return;\n }\n\n const offset = state.files.length;\n\n state.files.push(\n ...action.payload.fileNames.map((name, i) => ({\n name,\n index: offset + i,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[i] ?? 0,\n uploadedBytes: 0,\n }))\n );\n\n state.totalFiles += action.payload.fileNames.length;\n // The dialog may have been dismissed while the first drop was running.\n state.isVisible = true;\n state.isMinimized = false;\n },\n setFileUploading(\n state,\n action: PayloadAction<{ name: string; index: number; size: number; uploadId: number }>\n ) {\n const { index, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'uploading';\n state.files[index].size = size;\n }\n },\n setFileProgress(\n state,\n action: PayloadAction<{ index: number; bytes: number; uploadId: number }>\n ) {\n const { index, bytes, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file) {\n // Clamp to the known file size so the aggregate can never exceed 100%.\n file.uploadedBytes = Math.min(bytes, file.size);\n }\n },\n setFileComplete(\n state,\n action: PayloadAction<{ index: number; file: File; uploadId: number; completedAt: number }>\n ) {\n const { index, file, uploadId, completedAt } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'complete';\n state.files[index].file = file;\n state.files[index].completedAt = completedAt;\n // Reflect completion in the aggregate even if the final progress event was throttled.\n state.files[index].uploadedBytes = state.files[index].size;\n }\n },\n setFileError(\n state,\n action: PayloadAction<{ index: number; name: string; message: string; uploadId: number }>\n ) {\n const { index, name, message, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'error';\n state.files[index].error = message;\n }\n state.errors = [...state.errors, { name, message }];\n },\n /**\n * Metadata generation started for a row.\n *\n * Metadata requests are fired-and-forgotten, so their callbacks can land after\n * a new batch has replaced `files` and reused the same row indices. Every\n * metadata payload therefore carries the `uploadId` it was fired for, and stale\n * ones are dropped instead of writing onto another batch's row.\n */\n setFileMetadataGenerating(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = 'generating';\n }\n },\n /**\n * Terminal metadata outcome for a row. Never touches `status`/`error`/`errors`:\n * the upload itself already succeeded regardless of how generation went.\n */\n setFileMetadataResult(\n state,\n action: PayloadAction<{\n index: number;\n uploadId: number;\n status: FileMetadataResultStatus;\n }>\n ) {\n const { index, uploadId, status } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = status;\n }\n },\n addUploadErrors(state, action: PayloadAction<FileUploadError[]>) {\n state.errors = [...state.errors, ...action.payload];\n },\n closeUploadProgress(state) {\n state.isVisible = false;\n state.isMinimized = false;\n state.totalFiles = 0;\n state.files = [];\n state.errors = [];\n state.reportsByteProgress = false;\n },\n toggleMinimize(state) {\n state.isMinimized = !state.isMinimized;\n },\n cancelUpload(state) {\n // Mark all pending and uploading files as cancelled\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return { ...file, status: 'cancelled' as FileProgressStatus };\n }\n return file;\n });\n },\n setUploadFailed(state, action: PayloadAction<{ message: string }>) {\n // Mark all pending and uploading files as errored when a catastrophic failure occurs\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return {\n ...file,\n status: 'error' as FileProgressStatus,\n error: action.payload.message,\n };\n }\n return file;\n });\n state.errors = [...state.errors, { name: 'Upload Error', message: action.payload.message }];\n },\n retryCancelledFiles(state) {\n // Reset all cancelled files back to pending for retry\n state.files = state.files.map((file) => {\n if (file.status === 'cancelled') {\n return {\n ...file,\n status: 'pending' as FileProgressStatus,\n uploadedBytes: 0,\n // A retried row goes through the metadata phase again from scratch.\n metadataStatus: undefined,\n };\n }\n return file;\n });\n },\n },\n});\n\n/**\n * Assets whose own upload has already finished, newest batch only.\n *\n * The list behind the upload dialog uses these to show each asset the moment it\n * lands, instead of waiting for the batch mutation to invalidate the cache. Rows\n * only carry a `file` once the server has created it, so every entry here is a\n * real, persisted asset.\n */\nconst NO_FILES: FileProgress[] = [];\n\n/** An uploaded asset, with the moment the server confirmed it. */\nexport interface CompletedUpload {\n asset: File;\n completedAt: number;\n}\n\nexport const selectCompletedUploads = createSelector(\n // The plugin registers this slice in `register()`, so a host that has not\n // reached that point has no upload state — and therefore nothing to place.\n (state: Partial<RootState>) => state.uploadProgress?.files ?? NO_FILES,\n (files): CompletedUpload[] =>\n files.reduce<CompletedUpload[]>((completed, row) => {\n if (row.status === 'complete' && row.file && row.completedAt !== undefined) {\n completed.push({ asset: row.file, completedAt: row.completedAt });\n }\n\n return completed;\n }, [])\n);\n\n/**\n * Byte-weighted aggregate progress across the whole batch: `sum(uploadedBytes) / sum(size)`.\n *\n * Falls back to count-based progress (settled files / total files) when all sizes are\n * zero — e.g. URL-flow rows where the file size is unknown up front.\n */\nexport const selectAggregateProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number => {\n if (files.length === 0) return 0;\n\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n\n if (totalSize === 0) {\n const settled = files.filter(\n (f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled'\n ).length;\n return Math.round((settled / files.length) * 100);\n }\n\n const uploadedBytes = files.reduce((sum, f) => sum + f.uploadedBytes, 0);\n return Math.round((uploadedBytes / totalSize) * 100);\n }\n);\n\n/**\n * Whether to show byte-weighted `selectAggregateProgress` rather than count-based progress.\n * A batch that never reports bytes stays pinned at 0%, so the header falls back to\n * `selectCountBasedProgress`.\n *\n * Checks the rows too, not just the flag: an in-flight row reporting bytes proves the batch\n * can, so byte-weighting takes over once the URL flow starts emitting progress. Only\n * `uploading` rows count — completion backfills `uploadedBytes` to the file size, so letting\n * settled rows qualify would switch a multi-URL batch to byte-weighting mid-upload over only\n * the sizes known so far (transiently 100% after the first file).\n */\nexport const selectReportsByteProgress = createSelector(\n (state: RootState) => state.uploadProgress.reportsByteProgress,\n (state: RootState) => state.uploadProgress.files,\n (reportsByteProgress, files): boolean =>\n reportsByteProgress || files.some((f) => f.status === 'uploading' && f.uploadedBytes > 0)\n);\n\n/**\n * Count-based progress (settled / total rows) for a batch that reports no transferred bytes\n * (the URL flow). Used by the header whenever `selectReportsByteProgress` is false.\n *\n * Never byte-weights, so a multi-URL batch climbs 33 → 67 → 100 as each file lands instead\n * of jumping to a transient 100% after the first.\n *\n * Returns `null` until a row settles — 0% is the frozen signal this flow exists to remove\n * (a lone URL upload would otherwise read \"Uploading 1 item (0%)\" throughout), so the header\n * stays indeterminate until there's real progress.\n */\nexport const selectCountBasedProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const settled = files.filter(\n (f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled'\n ).length;\n\n if (settled === 0) return null;\n\n return Math.round((settled / files.length) * 100);\n }\n);\n\n/**\n * Count-based metadata progress across the whole batch: `settled / expected`.\n *\n * Count-based rather than byte-weighted because the generation endpoint answers in one\n * go — there is no intermediate progress to weight.\n *\n * The denominator is every row *expected* to enter the phase, not just those that\n * already have. Generation is fired per file as each upload finishes, so counting only\n * started rows made the denominator grow mid-batch and the percentage jump backwards\n * (1/1 = 100%, then a second row starts and it drops to 1/2 = 50%), which flickered the\n * header subtitle on and off once per file.\n *\n * \"Expected\" is derived from upload outcome rather than from the AI-metadata flag:\n * - a row still uploading may yet enter the phase, so it counts toward the total;\n * - an errored or cancelled row never will, so it must not — otherwise a batch with\n * one failure could never reach 100%.\n *\n * Returns `null` when nothing has entered the phase and nothing is pending — i.e. AI\n * metadata is off, or the batch is done — so the header can hide the subtitle.\n */\nexport const selectMetadataProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n // Nothing has entered the phase yet: with no started row there is no evidence AI\n // metadata is even enabled, so stay silent rather than showing a premature 0%.\n if (started.length === 0) return null;\n\n // Rows whose upload is still in flight are counted in the denominator so the\n // percentage only ever climbs as the batch progresses.\n const pending = files.filter(\n (f) => f.metadataStatus === undefined && (f.status === 'pending' || f.status === 'uploading')\n ).length;\n\n const expected = started.length + pending;\n const settled = started.filter((f) => f.metadataStatus !== 'generating').length;\n\n return Math.round((settled / expected) * 100);\n }\n);\n\n/**\n * Whether the metadata phase is still ongoing for the batch as a whole.\n *\n * The header uses this — not `selectMetadataProgress === 100` — to decide when to drop\n * the subtitle. Two distinct reasons the phase can be unfinished:\n * - a row is generating right now;\n * - no row is generating this instant, but rows are still uploading and will enter the\n * phase when they finish.\n *\n * The second clause is what keeps the subtitle stable. Generation for file N typically\n * finishes before file N+1 finishes uploading, so a naive \"is anything generating?\"\n * check goes false between every pair of files and blinks the subtitle out and back in.\n */\nexport const selectIsGeneratingMetadata = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): boolean => {\n if (files.some((f) => f.metadataStatus === 'generating')) return true;\n\n // Only bridge the gap if some row has already entered the phase — otherwise a batch\n // with AI metadata disabled would report the phase as ongoing for its whole upload.\n const hasStarted = files.some((f) => f.metadataStatus !== undefined);\n\n return hasStarted && files.some((f) => f.status === 'pending' || f.status === 'uploading');\n }\n);\n\n/**\n * How many rows reached each terminal metadata outcome, for the header's completion\n * message. `null` while the phase is unfinished — or was never entered at all — so the\n * caller has a single check for \"there is no settled outcome to report yet\".\n *\n * Counts are reported separately rather than collapsed into one total because they are\n * not interchangeable: only `generated` rows actually had metadata written, so only that\n * count can be claimed as a success. A batch of non-images settles entirely on `skipped`,\n * where \"generated on 0 files\" would be worse than saying nothing.\n */\nexport const selectMetadataOutcome = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): { generated: number; skipped: number; failed: number } | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n if (started.length === 0) return null;\n\n // Mirrors `selectIsGeneratingMetadata`: the phase isn't over while a row is\n // generating, nor while a row is still uploading and has yet to enter it.\n const isOngoing =\n started.some((f) => f.metadataStatus === 'generating') ||\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\n if (isOngoing) return null;\n\n return {\n generated: started.filter((f) => f.metadataStatus === 'generated').length,\n skipped: started.filter((f) => f.metadataStatus === 'skipped').length,\n failed: started.filter((f) => f.metadataStatus === 'failed').length,\n };\n }\n);\n\nexport const {\n openUploadProgress,\n appendUploadFiles,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n addUploadErrors,\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n setUploadFailed,\n retryCancelledFiles,\n} = uploadProgressSlice.actions;\n\n/**\n * The merge/reset switch. Errored and cancelled rows count as settled, so a\n * batch that finished badly is still replaced by the next drop.\n */\nexport const isUploadInFlight = (files: ReadonlyArray<{ status: FileProgressStatus }>): boolean =>\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\nexport const uploadProgressReducer = uploadProgressSlice.reducer;\n"],"names":["initialState","isVisible","isMinimized","totalFiles","files","errors","uploadId","reportsByteProgress","uploadProgressSlice","createSlice","name","reducers","openUploadProgress","state","action","pendingFiles","payload","fileNames","map","index","status","size","fileSizes","uploadedBytes","undefined","appendUploadFiles","offset","length","push","i","setFileUploading","setFileProgress","bytes","file","Math","min","setFileComplete","completedAt","setFileError","message","error","setFileMetadataGenerating","metadataStatus","setFileMetadataResult","addUploadErrors","closeUploadProgress","toggleMinimize","cancelUpload","setUploadFailed","retryCancelledFiles","NO_FILES","selectCompletedUploads","createSelector","uploadProgress","reduce","completed","row","asset","selectAggregateProgress","totalSize","sum","f","settled","filter","round","selectReportsByteProgress","some","selectCountBasedProgress","selectMetadataProgress","started","pending","expected","selectIsGeneratingMetadata","hasStarted","selectMetadataOutcome","isOngoing","generated","skipped","failed","actions","isUploadInFlight","uploadProgressReducer","reducer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uploadProgress.mjs","sources":["../../../../admin/src/future/store/uploadProgress.ts"],"sourcesContent":["import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit';\n\nimport type { File } from '../../../../shared/contracts/files';\n\nexport interface FileUploadError {\n name: string;\n message: string;\n}\n\nexport type FileProgressStatus = 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n\n/**\n * AI metadata generation phase for a single row, tracked independently from the\n * upload status: a metadata failure never turns a successful upload into an error.\n * `undefined` means the row has no metadata phase at all, i.e. AI metadata is\n * disabled — non-images do get a phase and come back `skipped` from the server.\n */\nexport type FileMetadataStatus = 'generating' | 'generated' | 'skipped' | 'failed';\n\nexport type FileMetadataResultStatus = Exclude<FileMetadataStatus, 'generating'>;\n\nexport interface FileProgress {\n name: string;\n index: number;\n status: FileProgressStatus;\n size: number;\n uploadedBytes: number;\n file?: File;\n /** When the server confirmed the upload. Set with the row's asset. */\n completedAt?: number;\n error?: string;\n metadataStatus?: FileMetadataStatus;\n}\n\nexport interface UploadProgressState {\n isVisible: boolean;\n isMinimized: boolean;\n totalFiles: number;\n files: FileProgress[];\n errors: FileUploadError[];\n uploadId: number;\n /**\n * Whether every row's size was known when the batch opened (the direct-file flow), so\n * the byte-weighted aggregate is meaningful. The URL flow learns sizes one row at a time.\n */\n reportsByteProgress: boolean;\n}\n\nexport interface RootState {\n uploadProgress: UploadProgressState;\n}\n\nconst initialState: UploadProgressState = {\n isVisible: false,\n isMinimized: false,\n totalFiles: 0,\n files: [],\n errors: [],\n uploadId: 0,\n reportsByteProgress: false,\n};\n\nconst uploadProgressSlice = createSlice({\n name: 'uploadProgress',\n initialState,\n reducers: {\n openUploadProgress(\n state,\n action: PayloadAction<{\n totalFiles: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n state.isVisible = true;\n state.isMinimized = false;\n\n // Create pending files for upload\n const pendingFiles: FileProgress[] = action.payload.fileNames.map((name, index) => ({\n name,\n index,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[index] ?? 0,\n uploadedBytes: 0,\n }));\n\n state.files = pendingFiles;\n state.totalFiles = action.payload.totalFiles;\n state.errors = [];\n state.uploadId += 1;\n // Known sizes == the direct-file flow == the flow that streams bytes.\n state.reportsByteProgress = action.payload.fileSizes !== undefined;\n },\n /**\n * Rows for a second drop, joined to the batch already uploading. Indices\n * continue from the current length so the earlier drop's in-flight uploads\n * keep addressing their own rows.\n */\n appendUploadFiles(\n state,\n action: PayloadAction<{\n uploadId: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n if (action.payload.uploadId !== state.uploadId) {\n return;\n }\n\n const offset = state.files.length;\n\n state.files.push(\n ...action.payload.fileNames.map((name, i) => ({\n name,\n index: offset + i,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[i] ?? 0,\n uploadedBytes: 0,\n }))\n );\n\n state.totalFiles += action.payload.fileNames.length;\n // The dialog may have been dismissed while the first drop was running.\n state.isVisible = true;\n state.isMinimized = false;\n },\n setFileUploading(\n state,\n action: PayloadAction<{ name: string; index: number; size: number; uploadId: number }>\n ) {\n const { index, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'uploading';\n state.files[index].size = size;\n }\n },\n /**\n * `size` is optional and only sent by the URL flow, which learns the size from the\n * same server event that carries the first byte count — the row was created with\n * `size: 0`, and bytes clamped against a zero size would all read as zero. The\n * direct-file flow already knows the size up front and omits it.\n */\n setFileProgress(\n state,\n action: PayloadAction<{ index: number; bytes: number; uploadId: number; size?: number }>\n ) {\n const { index, bytes, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file) {\n if (size !== undefined && file.size === 0) {\n file.size = size;\n }\n // Clamp to the known file size so the aggregate can never exceed 100%.\n file.uploadedBytes = Math.min(bytes, file.size);\n }\n },\n setFileComplete(\n state,\n action: PayloadAction<{ index: number; file: File; uploadId: number; completedAt: number }>\n ) {\n const { index, file, uploadId, completedAt } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'complete';\n state.files[index].file = file;\n state.files[index].completedAt = completedAt;\n // Reflect completion in the aggregate even if the final progress event was throttled.\n state.files[index].uploadedBytes = state.files[index].size;\n }\n },\n setFileError(\n state,\n action: PayloadAction<{ index: number; name: string; message: string; uploadId: number }>\n ) {\n const { index, name, message, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'error';\n state.files[index].error = message;\n }\n state.errors = [...state.errors, { name, message }];\n },\n /**\n * Metadata generation started for a row.\n *\n * Metadata requests are fired-and-forgotten, so their callbacks can land after\n * a new batch has replaced `files` and reused the same row indices. Every\n * metadata payload therefore carries the `uploadId` it was fired for, and stale\n * ones are dropped instead of writing onto another batch's row.\n */\n setFileMetadataGenerating(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = 'generating';\n }\n },\n /**\n * Terminal metadata outcome for a row. Never touches `status`/`error`/`errors`:\n * the upload itself already succeeded regardless of how generation went.\n */\n setFileMetadataResult(\n state,\n action: PayloadAction<{\n index: number;\n uploadId: number;\n status: FileMetadataResultStatus;\n }>\n ) {\n const { index, uploadId, status } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = status;\n }\n },\n addUploadErrors(state, action: PayloadAction<FileUploadError[]>) {\n state.errors = [...state.errors, ...action.payload];\n },\n closeUploadProgress(state) {\n state.isVisible = false;\n state.isMinimized = false;\n state.totalFiles = 0;\n state.files = [];\n state.errors = [];\n state.reportsByteProgress = false;\n },\n toggleMinimize(state) {\n state.isMinimized = !state.isMinimized;\n },\n cancelUpload(state) {\n // Mark all pending and uploading files as cancelled\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return { ...file, status: 'cancelled' as FileProgressStatus };\n }\n return file;\n });\n },\n setUploadFailed(state, action: PayloadAction<{ message: string }>) {\n // Mark all pending and uploading files as errored when a catastrophic failure occurs\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return {\n ...file,\n status: 'error' as FileProgressStatus,\n error: action.payload.message,\n };\n }\n return file;\n });\n state.errors = [...state.errors, { name: 'Upload Error', message: action.payload.message }];\n },\n retryCancelledFiles(state) {\n // Reset all cancelled files back to pending for retry\n state.files = state.files.map((file) => {\n if (file.status === 'cancelled') {\n return {\n ...file,\n status: 'pending' as FileProgressStatus,\n uploadedBytes: 0,\n // A retried row goes through the metadata phase again from scratch.\n metadataStatus: undefined,\n };\n }\n return file;\n });\n },\n },\n});\n\n/**\n * Assets whose own upload has already finished, newest batch only.\n *\n * The list behind the upload dialog uses these to show each asset the moment it\n * lands, instead of waiting for the batch mutation to invalidate the cache. Rows\n * only carry a `file` once the server has created it, so every entry here is a\n * real, persisted asset.\n */\nconst NO_FILES: FileProgress[] = [];\n\n/** An uploaded asset, with the moment the server confirmed it. */\nexport interface CompletedUpload {\n asset: File;\n completedAt: number;\n}\n\nexport const selectCompletedUploads = createSelector(\n // The plugin registers this slice in `register()`, so a host that has not\n // reached that point has no upload state — and therefore nothing to place.\n (state: Partial<RootState>) => state.uploadProgress?.files ?? NO_FILES,\n (files): CompletedUpload[] =>\n files.reduce<CompletedUpload[]>((completed, row) => {\n if (row.status === 'complete' && row.file && row.completedAt !== undefined) {\n completed.push({ asset: row.file, completedAt: row.completedAt });\n }\n\n return completed;\n }, [])\n);\n\n/**\n * Byte-weighted aggregate progress across the whole batch: `sum(uploadedBytes) / sum(size)`.\n *\n * Falls back to count-based progress (settled files / total files) when all sizes are\n * zero — e.g. URL-flow rows where the file size is unknown up front.\n */\nexport const selectAggregateProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number => {\n if (files.length === 0) return 0;\n\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n\n if (totalSize === 0) {\n const settled = files.filter(\n (f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled'\n ).length;\n return Math.round((settled / files.length) * 100);\n }\n\n const uploadedBytes = files.reduce((sum, f) => sum + f.uploadedBytes, 0);\n return Math.round((uploadedBytes / totalSize) * 100);\n }\n);\n\n/**\n * Whether to show byte-weighted `selectAggregateProgress` rather than `selectCountBasedProgress`.\n *\n * Only the flag: byte-weighting needs every size up front. A URL batch learns sizes one row\n * at a time, so weighting over the sizes known so far makes the header jump backwards at\n * every file boundary.\n */\nexport const selectReportsByteProgress = createSelector(\n (state: RootState) => state.uploadProgress.reportsByteProgress,\n (reportsByteProgress): boolean => reportsByteProgress\n);\n\n/**\n * Row-weighted progress for a batch whose sizes are not known up front (the URL flow).\n * Each row is worth `1 / total`: settled rows count fully and an in-flight row contributes\n * `uploadedBytes / size` once it reports bytes, so a multi-URL batch climbs smoothly to\n * 33 → 67 → 100 and never moves backwards.\n *\n * Returns `null` until something has moved — 0% is the frozen signal this flow exists to\n * remove, so the header stays indeterminate until there's real progress.\n */\nexport const selectCountBasedProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const done = files.reduce((sum, f) => {\n if (f.status === 'complete' || f.status === 'error' || f.status === 'cancelled') {\n return sum + 1;\n }\n return f.size > 0 ? sum + Math.min(f.uploadedBytes / f.size, 1) : sum;\n }, 0);\n\n if (done === 0) {\n return null;\n }\n\n return Math.round((done / files.length) * 100);\n }\n);\n\n/**\n * Count-based metadata progress across the whole batch: `settled / expected`.\n *\n * Count-based rather than byte-weighted because the generation endpoint answers in one\n * go — there is no intermediate progress to weight.\n *\n * The denominator is every row *expected* to enter the phase, not just those that\n * already have. Generation is fired per file as each upload finishes, so counting only\n * started rows made the denominator grow mid-batch and the percentage jump backwards\n * (1/1 = 100%, then a second row starts and it drops to 1/2 = 50%), which flickered the\n * header subtitle on and off once per file.\n *\n * \"Expected\" is derived from upload outcome rather than from the AI-metadata flag:\n * - a row still uploading may yet enter the phase, so it counts toward the total;\n * - an errored or cancelled row never will, so it must not — otherwise a batch with\n * one failure could never reach 100%.\n *\n * Returns `null` when nothing has entered the phase and nothing is pending — i.e. AI\n * metadata is off, or the batch is done — so the header can hide the subtitle.\n */\nexport const selectMetadataProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n // Nothing has entered the phase yet: with no started row there is no evidence AI\n // metadata is even enabled, so stay silent rather than showing a premature 0%.\n if (started.length === 0) return null;\n\n // Rows whose upload is still in flight are counted in the denominator so the\n // percentage only ever climbs as the batch progresses.\n const pending = files.filter(\n (f) => f.metadataStatus === undefined && (f.status === 'pending' || f.status === 'uploading')\n ).length;\n\n const expected = started.length + pending;\n const settled = started.filter((f) => f.metadataStatus !== 'generating').length;\n\n return Math.round((settled / expected) * 100);\n }\n);\n\n/**\n * Whether the metadata phase is still ongoing for the batch as a whole.\n *\n * The header uses this — not `selectMetadataProgress === 100` — to decide when to drop\n * the subtitle. Two distinct reasons the phase can be unfinished:\n * - a row is generating right now;\n * - no row is generating this instant, but rows are still uploading and will enter the\n * phase when they finish.\n *\n * The second clause is what keeps the subtitle stable. Generation for file N typically\n * finishes before file N+1 finishes uploading, so a naive \"is anything generating?\"\n * check goes false between every pair of files and blinks the subtitle out and back in.\n */\nexport const selectIsGeneratingMetadata = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): boolean => {\n if (files.some((f) => f.metadataStatus === 'generating')) return true;\n\n // Only bridge the gap if some row has already entered the phase — otherwise a batch\n // with AI metadata disabled would report the phase as ongoing for its whole upload.\n const hasStarted = files.some((f) => f.metadataStatus !== undefined);\n\n return hasStarted && files.some((f) => f.status === 'pending' || f.status === 'uploading');\n }\n);\n\n/**\n * How many rows reached each terminal metadata outcome, for the header's completion\n * message. `null` while the phase is unfinished — or was never entered at all — so the\n * caller has a single check for \"there is no settled outcome to report yet\".\n *\n * Counts are reported separately rather than collapsed into one total because they are\n * not interchangeable: only `generated` rows actually had metadata written, so only that\n * count can be claimed as a success. A batch of non-images settles entirely on `skipped`,\n * where \"generated on 0 files\" would be worse than saying nothing.\n */\nexport const selectMetadataOutcome = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): { generated: number; skipped: number; failed: number } | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n if (started.length === 0) return null;\n\n // Mirrors `selectIsGeneratingMetadata`: the phase isn't over while a row is\n // generating, nor while a row is still uploading and has yet to enter it.\n const isOngoing =\n started.some((f) => f.metadataStatus === 'generating') ||\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\n if (isOngoing) return null;\n\n return {\n generated: started.filter((f) => f.metadataStatus === 'generated').length,\n skipped: started.filter((f) => f.metadataStatus === 'skipped').length,\n failed: started.filter((f) => f.metadataStatus === 'failed').length,\n };\n }\n);\n\nexport const {\n openUploadProgress,\n appendUploadFiles,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n addUploadErrors,\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n setUploadFailed,\n retryCancelledFiles,\n} = uploadProgressSlice.actions;\n\n/**\n * The merge/reset switch. Errored and cancelled rows count as settled, so a\n * batch that finished badly is still replaced by the next drop.\n */\nexport const isUploadInFlight = (files: ReadonlyArray<{ status: FileProgressStatus }>): boolean =>\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\nexport const uploadProgressReducer = uploadProgressSlice.reducer;\n"],"names":["initialState","isVisible","isMinimized","totalFiles","files","errors","uploadId","reportsByteProgress","uploadProgressSlice","createSlice","name","reducers","openUploadProgress","state","action","pendingFiles","payload","fileNames","map","index","status","size","fileSizes","uploadedBytes","undefined","appendUploadFiles","offset","length","push","i","setFileUploading","setFileProgress","bytes","file","Math","min","setFileComplete","completedAt","setFileError","message","error","setFileMetadataGenerating","metadataStatus","setFileMetadataResult","addUploadErrors","closeUploadProgress","toggleMinimize","cancelUpload","setUploadFailed","retryCancelledFiles","NO_FILES","selectCompletedUploads","createSelector","uploadProgress","reduce","completed","row","asset","selectAggregateProgress","totalSize","sum","f","settled","filter","round","selectReportsByteProgress","selectCountBasedProgress","done","selectMetadataProgress","started","pending","expected","selectIsGeneratingMetadata","some","hasStarted","selectMetadataOutcome","isOngoing","generated","skipped","failed","actions","isUploadInFlight","uploadProgressReducer","reducer"],"mappings":";;AAoDA,MAAMA,YAAAA,GAAoC;IACxCC,SAAAA,EAAW,KAAA;IACXC,WAAAA,EAAa,KAAA;IACbC,UAAAA,EAAY,CAAA;AACZC,IAAAA,KAAAA,EAAO,EAAE;AACTC,IAAAA,MAAAA,EAAQ,EAAE;IACVC,QAAAA,EAAU,CAAA;IACVC,mBAAAA,EAAqB;AACvB,CAAA;AAEA,MAAMC,sBAAsBC,WAAAA,CAAY;IACtCC,IAAAA,EAAM,gBAAA;AACNV,IAAAA,YAAAA;IACAW,QAAAA,EAAU;QACRC,kBAAAA,CAAAA,CACEC,KAAK,EACLC,MAIE,EAAA;AAEFD,YAAAA,KAAAA,CAAMZ,SAAS,GAAG,IAAA;AAClBY,YAAAA,KAAAA,CAAMX,WAAW,GAAG,KAAA;;YAGpB,MAAMa,YAAAA,GAA+BD,MAAAA,CAAOE,OAAO,CAACC,SAAS,CAACC,GAAG,CAAC,CAACR,IAAAA,EAAMS,KAAAA,IAAW;AAClFT,oBAAAA,IAAAA;AACAS,oBAAAA,KAAAA;oBACAC,MAAAA,EAAQ,SAAA;AACRC,oBAAAA,IAAAA,EAAMP,OAAOE,OAAO,CAACM,SAAS,GAAGH,MAAM,IAAI,CAAA;oBAC3CI,aAAAA,EAAe;iBACjB,CAAA,CAAA;AAEAV,YAAAA,KAAAA,CAAMT,KAAK,GAAGW,YAAAA;AACdF,YAAAA,KAAAA,CAAMV,UAAU,GAAGW,MAAAA,CAAOE,OAAO,CAACb,UAAU;YAC5CU,KAAAA,CAAMR,MAAM,GAAG,EAAE;AACjBQ,YAAAA,KAAAA,CAAMP,QAAQ,IAAI,CAAA;;AAElBO,YAAAA,KAAAA,CAAMN,mBAAmB,GAAGO,MAAAA,CAAOE,OAAO,CAACM,SAAS,KAAKE,SAAAA;AAC3D,QAAA,CAAA;AACA;;;;QAKAC,iBAAAA,CAAAA,CACEZ,KAAK,EACLC,MAIE,EAAA;AAEF,YAAA,IAAIA,OAAOE,OAAO,CAACV,QAAQ,KAAKO,KAAAA,CAAMP,QAAQ,EAAE;AAC9C,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMoB,MAAAA,GAASb,KAAAA,CAAMT,KAAK,CAACuB,MAAM;AAEjCd,YAAAA,KAAAA,CAAMT,KAAK,CAACwB,IAAI,CAAA,GACXd,OAAOE,OAAO,CAACC,SAAS,CAACC,GAAG,CAAC,CAACR,IAAAA,EAAMmB,KAAO;AAC5CnB,oBAAAA,IAAAA;AACAS,oBAAAA,KAAAA,EAAOO,MAAAA,GAASG,CAAAA;oBAChBT,MAAAA,EAAQ,SAAA;AACRC,oBAAAA,IAAAA,EAAMP,OAAOE,OAAO,CAACM,SAAS,GAAGO,EAAE,IAAI,CAAA;oBACvCN,aAAAA,EAAe;iBACjB,CAAA,CAAA,CAAA;AAGFV,YAAAA,KAAAA,CAAMV,UAAU,IAAIW,MAAAA,CAAOE,OAAO,CAACC,SAAS,CAACU,MAAM;;AAEnDd,YAAAA,KAAAA,CAAMZ,SAAS,GAAG,IAAA;AAClBY,YAAAA,KAAAA,CAAMX,WAAW,GAAG,KAAA;AACtB,QAAA,CAAA;QACA4B,gBAAAA,CAAAA,CACEjB,KAAK,EACLC,MAAsF,EAAA;YAEtF,MAAM,EAAEK,KAAK,EAAEE,IAAI,EAAEf,QAAQ,EAAE,GAAGQ,MAAAA,CAAOE,OAAO;YAChD,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,IAAIO,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,EAAE;AACtBN,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACC,MAAM,GAAG,WAAA;AAC5BP,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACE,IAAI,GAAGA,IAAAA;AAC5B,YAAA;AACF,QAAA,CAAA;AACA;;;;;QAMAU,eAAAA,CAAAA,CACElB,KAAK,EACLC,MAAwF,EAAA;YAExF,MAAM,EAAEK,KAAK,EAAEa,KAAK,EAAEX,IAAI,EAAEf,QAAQ,EAAE,GAAGQ,MAAAA,CAAOE,OAAO;YACvD,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,MAAM2B,IAAAA,GAAOpB,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM;AAC/B,YAAA,IAAIc,IAAAA,EAAM;AACR,gBAAA,IAAIZ,IAAAA,KAASG,SAAAA,IAAaS,IAAAA,CAAKZ,IAAI,KAAK,CAAA,EAAG;AACzCY,oBAAAA,IAAAA,CAAKZ,IAAI,GAAGA,IAAAA;AACd,gBAAA;;AAEAY,gBAAAA,IAAAA,CAAKV,aAAa,GAAGW,IAAAA,CAAKC,GAAG,CAACH,KAAAA,EAAOC,KAAKZ,IAAI,CAAA;AAChD,YAAA;AACF,QAAA,CAAA;QACAe,eAAAA,CAAAA,CACEvB,KAAK,EACLC,MAA2F,EAAA;YAE3F,MAAM,EAAEK,KAAK,EAAEc,IAAI,EAAE3B,QAAQ,EAAE+B,WAAW,EAAE,GAAGvB,MAAAA,CAAOE,OAAO;YAC7D,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,IAAIO,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,EAAE;AACtBN,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACC,MAAM,GAAG,UAAA;AAC5BP,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACc,IAAI,GAAGA,IAAAA;AAC1BpB,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACkB,WAAW,GAAGA,WAAAA;;gBAEjCxB,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACI,aAAa,GAAGV,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACE,IAAI;AAC5D,YAAA;AACF,QAAA,CAAA;QACAiB,YAAAA,CAAAA,CACEzB,KAAK,EACLC,MAAyF,EAAA;YAEzF,MAAM,EAAEK,KAAK,EAAET,IAAI,EAAE6B,OAAO,EAAEjC,QAAQ,EAAE,GAAGQ,MAAAA,CAAOE,OAAO;YACzD,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,IAAIO,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,EAAE;AACtBN,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACC,MAAM,GAAG,OAAA;AAC5BP,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACqB,KAAK,GAAGD,OAAAA;AAC7B,YAAA;AACA1B,YAAAA,KAAAA,CAAMR,MAAM,GAAG;AAAIQ,gBAAAA,GAAAA,KAAAA,CAAMR,MAAM;AAAE,gBAAA;AAAEK,oBAAAA,IAAAA;AAAM6B,oBAAAA;AAAQ;AAAE,aAAA;AACrD,QAAA,CAAA;AACA;;;;;;;QAQAE,yBAAAA,CAAAA,CAA0B5B,KAAK,EAAEC,MAA0D,EAAA;AACzF,YAAA,MAAM,EAAEK,KAAK,EAAEb,QAAQ,EAAE,GAAGQ,OAAOE,OAAO;YAC1C,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,IAAIO,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,EAAE;AACtBN,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACuB,cAAc,GAAG,YAAA;AACtC,YAAA;AACF,QAAA,CAAA;AACA;;;QAIAC,qBAAAA,CAAAA,CACE9B,KAAK,EACLC,MAIE,EAAA;YAEF,MAAM,EAAEK,KAAK,EAAEb,QAAQ,EAAEc,MAAM,EAAE,GAAGN,MAAAA,CAAOE,OAAO;YAClD,IAAIV,QAAAA,KAAaO,KAAAA,CAAMP,QAAQ,EAAE;AAC/B,gBAAA;AACF,YAAA;AACA,YAAA,IAAIO,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,EAAE;AACtBN,gBAAAA,KAAAA,CAAMT,KAAK,CAACe,KAAAA,CAAM,CAACuB,cAAc,GAAGtB,MAAAA;AACtC,YAAA;AACF,QAAA,CAAA;QACAwB,eAAAA,CAAAA,CAAgB/B,KAAK,EAAEC,MAAwC,EAAA;AAC7DD,YAAAA,KAAAA,CAAMR,MAAM,GAAG;AAAIQ,gBAAAA,GAAAA,KAAAA,CAAMR,MAAM;AAAKS,gBAAAA,GAAAA,MAAAA,CAAOE;AAAQ,aAAA;AACrD,QAAA,CAAA;AACA6B,QAAAA,mBAAAA,CAAAA,CAAoBhC,KAAK,EAAA;AACvBA,YAAAA,KAAAA,CAAMZ,SAAS,GAAG,KAAA;AAClBY,YAAAA,KAAAA,CAAMX,WAAW,GAAG,KAAA;AACpBW,YAAAA,KAAAA,CAAMV,UAAU,GAAG,CAAA;YACnBU,KAAAA,CAAMT,KAAK,GAAG,EAAE;YAChBS,KAAAA,CAAMR,MAAM,GAAG,EAAE;AACjBQ,YAAAA,KAAAA,CAAMN,mBAAmB,GAAG,KAAA;AAC9B,QAAA,CAAA;AACAuC,QAAAA,cAAAA,CAAAA,CAAejC,KAAK,EAAA;AAClBA,YAAAA,KAAAA,CAAMX,WAAW,GAAG,CAACW,KAAAA,CAAMX,WAAW;AACxC,QAAA,CAAA;AACA6C,QAAAA,YAAAA,CAAAA,CAAalC,KAAK,EAAA;;AAEhBA,YAAAA,KAAAA,CAAMT,KAAK,GAAGS,KAAAA,CAAMT,KAAK,CAACc,GAAG,CAAC,CAACe,IAAAA,GAAAA;AAC7B,gBAAA,IAAIA,KAAKb,MAAM,KAAK,aAAaa,IAAAA,CAAKb,MAAM,KAAK,WAAA,EAAa;oBAC5D,OAAO;AAAE,wBAAA,GAAGa,IAAI;wBAAEb,MAAAA,EAAQ;AAAkC,qBAAA;AAC9D,gBAAA;gBACA,OAAOa,IAAAA;AACT,YAAA,CAAA,CAAA;AACF,QAAA,CAAA;QACAe,eAAAA,CAAAA,CAAgBnC,KAAK,EAAEC,MAA0C,EAAA;;AAE/DD,YAAAA,KAAAA,CAAMT,KAAK,GAAGS,KAAAA,CAAMT,KAAK,CAACc,GAAG,CAAC,CAACe,IAAAA,GAAAA;AAC7B,gBAAA,IAAIA,KAAKb,MAAM,KAAK,aAAaa,IAAAA,CAAKb,MAAM,KAAK,WAAA,EAAa;oBAC5D,OAAO;AACL,wBAAA,GAAGa,IAAI;wBACPb,MAAAA,EAAQ,OAAA;wBACRoB,KAAAA,EAAO1B,MAAAA,CAAOE,OAAO,CAACuB;AACxB,qBAAA;AACF,gBAAA;gBACA,OAAON,IAAAA;AACT,YAAA,CAAA,CAAA;AACApB,YAAAA,KAAAA,CAAMR,MAAM,GAAG;AAAIQ,gBAAAA,GAAAA,KAAAA,CAAMR,MAAM;AAAE,gBAAA;oBAAEK,IAAAA,EAAM,cAAA;oBAAgB6B,OAAAA,EAASzB,MAAAA,CAAOE,OAAO,CAACuB;AAAQ;AAAE,aAAA;AAC7F,QAAA,CAAA;AACAU,QAAAA,mBAAAA,CAAAA,CAAoBpC,KAAK,EAAA;;AAEvBA,YAAAA,KAAAA,CAAMT,KAAK,GAAGS,KAAAA,CAAMT,KAAK,CAACc,GAAG,CAAC,CAACe,IAAAA,GAAAA;gBAC7B,IAAIA,IAAAA,CAAKb,MAAM,KAAK,WAAA,EAAa;oBAC/B,OAAO;AACL,wBAAA,GAAGa,IAAI;wBACPb,MAAAA,EAAQ,SAAA;wBACRG,aAAAA,EAAe,CAAA;;wBAEfmB,cAAAA,EAAgBlB;AAClB,qBAAA;AACF,gBAAA;gBACA,OAAOS,IAAAA;AACT,YAAA,CAAA,CAAA;AACF,QAAA;AACF;AACF,CAAA,CAAA;AAEA;;;;;;;IAQA,MAAMiB,WAA2B,EAAE;AAQ5B,MAAMC,sBAAAA,GAAyBC,cAAAA;AAEpC;AACA,CAACvC,KAAAA,GAA8BA,KAAAA,CAAMwC,cAAc,EAAEjD,KAAAA,IAAS8C,QAAAA,EAC9D,CAAC9C,KAAAA,GACCA,KAAAA,CAAMkD,MAAM,CAAoB,CAACC,SAAAA,EAAWC,GAAAA,GAAAA;QAC1C,IAAIA,GAAAA,CAAIpC,MAAM,KAAK,UAAA,IAAcoC,GAAAA,CAAIvB,IAAI,IAAIuB,GAAAA,CAAInB,WAAW,KAAKb,SAAAA,EAAW;AAC1E+B,YAAAA,SAAAA,CAAU3B,IAAI,CAAC;AAAE6B,gBAAAA,KAAAA,EAAOD,IAAIvB,IAAI;AAAEI,gBAAAA,WAAAA,EAAamB,IAAInB;AAAY,aAAA,CAAA;AACjE,QAAA;QAEA,OAAOkB,SAAAA;AACT,IAAA,CAAA,EAAG,EAAE,CAAA;AAGT;;;;;IAMO,MAAMG,uBAAAA,GAA0BN,cAAAA,CACrC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAACjD,KAAK,EAChD,CAACA,KAAAA,GAAAA;AACC,IAAA,IAAIA,KAAAA,CAAMuB,MAAM,KAAK,CAAA,EAAG,OAAO,CAAA;IAE/B,MAAMgC,SAAAA,GAAYvD,KAAAA,CAAMkD,MAAM,CAAC,CAACM,KAAKC,CAAAA,GAAMD,GAAAA,GAAMC,CAAAA,CAAExC,IAAI,EAAE,CAAA,CAAA;AAEzD,IAAA,IAAIsC,cAAc,CAAA,EAAG;AACnB,QAAA,MAAMG,UAAU1D,KAAAA,CAAM2D,MAAM,CAC1B,CAACF,CAAAA,GAAMA,EAAEzC,MAAM,KAAK,UAAA,IAAcyC,CAAAA,CAAEzC,MAAM,KAAK,OAAA,IAAWyC,EAAEzC,MAAM,KAAK,aACvEO,MAAM;AACR,QAAA,OAAOO,KAAK8B,KAAK,CAAC,OAACF,GAAU1D,KAAAA,CAAMuB,MAAM,GAAI,GAAA,CAAA;AAC/C,IAAA;IAEA,MAAMJ,aAAAA,GAAgBnB,KAAAA,CAAMkD,MAAM,CAAC,CAACM,KAAKC,CAAAA,GAAMD,GAAAA,GAAMC,CAAAA,CAAEtC,aAAa,EAAE,CAAA,CAAA;AACtE,IAAA,OAAOW,IAAAA,CAAK8B,KAAK,CAAEzC,gBAAgBoC,SAAAA,GAAa,GAAA,CAAA;AAClD,CAAA;AAGF;;;;;;AAMC,IACM,MAAMM,yBAAAA,GAA4Bb,cAAAA,CACvC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAAC9C,mBAAmB,EAC9D,CAACA,sBAAiCA,mBAAAA;AAGpC;;;;;;;;IASO,MAAM2D,wBAAAA,GAA2Bd,cAAAA,CACtC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAACjD,KAAK,EAChD,CAACA,KAAAA,GAAAA;AACC,IAAA,MAAM+D,IAAAA,GAAO/D,KAAAA,CAAMkD,MAAM,CAAC,CAACM,GAAAA,EAAKC,CAAAA,GAAAA;QAC9B,IAAIA,CAAAA,CAAEzC,MAAM,KAAK,UAAA,IAAcyC,CAAAA,CAAEzC,MAAM,KAAK,OAAA,IAAWyC,CAAAA,CAAEzC,MAAM,KAAK,WAAA,EAAa;AAC/E,YAAA,OAAOwC,GAAAA,GAAM,CAAA;AACf,QAAA;AACA,QAAA,OAAOC,CAAAA,CAAExC,IAAI,GAAG,CAAA,GAAIuC,MAAM1B,IAAAA,CAAKC,GAAG,CAAC0B,CAAAA,CAAEtC,aAAa,GAAGsC,CAAAA,CAAExC,IAAI,EAAE,CAAA,CAAA,GAAKuC,GAAAA;IACpE,CAAA,EAAG,CAAA,CAAA;AAEH,IAAA,IAAIO,SAAS,CAAA,EAAG;QACd,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,OAAOjC,KAAK8B,KAAK,CAAC,IAACG,GAAO/D,KAAAA,CAAMuB,MAAM,GAAI,GAAA,CAAA;AAC5C,CAAA;AAGF;;;;;;;;;;;;;;;;;;;IAoBO,MAAMyC,sBAAAA,GAAyBhB,cAAAA,CACpC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAACjD,KAAK,EAChD,CAACA,KAAAA,GAAAA;IACC,MAAMiE,OAAAA,GAAUjE,MAAM2D,MAAM,CAAC,CAACF,CAAAA,GAAMA,CAAAA,CAAEnB,cAAc,KAAKlB,SAAAA,CAAAA;;;AAIzD,IAAA,IAAI6C,OAAAA,CAAQ1C,MAAM,KAAK,CAAA,EAAG,OAAO,IAAA;;;IAIjC,MAAM2C,OAAAA,GAAUlE,MAAM2D,MAAM,CAC1B,CAACF,CAAAA,GAAMA,CAAAA,CAAEnB,cAAc,KAAKlB,SAAAA,KAAcqC,CAAAA,CAAEzC,MAAM,KAAK,SAAA,IAAayC,CAAAA,CAAEzC,MAAM,KAAK,WAAU,GAC3FO,MAAM;IAER,MAAM4C,QAAAA,GAAWF,OAAAA,CAAQ1C,MAAM,GAAG2C,OAAAA;IAClC,MAAMR,OAAAA,GAAUO,OAAAA,CAAQN,MAAM,CAAC,CAACF,IAAMA,CAAAA,CAAEnB,cAAc,KAAK,YAAA,CAAA,CAAcf,MAAM;AAE/E,IAAA,OAAOO,IAAAA,CAAK8B,KAAK,CAAEF,UAAUS,QAAAA,GAAY,GAAA,CAAA;AAC3C,CAAA;AAGF;;;;;;;;;;;;IAaO,MAAMC,0BAAAA,GAA6BpB,cAAAA,CACxC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAACjD,KAAK,EAChD,CAACA,KAAAA,GAAAA;IACC,IAAIA,KAAAA,CAAMqE,IAAI,CAAC,CAACZ,IAAMA,CAAAA,CAAEnB,cAAc,KAAK,YAAA,CAAA,EAAe,OAAO,IAAA;;;IAIjE,MAAMgC,UAAAA,GAAatE,MAAMqE,IAAI,CAAC,CAACZ,CAAAA,GAAMA,CAAAA,CAAEnB,cAAc,KAAKlB,SAAAA,CAAAA;AAE1D,IAAA,OAAOkD,UAAAA,IAActE,KAAAA,CAAMqE,IAAI,CAAC,CAACZ,CAAAA,GAAMA,CAAAA,CAAEzC,MAAM,KAAK,SAAA,IAAayC,CAAAA,CAAEzC,MAAM,KAAK,WAAA,CAAA;AAChF,CAAA;AAGF;;;;;;;;;IAUO,MAAMuD,qBAAAA,GAAwBvB,cAAAA,CACnC,CAACvC,KAAAA,GAAqBA,KAAAA,CAAMwC,cAAc,CAACjD,KAAK,EAChD,CAACA,KAAAA,GAAAA;IACC,MAAMiE,OAAAA,GAAUjE,MAAM2D,MAAM,CAAC,CAACF,CAAAA,GAAMA,CAAAA,CAAEnB,cAAc,KAAKlB,SAAAA,CAAAA;AAEzD,IAAA,IAAI6C,OAAAA,CAAQ1C,MAAM,KAAK,CAAA,EAAG,OAAO,IAAA;;;IAIjC,MAAMiD,SAAAA,GACJP,QAAQI,IAAI,CAAC,CAACZ,CAAAA,GAAMA,CAAAA,CAAEnB,cAAc,KAAK,YAAA,CAAA,IACzCtC,MAAMqE,IAAI,CAAC,CAACZ,CAAAA,GAAMA,CAAAA,CAAEzC,MAAM,KAAK,SAAA,IAAayC,CAAAA,CAAEzC,MAAM,KAAK,WAAA,CAAA;AAE3D,IAAA,IAAIwD,WAAW,OAAO,IAAA;IAEtB,OAAO;QACLC,SAAAA,EAAWR,OAAAA,CAAQN,MAAM,CAAC,CAACF,IAAMA,CAAAA,CAAEnB,cAAc,KAAK,WAAA,CAAA,CAAaf,MAAM;QACzEmD,OAAAA,EAAST,OAAAA,CAAQN,MAAM,CAAC,CAACF,IAAMA,CAAAA,CAAEnB,cAAc,KAAK,SAAA,CAAA,CAAWf,MAAM;QACrEoD,MAAAA,EAAQV,OAAAA,CAAQN,MAAM,CAAC,CAACF,IAAMA,CAAAA,CAAEnB,cAAc,KAAK,QAAA,CAAA,CAAUf;AAC/D,KAAA;AACF,CAAA;AAGK,MAAM,EACXf,kBAAkB,EAClBa,iBAAiB,EACjBK,gBAAgB,EAChBC,eAAe,EACfK,eAAe,EACfE,YAAY,EACZG,yBAAyB,EACzBE,qBAAqB,EACrBC,eAAe,EACfC,mBAAmB,EACnBC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,mBAAmB,EACpB,GAAGzC,mBAAAA,CAAoBwE;AAExB;;;AAGC,IACM,MAAMC,gBAAAA,GAAmB,CAAC7E,KAAAA,GAC/BA,MAAMqE,IAAI,CAAC,CAACZ,CAAAA,GAAMA,EAAEzC,MAAM,KAAK,aAAayC,CAAAA,CAAEzC,MAAM,KAAK,WAAA;AAEpD,MAAM8D,qBAAAA,GAAwB1E,mBAAAA,CAAoB2E;;;;"}
|
package/dist/admin/index.js
CHANGED
|
@@ -53,10 +53,11 @@ const name = _package.default.strapi.name;
|
|
|
53
53
|
const admin = {
|
|
54
54
|
register (app) {
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
|
|
56
|
+
* Whichever Media Library is selected owns `plugins/upload` outright: the other is
|
|
57
|
+
* not registered at all, so there is exactly one Media Library entry in the menu.
|
|
58
|
+
*
|
|
59
|
+
* The new one is the default; `useLegacyMediaLibrary` opts back out.
|
|
60
|
+
*/ const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');
|
|
60
61
|
app.addMenuLink({
|
|
61
62
|
to: `plugins/${pluginId.pluginId}`,
|
|
62
63
|
icon: icons.Images,
|
|
@@ -65,18 +66,18 @@ const admin = {
|
|
|
65
66
|
defaultMessage: 'Media Library'
|
|
66
67
|
},
|
|
67
68
|
permissions: constants.PERMISSIONS.main,
|
|
68
|
-
Component:
|
|
69
|
-
return Promise.resolve().then(function () { return require('./future/App.js'); }).then((mod)=>({
|
|
70
|
-
default: mod.BetaMediaLibrary
|
|
71
|
-
}));
|
|
72
|
-
} : ()=>{
|
|
69
|
+
Component: isLegacyMediaLibrary ? ()=>{
|
|
73
70
|
return Promise.resolve().then(function () { return require('./pages/App/App.js'); }).then((mod)=>({
|
|
74
71
|
default: mod.Upload
|
|
75
72
|
}));
|
|
73
|
+
} : ()=>{
|
|
74
|
+
return Promise.resolve().then(function () { return require('./future/App.js'); }).then((mod)=>({
|
|
75
|
+
default: mod.BetaMediaLibrary
|
|
76
|
+
}));
|
|
76
77
|
},
|
|
77
78
|
position: 4
|
|
78
79
|
});
|
|
79
|
-
if (
|
|
80
|
+
if (!isLegacyMediaLibrary) {
|
|
80
81
|
app.addReducers({
|
|
81
82
|
uploadProgress: uploadProgress.uploadProgressReducer
|
|
82
83
|
});
|
package/dist/admin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n *
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * Whichever Media Library is selected owns `plugins/upload` outright: the other is\n * not registered at all, so there is exactly one Media Library entry in the menu.\n *\n * The new one is the default; `useLegacyMediaLibrary` opts back out.\n */\n const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isLegacyMediaLibrary\n ? () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n }\n : () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n },\n position: 4,\n });\n\n if (!isLegacyMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isLegacyMediaLibrary","window","featureFlags","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","Upload","BetaMediaLibrary","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
|
package/dist/admin/index.mjs
CHANGED
|
@@ -49,10 +49,11 @@ const name = pluginPkg.strapi.name;
|
|
|
49
49
|
const admin = {
|
|
50
50
|
register (app) {
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
|
|
52
|
+
* Whichever Media Library is selected owns `plugins/upload` outright: the other is
|
|
53
|
+
* not registered at all, so there is exactly one Media Library entry in the menu.
|
|
54
|
+
*
|
|
55
|
+
* The new one is the default; `useLegacyMediaLibrary` opts back out.
|
|
56
|
+
*/ const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');
|
|
56
57
|
app.addMenuLink({
|
|
57
58
|
to: `plugins/${pluginId}`,
|
|
58
59
|
icon: Images,
|
|
@@ -61,18 +62,18 @@ const admin = {
|
|
|
61
62
|
defaultMessage: 'Media Library'
|
|
62
63
|
},
|
|
63
64
|
permissions: PERMISSIONS.main,
|
|
64
|
-
Component:
|
|
65
|
-
return import('./future/App.mjs').then((mod)=>({
|
|
66
|
-
default: mod.BetaMediaLibrary
|
|
67
|
-
}));
|
|
68
|
-
} : ()=>{
|
|
65
|
+
Component: isLegacyMediaLibrary ? ()=>{
|
|
69
66
|
return import('./pages/App/App.mjs').then((mod)=>({
|
|
70
67
|
default: mod.Upload
|
|
71
68
|
}));
|
|
69
|
+
} : ()=>{
|
|
70
|
+
return import('./future/App.mjs').then((mod)=>({
|
|
71
|
+
default: mod.BetaMediaLibrary
|
|
72
|
+
}));
|
|
72
73
|
},
|
|
73
74
|
position: 4
|
|
74
75
|
});
|
|
75
|
-
if (
|
|
76
|
+
if (!isLegacyMediaLibrary) {
|
|
76
77
|
app.addReducers({
|
|
77
78
|
uploadProgress: uploadProgressReducer
|
|
78
79
|
});
|
package/dist/admin/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n *
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * Whichever Media Library is selected owns `plugins/upload` outright: the other is\n * not registered at all, so there is exactly one Media Library entry in the menu.\n *\n * The new one is the default; `useLegacyMediaLibrary` opts back out.\n */\n const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isLegacyMediaLibrary\n ? () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n }\n : () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n },\n position: 4,\n });\n\n if (!isLegacyMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isLegacyMediaLibrary","window","featureFlags","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","Upload","BetaMediaLibrary","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
|
|
@@ -32,9 +32,8 @@ export interface UploadProgressState {
|
|
|
32
32
|
errors: FileUploadError[];
|
|
33
33
|
uploadId: number;
|
|
34
34
|
/**
|
|
35
|
-
* Whether
|
|
36
|
-
* byte
|
|
37
|
-
* so its byte-weighted aggregate is stuck at 0%.
|
|
35
|
+
* Whether every row's size was known when the batch opened (the direct-file flow), so
|
|
36
|
+
* the byte-weighted aggregate is meaningful. The URL flow learns sizes one row at a time.
|
|
38
37
|
*/
|
|
39
38
|
reportsByteProgress: boolean;
|
|
40
39
|
}
|
|
@@ -63,31 +62,25 @@ export declare const selectAggregateProgress: ((state: RootState) => number) & i
|
|
|
63
62
|
clearCache: () => void;
|
|
64
63
|
};
|
|
65
64
|
/**
|
|
66
|
-
* Whether to show byte-weighted `selectAggregateProgress` rather than
|
|
67
|
-
* A batch that never reports bytes stays pinned at 0%, so the header falls back to
|
|
68
|
-
* `selectCountBasedProgress`.
|
|
65
|
+
* Whether to show byte-weighted `selectAggregateProgress` rather than `selectCountBasedProgress`.
|
|
69
66
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* settled rows qualify would switch a multi-URL batch to byte-weighting mid-upload over only
|
|
74
|
-
* the sizes known so far (transiently 100% after the first file).
|
|
67
|
+
* Only the flag: byte-weighting needs every size up front. A URL batch learns sizes one row
|
|
68
|
+
* at a time, so weighting over the sizes known so far makes the header jump backwards at
|
|
69
|
+
* every file boundary.
|
|
75
70
|
*/
|
|
76
|
-
export declare const selectReportsByteProgress: ((state: RootState) => boolean) & import("reselect").OutputSelectorFields<(args_0: boolean
|
|
71
|
+
export declare const selectReportsByteProgress: ((state: RootState) => boolean) & import("reselect").OutputSelectorFields<(args_0: boolean) => boolean, {
|
|
77
72
|
clearCache: () => void;
|
|
78
73
|
}> & {
|
|
79
74
|
clearCache: () => void;
|
|
80
75
|
};
|
|
81
76
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
77
|
+
* Row-weighted progress for a batch whose sizes are not known up front (the URL flow).
|
|
78
|
+
* Each row is worth `1 / total`: settled rows count fully and an in-flight row contributes
|
|
79
|
+
* `uploadedBytes / size` once it reports bytes, so a multi-URL batch climbs smoothly to
|
|
80
|
+
* 33 → 67 → 100 and never moves backwards.
|
|
84
81
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* Returns `null` until a row settles — 0% is the frozen signal this flow exists to remove
|
|
89
|
-
* (a lone URL upload would otherwise read "Uploading 1 item (0%)" throughout), so the header
|
|
90
|
-
* stays indeterminate until there's real progress.
|
|
82
|
+
* Returns `null` until something has moved — 0% is the frozen signal this flow exists to
|
|
83
|
+
* remove, so the header stays indeterminate until there's real progress.
|
|
91
84
|
*/
|
|
92
85
|
export declare const selectCountBasedProgress: ((state: RootState) => number | null) & import("reselect").OutputSelectorFields<(args_0: FileProgress[]) => number | null, {
|
|
93
86
|
clearCache: () => void;
|
|
@@ -177,6 +170,7 @@ export declare const openUploadProgress: import("@reduxjs/toolkit").ActionCreato
|
|
|
177
170
|
index: number;
|
|
178
171
|
bytes: number;
|
|
179
172
|
uploadId: number;
|
|
173
|
+
size?: number;
|
|
180
174
|
}, "uploadProgress/setFileProgress">, setFileComplete: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
181
175
|
index: number;
|
|
182
176
|
file: File;
|
|
@@ -102,9 +102,6 @@ var en = {
|
|
|
102
102
|
"upload.progress.maximize": "Maximize",
|
|
103
103
|
"upload.progress.minimize": "Minimize",
|
|
104
104
|
"upload.progress.close": "Close",
|
|
105
|
-
"beta.badge": "Beta",
|
|
106
|
-
"beta.notice.close": "Close",
|
|
107
|
-
"beta.notice.content": "This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.",
|
|
108
105
|
"bulk.select.label": "Select all assets",
|
|
109
106
|
"button.next": "Next",
|
|
110
107
|
"new": "New",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -100,9 +100,6 @@ var en = {
|
|
|
100
100
|
"upload.progress.maximize": "Maximize",
|
|
101
101
|
"upload.progress.minimize": "Minimize",
|
|
102
102
|
"upload.progress.close": "Close",
|
|
103
|
-
"beta.badge": "Beta",
|
|
104
|
-
"beta.notice.close": "Close",
|
|
105
|
-
"beta.notice.content": "This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.",
|
|
106
103
|
"bulk.select.label": "Select all assets",
|
|
107
104
|
"button.next": "Next",
|
|
108
105
|
"new": "New",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/server/bootstrap.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./utils/index.js');
|
|
4
4
|
var constants = require('./constants.js');
|
|
5
|
+
var mediaLibraryDefaultNotice = require('./media-library-default-notice.js');
|
|
5
6
|
|
|
6
7
|
async function bootstrap({ strapi: strapi1 }) {
|
|
7
8
|
const defaultConfig = {
|
|
@@ -16,6 +17,9 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
16
17
|
sort: constants.ALLOWED_SORT_STRINGS[0]
|
|
17
18
|
}
|
|
18
19
|
};
|
|
20
|
+
// Whether this plugin has stored settings from an earlier boot, which is what separates
|
|
21
|
+
// an upgrading app from a fresh install for the Media Library default notice below.
|
|
22
|
+
let isExistingApp = false;
|
|
19
23
|
for (const [key, defaultValue] of Object.entries(defaultConfig)){
|
|
20
24
|
// set plugin store
|
|
21
25
|
const configurator = strapi1.store({
|
|
@@ -24,6 +28,9 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
24
28
|
key
|
|
25
29
|
});
|
|
26
30
|
const config = await configurator.get({});
|
|
31
|
+
if (config) {
|
|
32
|
+
isExistingApp = true;
|
|
33
|
+
}
|
|
27
34
|
if (config && Object.keys(defaultValue).every((key)=>Object.prototype.hasOwnProperty.call(config, key))) {
|
|
28
35
|
continue;
|
|
29
36
|
}
|
|
@@ -33,6 +40,10 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
33
40
|
value: Object.assign(defaultValue, config || {})
|
|
34
41
|
});
|
|
35
42
|
}
|
|
43
|
+
await mediaLibraryDefaultNotice.notifyMediaLibraryDefault({
|
|
44
|
+
strapi: strapi1,
|
|
45
|
+
isExistingApp
|
|
46
|
+
});
|
|
36
47
|
await registerPermissionActions();
|
|
37
48
|
await registerWebhookEvents();
|
|
38
49
|
await index.getService('weeklyMetrics').registerCron();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getService } from './utils/index.mjs';
|
|
2
2
|
import { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants.mjs';
|
|
3
|
+
import { notifyMediaLibraryDefault } from './media-library-default-notice.mjs';
|
|
3
4
|
|
|
4
5
|
async function bootstrap({ strapi: strapi1 }) {
|
|
5
6
|
const defaultConfig = {
|
|
@@ -14,6 +15,9 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
14
15
|
sort: ALLOWED_SORT_STRINGS[0]
|
|
15
16
|
}
|
|
16
17
|
};
|
|
18
|
+
// Whether this plugin has stored settings from an earlier boot, which is what separates
|
|
19
|
+
// an upgrading app from a fresh install for the Media Library default notice below.
|
|
20
|
+
let isExistingApp = false;
|
|
17
21
|
for (const [key, defaultValue] of Object.entries(defaultConfig)){
|
|
18
22
|
// set plugin store
|
|
19
23
|
const configurator = strapi1.store({
|
|
@@ -22,6 +26,9 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
22
26
|
key
|
|
23
27
|
});
|
|
24
28
|
const config = await configurator.get({});
|
|
29
|
+
if (config) {
|
|
30
|
+
isExistingApp = true;
|
|
31
|
+
}
|
|
25
32
|
if (config && Object.keys(defaultValue).every((key)=>Object.prototype.hasOwnProperty.call(config, key))) {
|
|
26
33
|
continue;
|
|
27
34
|
}
|
|
@@ -31,6 +38,10 @@ async function bootstrap({ strapi: strapi1 }) {
|
|
|
31
38
|
value: Object.assign(defaultValue, config || {})
|
|
32
39
|
});
|
|
33
40
|
}
|
|
41
|
+
await notifyMediaLibraryDefault({
|
|
42
|
+
strapi: strapi1,
|
|
43
|
+
isExistingApp
|
|
44
|
+
});
|
|
34
45
|
await registerPermissionActions();
|
|
35
46
|
await registerWebhookEvents();
|
|
36
47
|
await getService('weeklyMetrics').registerCron();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
|