Skip to content

Commit 0486bda

Browse files
committed
Refactor
1 parent 15dabc6 commit 0486bda

8 files changed

Lines changed: 142 additions & 18 deletions

File tree

src/lib/components/assets/shared/info-panel.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
</section>
140140
<section>
141141
<h4>{$_('used_in')}</h4>
142-
{#each usedEntries as entry (entry.sha)}
142+
{#each usedEntries as entry (entry.id)}
143143
{#await sleep() then}
144144
{#each getAssociatedCollections(entry) as collection (collection.name)}
145145
{#key $appLocale}

src/lib/services/backends/gitea.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,10 @@ const commitChanges = async (changes, options) => {
486486
const date = new Date().toJSON();
487487

488488
const files = await Promise.all(
489-
changes.map(async ({ action, path, previousPath, data = '', base64 }) => ({
489+
changes.map(async ({ action, path, previousPath, data = '' }) => ({
490490
operation: action === 'move' ? 'update' : action,
491491
path,
492-
content: base64 ?? (await encodeBase64(data)),
492+
content: await encodeBase64(data),
493493
from_path: previousPath,
494494
})),
495495
);

src/lib/services/backends/github.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,9 @@ const commitChanges = async (changes, options) => {
551551
const additions = await Promise.all(
552552
changes
553553
.filter(({ action }) => ['create', 'update', 'move'].includes(action))
554-
.map(async ({ path, data, base64 }) => ({
554+
.map(async ({ path, data }) => ({
555555
path,
556-
contents: base64 ?? (await encodeBase64(data ?? '')),
556+
contents: await encodeBase64(data ?? ''),
557557
})),
558558
);
559559

src/lib/services/backends/gitlab.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -689,10 +689,10 @@ const commitChanges = async (changes, options) => {
689689
const { owner, repo, branch } = repository;
690690

691691
const actions = await Promise.all(
692-
changes.map(async ({ action, path, previousPath, data = '', base64 }) => ({
692+
changes.map(async ({ action, path, previousPath, data = '' }) => ({
693693
action,
694-
content: base64 ?? (typeof data !== 'string' ? await encodeBase64(data) : data),
695-
encoding: base64 || typeof data !== 'string' ? 'base64' : 'text',
694+
content: typeof data === 'string' ? data : await encodeBase64(data),
695+
encoding: typeof data === 'string' ? 'text' : 'base64',
696696
file_path: path,
697697
previous_path: previousPath,
698698
})),

src/lib/services/backends/shared/fetch.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ const getFileList = async ({ metaDB, lastHash, cachedFileEntries, fetchFileList
127127
* Restore cached text and commit info to `allFiles` array.
128128
* @param {object} args Arguments.
129129
* @param {BaseFileListItem[]} args.allFiles The list of all files.
130-
* @param {Record<string, BaseFileListItemProps>} args.cachedFiles Cached files object.
130+
* @param {RepositoryContentsMap} args.cachedFiles Cached files object.
131131
*/
132132
const restoreCachedFileData = ({ allFiles, cachedFiles }) => {
133133
allFiles.forEach(({ sha, path }, index) => {
@@ -178,7 +178,7 @@ const updateStores = ({ entries, assets, configFiles, errors = [] }) => {
178178
* @param {object} args Arguments.
179179
* @param {IndexedDB} args.cacheDB The cache database instance.
180180
* @param {BaseFileListItem[]} args.allFiles List of all files in the repository.
181-
* @param {Record<string, BaseFileListItemProps>} args.cachedFiles Cached files object.
181+
* @param {RepositoryContentsMap} args.cachedFiles Cached files object.
182182
* @param {BaseFileListItem[]} args.fetchingFiles List of files being fetched.
183183
* @param {RepositoryContentsMap} args.fetchedFileMap Map of newly fetched file data.
184184
*/
@@ -245,6 +245,7 @@ export const fetchAndParseFiles = async ({
245245
}
246246

247247
const { entryFiles, assetFiles, configFiles, allFiles } = fileList;
248+
/** @type {RepositoryContentsMap} */
248249
const cachedFiles = Object.fromEntries(cachedFileEntries);
249250

250251
restoreCachedFileData({ allFiles, cachedFiles });

src/lib/services/utils/file.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,23 @@ export const resolvePath = (path) => {
183183
return createPath(segments);
184184
};
185185

186+
/**
187+
* Get the Blob object from the given file or blob input. If the input is a string, it is treated as
188+
* the file content and converted to a Blob with `text/plain` MIME type.
189+
* @param {File | Blob | string} input File or Blob object, or a string representing the file
190+
* content.
191+
* @returns {Blob} Blob object representing the file.
192+
*/
193+
export const getBlob = (input) =>
194+
typeof input === 'string' ? new Blob([input], { type: 'text/plain' }) : input;
195+
186196
/**
187197
* Get the size of the given file or blob.
188198
* @param {File | Blob | string} input File or Blob object, or a string representing the file
189199
* content.
190200
* @returns {number} Size of the file in bytes.
191201
*/
192-
export const getFileSize = (input) => {
193-
const file = typeof input === 'string' ? new Blob([input], { type: 'text/plain' }) : input;
194-
195-
return file.size;
196-
};
202+
export const getFileSize = (input) => getBlob(input).size;
197203

198204
/**
199205
* Get the Git object ID (SHA-1 hash) of the given file or blob.
@@ -204,7 +210,7 @@ export const getFileSize = (input) => {
204210
* @see https://github.com/Richienb/git-hash-object/blob/master/index.js
205211
*/
206212
export const getGitHash = async (input) => {
207-
const file = typeof input === 'string' ? new Blob([input], { type: 'text/plain' }) : input;
213+
const file = getBlob(input);
208214
const buffer = await file.arrayBuffer();
209215

210216
return getHash(new Blob([`blob ${buffer.byteLength}\0`, buffer]));

src/lib/services/utils/file.spec.js

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
/* cSpell:disable */
22

33
import { describe, expect, test } from 'vitest';
4-
import { encodeFilePath, formatFileName, getFileSize, getGitHash } from '$lib/services/utils/file';
4+
import {
5+
encodeFilePath,
6+
formatFileName,
7+
getBlob,
8+
getFileSize,
9+
getGitHash,
10+
} from '$lib/services/utils/file';
511

612
describe('Test encodeFilePath()', () => {
713
test('Encode', () => {
@@ -137,6 +143,118 @@ describe('Test formatFileName()', () => {
137143
});
138144
});
139145

146+
describe('Test getBlob()', () => {
147+
test('Convert string to Blob', () => {
148+
// Test with a simple string
149+
const content = 'hello world';
150+
const result = getBlob(content);
151+
152+
expect(result).toBeInstanceOf(Blob);
153+
expect(result.size).toBe(11); // "hello world" is 11 bytes
154+
expect(result.type).toBe('text/plain');
155+
});
156+
157+
test('Convert empty string to Blob', () => {
158+
// Test with empty string
159+
const result = getBlob('');
160+
161+
expect(result).toBeInstanceOf(Blob);
162+
expect(result.size).toBe(0);
163+
expect(result.type).toBe('text/plain');
164+
});
165+
166+
test('Convert UTF-8 string to Blob', () => {
167+
// Test with Unicode characters
168+
const content = '私の画像'; // Japanese characters
169+
const result = getBlob(content);
170+
171+
expect(result).toBeInstanceOf(Blob);
172+
expect(result.type).toBe('text/plain');
173+
expect(result.size).toBeGreaterThan(content.length); // More bytes than characters
174+
});
175+
176+
test('Return File object unchanged', () => {
177+
// Test with a File object - should return it unchanged
178+
const content = 'hello world\n';
179+
const file = new File([content], 'test.txt', { type: 'text/plain' });
180+
const result = getBlob(file);
181+
182+
expect(result).toBe(file); // Should return the same File object
183+
expect(result).toBeInstanceOf(File);
184+
expect(result.size).toBe(12);
185+
expect(result.type).toBe('text/plain');
186+
});
187+
188+
test('Return Blob object unchanged', () => {
189+
// Test with a Blob object - should return it unchanged
190+
const content = 'test content';
191+
const blob = new Blob([content], { type: 'application/json' });
192+
const result = getBlob(blob);
193+
194+
expect(result).toBe(blob); // Should return the same Blob object
195+
expect(result).toBeInstanceOf(Blob);
196+
expect(result.size).toBe(12);
197+
expect(result.type).toBe('application/json');
198+
});
199+
200+
test('Convert JSON string to Blob', () => {
201+
// Test with JSON content
202+
const jsonContent = JSON.stringify({ name: 'test', value: 123 });
203+
const result = getBlob(jsonContent);
204+
205+
expect(result).toBeInstanceOf(Blob);
206+
expect(result.type).toBe('text/plain');
207+
expect(result.size).toBe(jsonContent.length);
208+
});
209+
210+
test('Convert large string to Blob', () => {
211+
// Test with larger content
212+
const largeContent = 'a'.repeat(10000);
213+
const result = getBlob(largeContent);
214+
215+
expect(result).toBeInstanceOf(Blob);
216+
expect(result.type).toBe('text/plain');
217+
expect(result.size).toBe(10000);
218+
});
219+
220+
test('Convert string with newlines to Blob', () => {
221+
// Test with various newline characters
222+
const content1 = 'line1\nline2'; // Unix newline
223+
const content2 = 'line1\r\nline2'; // Windows newline
224+
const content3 = 'line1\rline2'; // Old Mac newline
225+
const result1 = getBlob(content1);
226+
const result2 = getBlob(content2);
227+
const result3 = getBlob(content3);
228+
229+
expect(result1.size).toBe(11); // 11 bytes
230+
expect(result2.size).toBe(12); // 12 bytes (extra \r)
231+
expect(result3.size).toBe(11); // 11 bytes
232+
expect(result1.type).toBe('text/plain');
233+
expect(result2.type).toBe('text/plain');
234+
expect(result3.type).toBe('text/plain');
235+
});
236+
237+
test('Blob can be read back as text', async () => {
238+
// Test that the created Blob can be read back as text
239+
const originalContent = 'hello world test';
240+
const blob = getBlob(originalContent);
241+
const readBackContent = await blob.text();
242+
243+
expect(readBackContent).toBe(originalContent);
244+
});
245+
246+
test('Binary Blob remains unchanged', () => {
247+
// Test with binary content in a Blob
248+
const binaryData = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0xff]);
249+
const binaryBlob = new Blob([binaryData], { type: 'application/octet-stream' });
250+
const result = getBlob(binaryBlob);
251+
252+
expect(result).toBe(binaryBlob); // Should return the same Blob object
253+
expect(result.size).toBe(5);
254+
expect(result.type).toBe('application/octet-stream');
255+
});
256+
});
257+
140258
describe('Test getFileSize()', () => {
141259
test('Get size of string content', () => {
142260
// Test with a simple string

src/lib/types/private.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,6 @@
579579
* `action` is `move`.
580580
* @property {string} [slug] Entry slug or `undefined` for an asset.
581581
* @property {string | File} [data] File data.
582-
* @property {string} [base64] Base64 of the data.
583582
*/
584583

585584
/**

0 commit comments

Comments
 (0)