All files / lib/schemas results.js

100% Statements 6/6
100% Branches 2/2
100% Functions 4/4
100% Lines 5/5

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 104 105 106 107 108 109 110 111              18x                               36x             18x         36x                     14x                                                                                                                                
import { type } from 'arktype';
 
// Can't use $lib/ in $lib/schemas files, they're susceptible
// to be imported by non-Vite-managed pre-build scripts (e.g. JSON Schema generation)
import { mapValues } from '../utils.js';
import { MetadataErrors, MetadataRecord } from './metadata.js';
 
export const AnalyzedImage = type({
	id: ['string', '@', "ID de l'image"],
	fileId: ['string | null', '@', "ID du fichier source de l'image"],
	filename: ['string', '@', 'Nom du fichier utilisé pour cette image'],
	contentType: [
		'string',
		'@',
		"Type de contenu de l'image, au format MIME (exemple: image/jpeg)"
	],
	sequence: [
		'number > 0',
		'@',
		"Numéro de séquence de l'image dans l'archive .zip. Unique à l'entièreté de l'export"
	],
	numberInObservation: ['number > 0', '@', "Numéro de l'image dans l'observation"],
	metadata: MetadataRecord,
	metadataErrors: MetadataErrors.default(() => ({})),
	exportedAs: type({
		original: ['string', '@', "Chemin vers l'image originale"],
		cropped: ['string', '@', "Chemin vers l'image recadrée"]
	}).describe("Chemins dans l'archive .zip vers l'image exportée")
});
 
export const AnalyzedObservation = type({
	number: ['number > 0', '@', "Numéro de l'observation dans l'export"],
	label: ['string', '@', "Label de l'observation"],
	images: AnalyzedImage.array(),
	metadata: MetadataRecord,
	metadataErrors: MetadataErrors.default(() => ({})),
	protocolMetadata: MetadataRecord.describe(
		"Métadonnées définies par le protocole. Les clés de l'objet sont les identifiants des métadonnées, sans le préfixe qui identifie leur protocole de provenance"
	)
});
 
/**
 * @param {Record<string, Omit<import('$lib/database.js').MetadataValue, 'value'> & { value: null | import('$lib/schemas/metadata.js').RuntimeValue }>} values
 * @returns {typeof MetadataRecord.infer}
 */
export function toMetadataRecord(values) {
	return mapValues(values, ({ value, ...rest }) => ({
		value: value instanceof Date ? value.toISOString() : value,
		...rest
	}));
}
 
if (import.meta.vitest) {
	const { describe, it, expect } = import.meta.vitest;
	describe('toMetadataRecord', () => {
		it('should convert Date to ISO string', () => {
			const input = {
				meta1: {
					value: new Date('2024-01-01T12:00:00Z'),
					confidence: 0.9,
					manuallyModified: false,
					confirmed: true,
					alternatives: {
						alt1: 0.7
					}
				}
			};
			const output = toMetadataRecord(input);
			expect(output.meta1).toMatchObject({
				...input.meta1,
				value: '2024-01-01T12:00:00.000Z'
			});
		});
		it('should keep other types unchanged', () => {
			const input = {
				meta1: {
					value: 42,
					confidence: 0.8,
					manuallyModified: true,
					confirmed: false,
					alternatives: {
						alt1: 0.7
					}
				},
				meta2: {
					value: 'test',
					confidence: 1,
					manuallyModified: false,
					confirmed: false,
					alternatives: {
						alt1: 0.7
					}
				},
				meta3: {
					value: null,
					confidence: 0,
					manuallyModified: false,
					confirmed: false,
					alternatives: {
						alt1: 0.7
					}
				}
			};
			const output = toMetadataRecord(input);
			expect(output.meta1).toMatchObject(input.meta1);
			expect(output.meta2).toMatchObject(input.meta2);
			expect(output.meta3).toMatchObject(input.meta3);
		});
	});
}