lsr-text-catalog 0.1.2

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/dist/compiled/index.d.ts +12 -0
  4. package/dist/compiled/index.d.ts.map +1 -0
  5. package/dist/compiled/index.js +39 -0
  6. package/dist/compiled/index.js.map +1 -0
  7. package/dist/language.d.ts +4 -0
  8. package/dist/language.d.ts.map +1 -0
  9. package/dist/language.js +50 -0
  10. package/dist/language.js.map +1 -0
  11. package/dist/runtime/index.d.ts +17 -0
  12. package/dist/runtime/index.d.ts.map +1 -0
  13. package/dist/runtime/index.js +68 -0
  14. package/dist/runtime/index.js.map +1 -0
  15. package/dist/types.d.ts +37 -0
  16. package/dist/types.d.ts.map +1 -0
  17. package/dist/types.js +2 -0
  18. package/dist/types.js.map +1 -0
  19. package/dist/vite/index.d.ts +21 -0
  20. package/dist/vite/index.d.ts.map +1 -0
  21. package/dist/vite/index.js +559 -0
  22. package/dist/vite/index.js.map +1 -0
  23. package/dist/vite/manifest.d.ts +24 -0
  24. package/dist/vite/manifest.d.ts.map +1 -0
  25. package/dist/vite/manifest.js +110 -0
  26. package/dist/vite/manifest.js.map +1 -0
  27. package/dist/vite/transform.d.ts +5 -0
  28. package/dist/vite/transform.d.ts.map +1 -0
  29. package/dist/vite/transform.js +873 -0
  30. package/dist/vite/transform.js.map +1 -0
  31. package/dist/vite/types.d.ts +23 -0
  32. package/dist/vite/types.d.ts.map +1 -0
  33. package/dist/vite/types.js +2 -0
  34. package/dist/vite/types.js.map +1 -0
  35. package/package.json +99 -0
  36. package/src/compiled/index.ts +81 -0
  37. package/src/language.ts +62 -0
  38. package/src/runtime/index.ts +126 -0
  39. package/src/types.ts +55 -0
  40. package/src/vite/index.ts +642 -0
  41. package/src/vite/manifest.ts +158 -0
  42. package/src/vite/transform.ts +1228 -0
  43. package/src/vite/types.ts +27 -0
@@ -0,0 +1,110 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, realpathSync } from "node:fs";
3
+ import path from "node:path";
4
+ /** Byte-ordered compact UTF-8 JSON, matching PHP's unescaped Unicode/slash encoding. */
5
+ export function canonicalJson(value) {
6
+ if (Array.isArray(value))
7
+ return `[${value.map(canonicalJson).join(",")}]`;
8
+ if (value !== null && typeof value === "object") {
9
+ return `{${Object.keys(value)
10
+ .sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)))
11
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
12
+ .join(",")}}`;
13
+ }
14
+ const encoded = JSON.stringify(value);
15
+ if (encoded === undefined)
16
+ throw new Error("Catalog manifest contains a non-JSON value.");
17
+ return encoded;
18
+ }
19
+ const keyPattern = /^[a-z][a-zA-Z0-9]*(?:\.[a-z][a-zA-Z0-9]*)*$/u;
20
+ const digestPattern = /^[a-f0-9]{64}$/u;
21
+ function object(value, label) {
22
+ if (value === null || typeof value !== "object" || Array.isArray(value))
23
+ throw new Error(`Catalog ${label} must be an object.`);
24
+ return value;
25
+ }
26
+ function ascii(value, label) {
27
+ if (typeof value !== "string" || !/^[\x21-\x7e]+$/u.test(value))
28
+ throw new Error(`Catalog ${label} must be a nonempty ASCII string.`);
29
+ }
30
+ /** Read one complete generation; no legacy manifest or stale-artifact fallback is accepted. */
31
+ export function readCatalogManifest(directory, identity) {
32
+ const manifestFile = path.join(directory, "catalog.build.json");
33
+ const raw = object(JSON.parse(readFileSync(manifestFile, "utf8")), "manifest");
34
+ if (raw.formatVersion !== 1)
35
+ throw new Error(`Unsupported catalog formatVersion: ${String(raw.formatVersion)}.`);
36
+ ascii(raw.sourceLocale, "sourceLocale");
37
+ ascii(raw.domain, "domain");
38
+ if (!Array.isArray(raw.locales) || raw.locales.length === 0)
39
+ throw new Error("Catalog locales must be a nonempty array.");
40
+ for (const locale of raw.locales)
41
+ ascii(locale, "locale");
42
+ if (new Set(raw.locales).size !== raw.locales.length ||
43
+ !raw.locales.includes(raw.sourceLocale)) {
44
+ throw new Error("Catalog locales must be unique and contain sourceLocale.");
45
+ }
46
+ if (raw.sourceLocale !== identity.sourceLocale ||
47
+ raw.domain !== identity.domain ||
48
+ JSON.stringify(raw.locales) !== JSON.stringify(identity.locales)) {
49
+ throw new Error("Catalog manifest identity does not match the configured domain/locales/sourceLocale.");
50
+ }
51
+ const texts = object(raw.texts, "texts");
52
+ const htmlKeys = object(raw.htmlKeys, "htmlKeys");
53
+ const plurals = object(raw.plurals, "plurals");
54
+ for (const [key, value] of Object.entries(texts)) {
55
+ if (!keyPattern.test(key) || typeof value !== "string")
56
+ throw new Error(`Invalid catalog text ${JSON.stringify(key)}.`);
57
+ }
58
+ for (const [key, value] of Object.entries(htmlKeys)) {
59
+ if (value !== true || !Object.hasOwn(texts, key))
60
+ throw new Error(`Catalog HTML key ${JSON.stringify(key)} must reference an existing text.`);
61
+ }
62
+ for (const [key, value] of Object.entries(plurals)) {
63
+ const pair = object(value, `plural ${JSON.stringify(key)}`);
64
+ if (!keyPattern.test(key) ||
65
+ pair.one !== `${key}.one` ||
66
+ pair.plural !== `${key}.plural` ||
67
+ !Object.hasOwn(texts, pair.one) ||
68
+ !Object.hasOwn(texts, pair.plural)) {
69
+ throw new Error(`Catalog plural ${JSON.stringify(key)} must reference existing sibling one/plural text keys.`);
70
+ }
71
+ }
72
+ const artifacts = object(raw.artifacts, "artifacts");
73
+ const contents = { runtime: "", compiled: "" };
74
+ const realDirectory = realpathSync(directory);
75
+ const paths = new Set();
76
+ for (const mode of ["runtime", "compiled"]) {
77
+ const artifact = object(artifacts[mode], `${mode} artifact`);
78
+ const expected = mode === "runtime" ? "catalog.ts" : "catalog.compiled.ts";
79
+ if (typeof artifact.path !== "string" ||
80
+ artifact.path !== expected ||
81
+ paths.has(artifact.path))
82
+ throw new Error(`Unsafe or duplicate catalog artifact path for ${mode}.`);
83
+ paths.add(artifact.path);
84
+ if (typeof artifact.sha256 !== "string" ||
85
+ !digestPattern.test(artifact.sha256))
86
+ throw new Error(`Invalid ${mode} artifact digest.`);
87
+ const file = realpathSync(path.join(directory, artifact.path));
88
+ if (path.dirname(file) !== realDirectory || paths.has(file))
89
+ throw new Error(`Unsafe or duplicate resolved catalog artifact path for ${mode}.`);
90
+ paths.add(file);
91
+ const bytes = readFileSync(file);
92
+ if (createHash("sha256").update(bytes).digest("hex") !== artifact.sha256)
93
+ throw new Error(`Catalog ${mode} artifact digest mismatch.`);
94
+ contents[mode] = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
95
+ }
96
+ const { generation, ...payload } = raw;
97
+ if (typeof generation !== "string" ||
98
+ !digestPattern.test(generation) ||
99
+ createHash("sha256").update(canonicalJson(payload)).digest("hex") !==
100
+ generation) {
101
+ throw new Error("Catalog manifest generation digest mismatch.");
102
+ }
103
+ // A concurrently published manifest must not authorize the artifacts read above.
104
+ if (canonicalJson(JSON.parse(readFileSync(manifestFile, "utf8"))) !==
105
+ canonicalJson(raw)) {
106
+ throw new Error("Catalog generation changed while reading its artifacts.");
107
+ }
108
+ return { manifest: raw, ...contents };
109
+ }
110
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/vite/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { TransformResult } from "vite";
2
+ import type { TextCatalogSnapshot, TextCatalogTransformOptions } from "./types.js";
3
+ /** Expand only original application sources, before Vue owns SFC compilation. */
4
+ export declare function transformTextCatalog(source: string, id: string, snapshot: TextCatalogSnapshot, options: TextCatalogTransformOptions): Promise<TransformResult | null>;
5
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/vite/transform.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAQ5C,OAAO,KAAK,EAEV,mBAAmB,EACnB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAmKpB,iFAAiF;AACjF,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAogCjC"}