@@ -5,11 +5,12 @@ import { get } from 'svelte/store';
55
66import { allAssets } from '$lib/services/assets' ;
77import { getAssetPublicURL } from '$lib/services/assets/info' ;
8+ import { getAssetKind } from '$lib/services/assets/kinds' ;
89import { transformFile } from '$lib/services/integrations/media-libraries/default' ;
910import { getGitHash } from '$lib/services/utils/file' ;
1011
1112/**
12- * @import { EntryDraft, SelectedResource } from '$lib/types/private';
13+ * @import { Asset, AssetFolderInfo, EntryDraft, SelectedResource } from '$lib/types/private';
1314 * @import { DefaultMediaLibraryConfig } from '$lib/types/public';
1415 */
1516
@@ -37,6 +38,45 @@ export const getExistingBlobURL = async ({ draft, file }) => {
3738 return foundURL ;
3839} ;
3940
41+ /**
42+ * Convert unsaved files to the `Asset` format so these can be browsed just like other assets.
43+ * @param {object } args Arguments.
44+ * @param {File } args.file Raw file.
45+ * @param {string } [args.blobURL] Blob URL of the file.
46+ * @param {AssetFolderInfo | undefined } args.folder Asset folder.
47+ * @param {string } [args.targetFolderPath] Target folder path.
48+ * @returns {Promise<Asset> } Asset.
49+ */
50+ export const convertFileItemToAsset = async ( { file, blobURL, folder, targetFolderPath } ) => {
51+ const { name, size } = file ;
52+
53+ return /** @type {Asset } */ ( {
54+ unsaved : true ,
55+ file,
56+ blobURL : blobURL ?? URL . createObjectURL ( file ) ,
57+ name,
58+ path : targetFolderPath ? `${ targetFolderPath } /${ name } ` : name ,
59+ sha : await getGitHash ( file ) ,
60+ size,
61+ kind : getAssetKind ( name ) ,
62+ folder,
63+ } ) ;
64+ } ;
65+
66+ /**
67+ * Get all the unsaved assets, including already cached for the draft and dropped ones.
68+ * @param {object } args Arguments.
69+ * @param {EntryDraft } args.draft Entry draft containing the resource.
70+ * @param {string } [args.targetFolderPath] Target folder path.
71+ * @returns {Promise<Asset[]> } Assets.
72+ */
73+ export const getUnsavedAssets = async ( { draft, targetFolderPath } ) =>
74+ Promise . all (
75+ Object . entries ( draft . files ) . map ( async ( [ blobURL , { file, folder } ] ) =>
76+ convertFileItemToAsset ( { file, blobURL, folder, targetFolderPath } ) ,
77+ ) ,
78+ ) ;
79+
4080/**
4181 * Process a selected resource.
4282 * @param {object } args Arguments.
@@ -67,7 +107,12 @@ export const processResource = async ({ draft, resource, libraryConfig }) => {
67107
68108 const sha = await getGitHash ( file ) ;
69109 const { folder } = resource ;
70- const existingAsset = get ( allAssets ) . find ( ( a ) => a . sha === sha && equal ( a . folder , folder ) ) ;
110+
111+ // Check if the selected file has already been uploaded or is pending upload, otherwise
112+ // duplicate files lead to an `each_key_duplicate` error in Svelte
113+ const existingAsset = [ ...get ( allAssets ) , ...( await getUnsavedAssets ( { draft } ) ) ] . find (
114+ ( a ) => a . sha === sha && equal ( a . folder , folder ) ,
115+ ) ;
71116
72117 if ( existingAsset ) {
73118 // If the selected file has already been uploaded, use the existing asset instead of
0 commit comments