@usecds/server 0.0.0-stage → 0.1.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/LICENSE +201 -0
- package/dist/core/content-report.d.ts +37 -0
- package/dist/core/content-report.js +306 -0
- package/dist/core/content-report.js.map +1 -0
- package/dist/core/content-types.d.ts +40 -0
- package/dist/core/content-types.js +27 -0
- package/dist/core/content-types.js.map +1 -0
- package/dist/core/jsonld.d.ts +33 -0
- package/dist/core/jsonld.js +94 -0
- package/dist/core/jsonld.js.map +1 -0
- package/dist/core/media-metadata.d.ts +20 -0
- package/dist/core/media-metadata.js +53 -0
- package/dist/core/media-metadata.js.map +1 -0
- package/dist/core/media-names.d.ts +9 -0
- package/dist/core/media-names.js +58 -0
- package/dist/core/media-names.js.map +1 -0
- package/dist/core/menu.d.ts +33 -0
- package/dist/core/menu.js +89 -0
- package/dist/core/menu.js.map +1 -0
- package/dist/core/publisher.d.ts +77 -0
- package/dist/core/publisher.js +261 -0
- package/dist/core/publisher.js.map +1 -0
- package/dist/core/report.d.ts +54 -0
- package/dist/core/report.js +132 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/site.d.ts +37 -0
- package/dist/core/site.js +96 -0
- package/dist/core/site.js.map +1 -0
- package/dist/core/storage-report.d.ts +44 -0
- package/dist/core/storage-report.js +112 -0
- package/dist/core/storage-report.js.map +1 -0
- package/dist/core/targets.d.ts +63 -0
- package/dist/core/targets.js +213 -0
- package/dist/core/targets.js.map +1 -0
- package/dist/core/translations.d.ts +41 -0
- package/dist/core/translations.js +125 -0
- package/dist/core/translations.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/sources/fixture.d.ts +9 -0
- package/dist/sources/fixture.js +79 -0
- package/dist/sources/fixture.js.map +1 -0
- package/dist/storage/filesystem.d.ts +23 -0
- package/dist/storage/filesystem.js +125 -0
- package/dist/storage/filesystem.js.map +1 -0
- package/dist/types.d.ts +223 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +17 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +21 -0
- package/dist/validation.js +100 -0
- package/dist/validation.js.map +1 -0
- package/package.json +28 -3
- package/schemas/v1/block.json +31 -0
- package/schemas/v1/channel-manifest.json +23 -0
- package/schemas/v1/collection.json +89 -0
- package/schemas/v1/jsonld.json +19 -0
- package/schemas/v1/media-metadata.json +41 -0
- package/schemas/v1/menu.json +21 -0
- package/schemas/v1/page.json +12 -0
- package/schemas/v1/release-manifest.json +82 -0
- package/schemas/v1/route.json +24 -0
- package/schemas/v1/target.json +98 -0
- package/README.md +0 -3
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ObjectStore } from "../types.js";
|
|
2
|
+
export interface StoredFile {
|
|
3
|
+
kind: "object" | "media";
|
|
4
|
+
hash: string;
|
|
5
|
+
file: string;
|
|
6
|
+
bytes: number | null;
|
|
7
|
+
}
|
|
8
|
+
export interface ReleaseDiff {
|
|
9
|
+
previousReleaseId: string;
|
|
10
|
+
added: string[];
|
|
11
|
+
removed: string[];
|
|
12
|
+
shared: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ReleaseUsage {
|
|
15
|
+
releaseId: string;
|
|
16
|
+
channels: string[];
|
|
17
|
+
objects: number;
|
|
18
|
+
media: number;
|
|
19
|
+
bytes: number;
|
|
20
|
+
uniqueBytes: number;
|
|
21
|
+
missing: string[];
|
|
22
|
+
diff: ReleaseDiff | null;
|
|
23
|
+
}
|
|
24
|
+
export interface StorageReport {
|
|
25
|
+
releases: ReleaseUsage[];
|
|
26
|
+
channels: Record<string, {
|
|
27
|
+
releaseId: string;
|
|
28
|
+
retained: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
totals: {
|
|
31
|
+
objects: number;
|
|
32
|
+
media: number;
|
|
33
|
+
bytes: number;
|
|
34
|
+
};
|
|
35
|
+
orphans: {
|
|
36
|
+
files: StoredFile[];
|
|
37
|
+
bytes: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walks the store and reports per-release usage, release-to-release diffs,
|
|
42
|
+
* channel pointers and orphaned files. Read-only.
|
|
43
|
+
*/
|
|
44
|
+
export declare function analyzeStorage(store: ObjectStore): Promise<StorageReport>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks the store and reports per-release usage, release-to-release diffs,
|
|
3
|
+
* channel pointers and orphaned files. Read-only.
|
|
4
|
+
*/
|
|
5
|
+
export async function analyzeStorage(store) {
|
|
6
|
+
// 1. Inventory of stored files
|
|
7
|
+
const files = new Map(); // keyed by file path
|
|
8
|
+
const mediaFilesByHash = new Map();
|
|
9
|
+
for (const hash of await store.listObjects()) {
|
|
10
|
+
const file = `objects/${hash}.json`;
|
|
11
|
+
files.set(file, { kind: "object", hash, file, bytes: await store.objectSize(hash) });
|
|
12
|
+
}
|
|
13
|
+
for (const filename of await store.listMedia()) {
|
|
14
|
+
// Filename is <hash>.<ext>
|
|
15
|
+
const hash = filename.split(".")[0];
|
|
16
|
+
const file = `media/${filename}`;
|
|
17
|
+
files.set(file, { kind: "media", hash, file, bytes: await store.mediaSize(filename) });
|
|
18
|
+
mediaFilesByHash.set(hash, [...(mediaFilesByHash.get(hash) ?? []), file]);
|
|
19
|
+
}
|
|
20
|
+
// 2. Channel pointers
|
|
21
|
+
const channels = {};
|
|
22
|
+
const releaseIds = (await store.listReleases()).sort();
|
|
23
|
+
for (const channel of await store.listChannels()) {
|
|
24
|
+
const manifest = await store.readChannelManifest(channel);
|
|
25
|
+
if (manifest) {
|
|
26
|
+
channels[channel] = { releaseId: manifest.releaseId, retained: releaseIds.includes(manifest.releaseId) };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 3. Files referenced by each retained release
|
|
30
|
+
const referencesByRelease = new Map();
|
|
31
|
+
for (const releaseId of releaseIds) {
|
|
32
|
+
const manifest = await store.readRelease(releaseId);
|
|
33
|
+
if (!manifest)
|
|
34
|
+
continue;
|
|
35
|
+
const referenced = new Set();
|
|
36
|
+
for (const col of Object.values(manifest.collections)) {
|
|
37
|
+
referenced.add(`objects/${col.hash}.json`);
|
|
38
|
+
}
|
|
39
|
+
for (const [virtualPath, med] of Object.entries(manifest.media)) {
|
|
40
|
+
const stored = mediaFilesByHash.get(med.hash);
|
|
41
|
+
if (stored) {
|
|
42
|
+
stored.forEach((f) => referenced.add(f));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const ext = virtualPath.includes(".") ? virtualPath.substring(virtualPath.lastIndexOf(".")) : "";
|
|
46
|
+
referenced.add(`media/${med.hash}${ext}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
referencesByRelease.set(releaseId, { files: referenced, manifest });
|
|
50
|
+
}
|
|
51
|
+
const referenceCount = new Map();
|
|
52
|
+
for (const { files: referenced } of referencesByRelease.values()) {
|
|
53
|
+
referenced.forEach((f) => referenceCount.set(f, (referenceCount.get(f) ?? 0) + 1));
|
|
54
|
+
}
|
|
55
|
+
// 4. Per-release usage and diff against the previous retained release
|
|
56
|
+
const releases = [];
|
|
57
|
+
let previous = null;
|
|
58
|
+
for (const [releaseId, { files: referenced }] of referencesByRelease) {
|
|
59
|
+
const usage = {
|
|
60
|
+
releaseId,
|
|
61
|
+
channels: Object.keys(channels).filter((c) => channels[c].releaseId === releaseId),
|
|
62
|
+
objects: 0,
|
|
63
|
+
media: 0,
|
|
64
|
+
bytes: 0,
|
|
65
|
+
uniqueBytes: 0,
|
|
66
|
+
missing: [],
|
|
67
|
+
diff: null
|
|
68
|
+
};
|
|
69
|
+
for (const file of referenced) {
|
|
70
|
+
const stored = files.get(file);
|
|
71
|
+
if (!stored || stored.bytes === null) {
|
|
72
|
+
usage.missing.push(file);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (stored.kind === "object")
|
|
76
|
+
usage.objects++;
|
|
77
|
+
else
|
|
78
|
+
usage.media++;
|
|
79
|
+
usage.bytes += stored.bytes;
|
|
80
|
+
if (referenceCount.get(file) === 1)
|
|
81
|
+
usage.uniqueBytes += stored.bytes;
|
|
82
|
+
}
|
|
83
|
+
if (previous) {
|
|
84
|
+
const prevFiles = previous.files;
|
|
85
|
+
usage.diff = {
|
|
86
|
+
previousReleaseId: previous.releaseId,
|
|
87
|
+
added: [...referenced].filter((f) => !prevFiles.has(f)),
|
|
88
|
+
removed: [...prevFiles].filter((f) => !referenced.has(f)),
|
|
89
|
+
shared: [...referenced].filter((f) => prevFiles.has(f)).length
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
releases.push(usage);
|
|
93
|
+
previous = { releaseId, files: referenced };
|
|
94
|
+
}
|
|
95
|
+
// 5. Totals and orphans
|
|
96
|
+
const all = [...files.values()];
|
|
97
|
+
const orphanFiles = all.filter((f) => !referenceCount.has(f.file));
|
|
98
|
+
return {
|
|
99
|
+
releases,
|
|
100
|
+
channels,
|
|
101
|
+
totals: {
|
|
102
|
+
objects: all.filter((f) => f.kind === "object").length,
|
|
103
|
+
media: all.filter((f) => f.kind === "media").length,
|
|
104
|
+
bytes: sum(all)
|
|
105
|
+
},
|
|
106
|
+
orphans: { files: orphanFiles, bytes: sum(orphanFiles) }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function sum(files) {
|
|
110
|
+
return files.reduce((total, f) => total + (f.bytes ?? 0), 0);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=storage-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-report.js","sourceRoot":"","sources":["../../src/core/storage-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const DEFAULT_TARGET_ID = "default";
|
|
2
|
+
export declare const RECOMMENDED_MAX_TARGETS = 8;
|
|
3
|
+
export interface CollectionRules {
|
|
4
|
+
localized?: object;
|
|
5
|
+
fields?: object;
|
|
6
|
+
}
|
|
7
|
+
export interface CollectionRequirements extends CollectionRules {
|
|
8
|
+
minItems?: number;
|
|
9
|
+
presets?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface MediaPreset {
|
|
12
|
+
aspect?: string;
|
|
13
|
+
fit?: "fill" | "fit";
|
|
14
|
+
widths: Record<string, number>;
|
|
15
|
+
formats?: ("avif" | "webp" | "jpeg" | "png")[];
|
|
16
|
+
quality?: number;
|
|
17
|
+
lossless?: boolean;
|
|
18
|
+
background?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TargetDefinition {
|
|
21
|
+
id: string;
|
|
22
|
+
scope?: string[];
|
|
23
|
+
locales?: {
|
|
24
|
+
required?: string[];
|
|
25
|
+
minCompleteness?: number;
|
|
26
|
+
maxStale?: number;
|
|
27
|
+
};
|
|
28
|
+
collections?: Record<string, CollectionRequirements>;
|
|
29
|
+
items?: {
|
|
30
|
+
collection: string;
|
|
31
|
+
key: string;
|
|
32
|
+
}[];
|
|
33
|
+
recommendations?: Record<string, CollectionRules>;
|
|
34
|
+
media?: {
|
|
35
|
+
breakpoints?: Record<string, number>;
|
|
36
|
+
dpr?: number[];
|
|
37
|
+
presets?: Record<string, MediaPreset>;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Used when no default target is provided.
|
|
42
|
+
*/
|
|
43
|
+
export declare const BUILTIN_DEFAULT_TARGET: TargetDefinition;
|
|
44
|
+
export interface ResolvedTargets {
|
|
45
|
+
defaultTarget: TargetDefinition;
|
|
46
|
+
named: TargetDefinition[];
|
|
47
|
+
effective: Record<string, TargetDefinition>;
|
|
48
|
+
warnings: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Loads all *.json target definitions from a folder. default.json is the default target.
|
|
52
|
+
*/
|
|
53
|
+
export declare function loadTargets(dir: string): Promise<TargetDefinition[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Validates the given definitions, picks the default target (built-in if none) and
|
|
56
|
+
* computes each named target's effective definition (default merged with its own).
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveTargets(definitions: TargetDefinition[]): ResolvedTargets;
|
|
59
|
+
/**
|
|
60
|
+
* Additive merge: lists are combined, thresholds take the stricter value, schemas are
|
|
61
|
+
* combined with allOf (both must pass). Nothing is overwritten. Scope is the named target's own.
|
|
62
|
+
*/
|
|
63
|
+
export declare function mergeTargets(base: TargetDefinition, own: TargetDefinition): TargetDefinition;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { deterministicStringify } from "../utils.js";
|
|
4
|
+
import { validateTargetDefinition } from "../validation.js";
|
|
5
|
+
export const DEFAULT_TARGET_ID = "default";
|
|
6
|
+
export const RECOMMENDED_MAX_TARGETS = 8;
|
|
7
|
+
/**
|
|
8
|
+
* Used when no default target is provided.
|
|
9
|
+
*/
|
|
10
|
+
export const BUILTIN_DEFAULT_TARGET = {
|
|
11
|
+
id: DEFAULT_TARGET_ID,
|
|
12
|
+
recommendations: {
|
|
13
|
+
_media: {
|
|
14
|
+
localized: {
|
|
15
|
+
type: "object",
|
|
16
|
+
required: ["alt", "description"],
|
|
17
|
+
properties: {
|
|
18
|
+
alt: { type: "string", minLength: 1, maxLength: 125 },
|
|
19
|
+
description: { type: "string", minLength: 50, maxLength: 300 }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
_pages: {
|
|
24
|
+
localized: {
|
|
25
|
+
type: "object",
|
|
26
|
+
required: ["title", "description"],
|
|
27
|
+
properties: {
|
|
28
|
+
title: { type: "string", minLength: 1, maxLength: 60 },
|
|
29
|
+
description: { type: "string", minLength: 50, maxLength: 160 }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Loads all *.json target definitions from a folder. default.json is the default target.
|
|
37
|
+
*/
|
|
38
|
+
export async function loadTargets(dir) {
|
|
39
|
+
const files = (await fs.readdir(dir)).filter((f) => f.endsWith(".json")).sort();
|
|
40
|
+
const targets = [];
|
|
41
|
+
for (const file of files) {
|
|
42
|
+
const target = JSON.parse(await fs.readFile(path.join(dir, file), "utf-8"));
|
|
43
|
+
validateTargetDefinition(target);
|
|
44
|
+
const expectedDefault = file === `${DEFAULT_TARGET_ID}.json`;
|
|
45
|
+
if (expectedDefault !== (target.id === DEFAULT_TARGET_ID)) {
|
|
46
|
+
throw new Error(`Target file ${file}: only default.json may (and must) use the id "${DEFAULT_TARGET_ID}"`);
|
|
47
|
+
}
|
|
48
|
+
targets.push(target);
|
|
49
|
+
}
|
|
50
|
+
return targets;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validates the given definitions, picks the default target (built-in if none) and
|
|
54
|
+
* computes each named target's effective definition (default merged with its own).
|
|
55
|
+
*/
|
|
56
|
+
export function resolveTargets(definitions) {
|
|
57
|
+
const warnings = [];
|
|
58
|
+
const seen = new Set();
|
|
59
|
+
for (const def of definitions) {
|
|
60
|
+
validateTargetDefinition(def);
|
|
61
|
+
if (seen.has(def.id))
|
|
62
|
+
throw new Error(`Duplicate target id: ${def.id}`);
|
|
63
|
+
seen.add(def.id);
|
|
64
|
+
if (def.id !== DEFAULT_TARGET_ID)
|
|
65
|
+
checkOwnScope(def);
|
|
66
|
+
}
|
|
67
|
+
const defaultTarget = definitions.find((d) => d.id === DEFAULT_TARGET_ID) ?? BUILTIN_DEFAULT_TARGET;
|
|
68
|
+
if (defaultTarget.scope) {
|
|
69
|
+
throw new Error(`The default target applies to everything and can't declare a scope`);
|
|
70
|
+
}
|
|
71
|
+
const named = definitions.filter((d) => d.id !== DEFAULT_TARGET_ID);
|
|
72
|
+
if (named.length > RECOMMENDED_MAX_TARGETS) {
|
|
73
|
+
warnings.push(`${named.length} named targets; the recommended maximum is ${RECOMMENDED_MAX_TARGETS}`);
|
|
74
|
+
}
|
|
75
|
+
checkPresetConflicts([defaultTarget, ...named]);
|
|
76
|
+
checkBreakpoints([defaultTarget, ...named]);
|
|
77
|
+
const effective = { [DEFAULT_TARGET_ID]: defaultTarget };
|
|
78
|
+
for (const target of named) {
|
|
79
|
+
effective[target.id] = mergeTargets(defaultTarget, target);
|
|
80
|
+
}
|
|
81
|
+
return { defaultTarget, named, effective, warnings };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Additive merge: lists are combined, thresholds take the stricter value, schemas are
|
|
85
|
+
* combined with allOf (both must pass). Nothing is overwritten. Scope is the named target's own.
|
|
86
|
+
*/
|
|
87
|
+
export function mergeTargets(base, own) {
|
|
88
|
+
const merged = { id: own.id };
|
|
89
|
+
if (own.scope)
|
|
90
|
+
merged.scope = [...own.scope];
|
|
91
|
+
const locales = {
|
|
92
|
+
required: union(base.locales?.required, own.locales?.required),
|
|
93
|
+
minCompleteness: stricter(base.locales?.minCompleteness, own.locales?.minCompleteness, Math.max),
|
|
94
|
+
maxStale: stricter(base.locales?.maxStale, own.locales?.maxStale, Math.min)
|
|
95
|
+
};
|
|
96
|
+
if (locales.required || locales.minCompleteness !== undefined || locales.maxStale !== undefined) {
|
|
97
|
+
merged.locales = dropUndefined(locales);
|
|
98
|
+
}
|
|
99
|
+
const collections = mergeRecords(base.collections, own.collections, (a, b) => dropUndefined({
|
|
100
|
+
minItems: stricter(a.minItems, b.minItems, Math.max),
|
|
101
|
+
localized: allOf(a.localized, b.localized),
|
|
102
|
+
fields: allOf(a.fields, b.fields),
|
|
103
|
+
presets: union(a.presets, b.presets)
|
|
104
|
+
}));
|
|
105
|
+
if (collections)
|
|
106
|
+
merged.collections = collections;
|
|
107
|
+
const items = unionBy([...(base.items ?? []), ...(own.items ?? [])], (i) => `${i.collection}\u0000${i.key}`);
|
|
108
|
+
if (items.length)
|
|
109
|
+
merged.items = items;
|
|
110
|
+
const recommendations = mergeRecords(base.recommendations, own.recommendations, (a, b) => dropUndefined({ localized: allOf(a.localized, b.localized), fields: allOf(a.fields, b.fields) }));
|
|
111
|
+
if (recommendations)
|
|
112
|
+
merged.recommendations = recommendations;
|
|
113
|
+
if (base.media || own.media) {
|
|
114
|
+
merged.media = dropUndefined({
|
|
115
|
+
breakpoints: base.media?.breakpoints || own.media?.breakpoints
|
|
116
|
+
? { ...base.media?.breakpoints, ...own.media?.breakpoints }
|
|
117
|
+
: undefined,
|
|
118
|
+
dpr: union(base.media?.dpr, own.media?.dpr)?.sort((x, y) => x - y),
|
|
119
|
+
presets: base.media?.presets || own.media?.presets ? { ...base.media?.presets, ...own.media?.presets } : undefined
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return merged;
|
|
123
|
+
}
|
|
124
|
+
// A named target's own requirements and recommendations must stay within its own scope
|
|
125
|
+
function checkOwnScope(target) {
|
|
126
|
+
if (!target.scope)
|
|
127
|
+
return;
|
|
128
|
+
const scope = new Set(target.scope);
|
|
129
|
+
const outside = [
|
|
130
|
+
...Object.keys(target.collections ?? {}),
|
|
131
|
+
...Object.keys(target.recommendations ?? {}),
|
|
132
|
+
...(target.items ?? []).map((i) => i.collection)
|
|
133
|
+
].filter((c) => !scope.has(c));
|
|
134
|
+
if (outside.length) {
|
|
135
|
+
throw new Error(`Target ${target.id} declares rules outside its scope: ${[...new Set(outside)].join(", ")}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// All variants land in one release, so a preset name must mean the same thing in every target
|
|
139
|
+
function checkPresetConflicts(targets) {
|
|
140
|
+
const presets = new Map();
|
|
141
|
+
for (const target of targets) {
|
|
142
|
+
for (const [name, preset] of Object.entries(target.media?.presets ?? {})) {
|
|
143
|
+
const definition = deterministicStringify(preset);
|
|
144
|
+
const existing = presets.get(name);
|
|
145
|
+
if (existing && existing.definition !== definition) {
|
|
146
|
+
throw new Error(`Preset "${name}" is defined differently in targets ${existing.target} and ${target.id}`);
|
|
147
|
+
}
|
|
148
|
+
presets.set(name, { target: target.id, definition });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Breakpoints are shared like presets: one name, one width. Presets may only use declared breakpoints.
|
|
153
|
+
function checkBreakpoints(targets) {
|
|
154
|
+
const widths = new Map();
|
|
155
|
+
for (const target of targets) {
|
|
156
|
+
for (const [name, minWidth] of Object.entries(target.media?.breakpoints ?? {})) {
|
|
157
|
+
const existing = widths.get(name);
|
|
158
|
+
if (existing && existing.minWidth !== minWidth) {
|
|
159
|
+
throw new Error(`Breakpoint "${name}" is defined differently in targets ${existing.target} and ${target.id}`);
|
|
160
|
+
}
|
|
161
|
+
widths.set(name, { target: target.id, minWidth });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
for (const target of targets) {
|
|
165
|
+
for (const [presetName, preset] of Object.entries(target.media?.presets ?? {})) {
|
|
166
|
+
for (const breakpoint of Object.keys(preset.widths)) {
|
|
167
|
+
if (!widths.has(breakpoint)) {
|
|
168
|
+
throw new Error(`Preset "${presetName}" in target ${target.id} uses unknown breakpoint "${breakpoint}"`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function union(a, b) {
|
|
175
|
+
if (!a && !b)
|
|
176
|
+
return undefined;
|
|
177
|
+
return [...new Set([...(a ?? []), ...(b ?? [])])];
|
|
178
|
+
}
|
|
179
|
+
function unionBy(list, key) {
|
|
180
|
+
const map = new Map();
|
|
181
|
+
for (const item of list)
|
|
182
|
+
map.set(key(item), item);
|
|
183
|
+
return [...map.values()];
|
|
184
|
+
}
|
|
185
|
+
function stricter(a, b, pick) {
|
|
186
|
+
if (a === undefined)
|
|
187
|
+
return b;
|
|
188
|
+
if (b === undefined)
|
|
189
|
+
return a;
|
|
190
|
+
return pick(a, b);
|
|
191
|
+
}
|
|
192
|
+
function allOf(a, b) {
|
|
193
|
+
if (!a)
|
|
194
|
+
return b;
|
|
195
|
+
if (!b)
|
|
196
|
+
return a;
|
|
197
|
+
if (deterministicStringify(a) === deterministicStringify(b))
|
|
198
|
+
return a;
|
|
199
|
+
return { allOf: [a, b] };
|
|
200
|
+
}
|
|
201
|
+
function mergeRecords(a, b, merge) {
|
|
202
|
+
if (!a && !b)
|
|
203
|
+
return undefined;
|
|
204
|
+
const result = { ...a };
|
|
205
|
+
for (const [key, value] of Object.entries(b ?? {})) {
|
|
206
|
+
result[key] = key in result ? merge(result[key], value) : value;
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
function dropUndefined(obj) {
|
|
211
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../src/core/targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CollectionItem, TranslationCounts, TranslationSummary } from "../types.js";
|
|
2
|
+
export declare const DEFAULT_SOURCE_LOCALE = "en";
|
|
3
|
+
export type SourceLocaleOrigin = "argument" | "source" | "inferred" | "fallback";
|
|
4
|
+
export interface TranslationIssue {
|
|
5
|
+
collection: string;
|
|
6
|
+
id: string;
|
|
7
|
+
locale: string;
|
|
8
|
+
field: string;
|
|
9
|
+
issue: "missing" | "stale";
|
|
10
|
+
}
|
|
11
|
+
export interface TranslationReport extends TranslationSummary {
|
|
12
|
+
sourceLocaleOrigin: SourceLocaleOrigin;
|
|
13
|
+
collections: Record<string, Record<string, TranslationCounts>>;
|
|
14
|
+
itemsWithoutSource: {
|
|
15
|
+
collection: string;
|
|
16
|
+
id: string;
|
|
17
|
+
}[];
|
|
18
|
+
issues: TranslationIssue[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Hash of a source text, as stored in _provenance translation markers (sourceHash).
|
|
22
|
+
*/
|
|
23
|
+
export declare function translationSourceHash(text: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Infers the source locale from _provenance translation markers: the locales of fields marked
|
|
26
|
+
* "original" plus all "from" locales. Returns undefined unless exactly one candidate exists.
|
|
27
|
+
*/
|
|
28
|
+
export declare function inferSourceLocale(collections: Record<string, CollectionItem[]>): string | undefined;
|
|
29
|
+
export type ItemLocales = (collection: string, item: CollectionItem) => string[] | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Measures translation completeness against the source locale.
|
|
32
|
+
*
|
|
33
|
+
* - Expected: every source-locale field whose value is a non-empty string. Other source values are ignored.
|
|
34
|
+
* - Missing: the translation is absent, null or "".
|
|
35
|
+
* - Stale: the marker's sourceHash differs from the current source text. Without a sourceHash,
|
|
36
|
+
* falls back to the previous release: source text changed but the translation didn't.
|
|
37
|
+
* - Items restricted by itemLocales are only measured in those locales, and skipped entirely
|
|
38
|
+
* if they aren't used in the source locale (their texts are originals, not translations).
|
|
39
|
+
*/
|
|
40
|
+
export declare function analyzeTranslations(collections: Record<string, CollectionItem[]>, sourceLocale: string, sourceLocaleOrigin: SourceLocaleOrigin, previous?: Record<string, CollectionItem[]>, itemLocales?: ItemLocales): TranslationReport;
|
|
41
|
+
export declare function toTranslationSummary(report: TranslationReport): TranslationSummary;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { sha256 } from "../utils.js";
|
|
2
|
+
export const DEFAULT_SOURCE_LOCALE = "en";
|
|
3
|
+
/**
|
|
4
|
+
* Hash of a source text, as stored in _provenance translation markers (sourceHash).
|
|
5
|
+
*/
|
|
6
|
+
export function translationSourceHash(text) {
|
|
7
|
+
return sha256(text);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Infers the source locale from _provenance translation markers: the locales of fields marked
|
|
11
|
+
* "original" plus all "from" locales. Returns undefined unless exactly one candidate exists.
|
|
12
|
+
*/
|
|
13
|
+
export function inferSourceLocale(collections) {
|
|
14
|
+
const candidates = new Set();
|
|
15
|
+
for (const items of Object.values(collections)) {
|
|
16
|
+
for (const item of items) {
|
|
17
|
+
for (const [locale, fields] of Object.entries(item._provenance?.translations ?? {})) {
|
|
18
|
+
for (const marker of Object.values(fields)) {
|
|
19
|
+
if (marker.status === "original")
|
|
20
|
+
candidates.add(locale);
|
|
21
|
+
if (marker.from)
|
|
22
|
+
candidates.add(marker.from);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return candidates.size === 1 ? [...candidates][0] : undefined;
|
|
28
|
+
}
|
|
29
|
+
const emptyCounts = () => ({ expected: 0, translated: 0, missing: 0, stale: 0, machine: 0 });
|
|
30
|
+
function addCounts(target, add) {
|
|
31
|
+
target.expected += add.expected;
|
|
32
|
+
target.translated += add.translated;
|
|
33
|
+
target.missing += add.missing;
|
|
34
|
+
target.stale += add.stale;
|
|
35
|
+
target.machine += add.machine;
|
|
36
|
+
}
|
|
37
|
+
const isEmpty = (value) => value === undefined || value === null || value === "";
|
|
38
|
+
/**
|
|
39
|
+
* Measures translation completeness against the source locale.
|
|
40
|
+
*
|
|
41
|
+
* - Expected: every source-locale field whose value is a non-empty string. Other source values are ignored.
|
|
42
|
+
* - Missing: the translation is absent, null or "".
|
|
43
|
+
* - Stale: the marker's sourceHash differs from the current source text. Without a sourceHash,
|
|
44
|
+
* falls back to the previous release: source text changed but the translation didn't.
|
|
45
|
+
* - Items restricted by itemLocales are only measured in those locales, and skipped entirely
|
|
46
|
+
* if they aren't used in the source locale (their texts are originals, not translations).
|
|
47
|
+
*/
|
|
48
|
+
export function analyzeTranslations(collections, sourceLocale, sourceLocaleOrigin, previous, itemLocales) {
|
|
49
|
+
const locales = new Set();
|
|
50
|
+
for (const items of Object.values(collections)) {
|
|
51
|
+
for (const item of items) {
|
|
52
|
+
Object.keys(item.translations).forEach((l) => locales.add(l));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
locales.delete(sourceLocale);
|
|
56
|
+
const targetLocales = [...locales].sort();
|
|
57
|
+
const report = {
|
|
58
|
+
sourceLocale,
|
|
59
|
+
sourceLocaleOrigin,
|
|
60
|
+
locales: Object.fromEntries(targetLocales.map((l) => [l, emptyCounts()])),
|
|
61
|
+
overall: emptyCounts(),
|
|
62
|
+
collections: {},
|
|
63
|
+
itemsWithoutSource: [],
|
|
64
|
+
issues: []
|
|
65
|
+
};
|
|
66
|
+
for (const [collection, items] of Object.entries(collections)) {
|
|
67
|
+
const perLocale = Object.fromEntries(targetLocales.map((l) => [l, emptyCounts()]));
|
|
68
|
+
report.collections[collection] = perLocale;
|
|
69
|
+
const previousById = new Map((previous?.[collection] ?? []).map((i) => [i.id, i]));
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
const usedIn = itemLocales?.(collection, item);
|
|
72
|
+
if (usedIn && !usedIn.includes(sourceLocale))
|
|
73
|
+
continue;
|
|
74
|
+
const sourceFields = item.translations[sourceLocale];
|
|
75
|
+
if (!sourceFields) {
|
|
76
|
+
report.itemsWithoutSource.push({ collection, id: item.id });
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const prevItem = previousById.get(item.id);
|
|
80
|
+
for (const [field, sourceValue] of Object.entries(sourceFields)) {
|
|
81
|
+
if (typeof sourceValue !== "string" || sourceValue.length === 0)
|
|
82
|
+
continue;
|
|
83
|
+
for (const locale of targetLocales) {
|
|
84
|
+
if (usedIn && !usedIn.includes(locale))
|
|
85
|
+
continue;
|
|
86
|
+
const counts = perLocale[locale];
|
|
87
|
+
counts.expected++;
|
|
88
|
+
const value = item.translations[locale]?.[field];
|
|
89
|
+
if (isEmpty(value)) {
|
|
90
|
+
counts.missing++;
|
|
91
|
+
report.issues.push({ collection, id: item.id, locale, field, issue: "missing" });
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
counts.translated++;
|
|
95
|
+
const marker = item._provenance?.translations?.[locale]?.[field];
|
|
96
|
+
if (marker?.status === "machine")
|
|
97
|
+
counts.machine++;
|
|
98
|
+
let stale = false;
|
|
99
|
+
if (marker?.sourceHash) {
|
|
100
|
+
const reference = item.translations[marker.from ?? sourceLocale]?.[field];
|
|
101
|
+
stale = typeof reference === "string" && translationSourceHash(reference) !== marker.sourceHash;
|
|
102
|
+
}
|
|
103
|
+
else if (prevItem) {
|
|
104
|
+
const prevSource = prevItem.translations[sourceLocale]?.[field];
|
|
105
|
+
const prevValue = prevItem.translations[locale]?.[field];
|
|
106
|
+
stale = typeof prevSource === "string" && prevSource !== sourceValue && prevValue === value;
|
|
107
|
+
}
|
|
108
|
+
if (stale) {
|
|
109
|
+
counts.stale++;
|
|
110
|
+
report.issues.push({ collection, id: item.id, locale, field, issue: "stale" });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const locale of targetLocales) {
|
|
116
|
+
addCounts(report.locales[locale], perLocale[locale]);
|
|
117
|
+
addCounts(report.overall, perLocale[locale]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return report;
|
|
121
|
+
}
|
|
122
|
+
export function toTranslationSummary(report) {
|
|
123
|
+
return { sourceLocale: report.sourceLocale, locales: report.locales, overall: report.overall };
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=translations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translations.js","sourceRoot":"","sources":["../../src/core/translations.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./utils.js";
|
|
3
|
+
export * from "./validation.js";
|
|
4
|
+
export { Publisher, PublisherConfig, PublishOptions, PublishArtifacts, PublishResult, PublishRequirementsError, GarbageCollectOptions, GarbageCollectResult } from "./core/publisher.js";
|
|
5
|
+
export * from "./core/storage-report.js";
|
|
6
|
+
export * from "./core/translations.js";
|
|
7
|
+
export * from "./core/targets.js";
|
|
8
|
+
export * from "./core/content-report.js";
|
|
9
|
+
export * from "./core/media-metadata.js";
|
|
10
|
+
export * from "./core/media-names.js";
|
|
11
|
+
export * from "./core/jsonld.js";
|
|
12
|
+
export * from "./core/site.js";
|
|
13
|
+
export * from "./core/menu.js";
|
|
14
|
+
export * from "./core/report.js";
|
|
15
|
+
export * from "./core/content-types.js";
|
|
16
|
+
export { FixtureSource } from "./sources/fixture.js";
|
|
17
|
+
export { FilesystemStore } from "./storage/filesystem.js";
|