All files / lib download.js

61.53% Statements 16/26
50% Branches 9/18
80% Functions 4/5
61.9% Lines 13/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                                      2x   2x   1x             2x 9x 9x 9x     7x 9x         2x 1x 1x     1x                                                                              
import YAML from 'yaml';
 
/**
 *
 * @param {BlobPart | string} content
 * @param {string} filename
 * @param {string} [contentType] defaults to 'text/plain' for strings and 'application/octet-stream' for blobs
 */
export function downloadAsFile(content, filename, contentType) {
	const blob =
		content instanceof Blob
			? content
			: new Blob([content], {
					type:
						contentType ??
						(typeof content === 'string' ? 'text/plain' : 'application/octet-stream')
				});
 
	const url = URL.createObjectURL(blob);
	const a = document.createElement('a');
	a.href = url;
	a.download = filename;
	a.click();
	URL.revokeObjectURL(url);
}
 
/**
 *
 * @template {string} Keys
 * @param { { [K in Keys]?: unknown } } object the object to serialize
 * @param {readonly Keys[]} ordering an array of keys in target order, for the top-level object
 * @param {'json' | 'yaml'} format
 * @param {string} schema the json schema URL
 */
export function stringifyWithToplevelOrdering(format, schema, object, ordering) {
	let keysOrder = [...ordering];
 
	if (format === 'json') {
		// @ts-expect-error
		keysOrder = ['$schema', ...keysOrder];
	}
 
	/**
	 * @param {*} _
	 * @param {*} value
	 */
	const reviver = (_, value) => {
		Iif (value === null) return value;
		Iif (Array.isArray(value)) return value;
		if (typeof value !== 'object') return value;
 
		// @ts-expect-error
		Eif (Object.keys(value).every((key) => keysOrder.includes(key))) {
			return Object.fromEntries(keysOrder.map((key) => [key, value[key]]));
		}
		return value;
	};
 
	if (format === 'yaml') {
		const yamled = YAML.stringify(object, reviver, 2);
		return `# yaml-language-server: $schema=${schema}\n\n${yamled}`;
	}
 
	return JSON.stringify({ $schema: schema, ...object }, reviver, 2);
}
 
if (import.meta.vitest) {
	const { test, expect } = import.meta.vitest;
	test('stringifyWithToplevelOrdering', () => {
		expect(
			stringifyWithToplevelOrdering(
				'json',
				'http://example.com/schema.json',
				{ a: 1, b: 2, c: 3 },
				['a', 'c', 'a', 'b']
			)
		).toMatchInlineSnapshot(`
			"{
			  "$schema": "http://example.com/schema.json",
			  "a": 1,
			  "c": 3,
			  "b": 2
			}"
		`);
 
		expect(
			stringifyWithToplevelOrdering(
				'yaml',
				'http://example.com/schema.json',
				{ a: 1, b: 2, c: 3 },
				['a', 'c', 'a', 'b']
			)
		).toMatchInlineSnapshot(`
			"# yaml-language-server: $schema=http://example.com/schema.json
 
			a: 1
			c: 3
			b: 2
			"
		`);
	});
}