@x18n/builtins 0.0.13 → 0.0.15

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 (173) hide show
  1. package/dist/angular-templates-DqIOGfzT.mjs +8 -0
  2. package/dist/checks.d.mts +1 -0
  3. package/dist/checks.mjs +26 -1
  4. package/dist/extractors.mjs +7 -3
  5. package/dist/finders.d.mts +4 -1
  6. package/dist/finders.mjs +1 -1
  7. package/dist/formats/ecmascript.d.mts +5 -0
  8. package/dist/formats/ecmascript.mjs +232 -0
  9. package/dist/formats/ftl.d.mts +5 -0
  10. package/dist/formats/ftl.mjs +234 -0
  11. package/dist/formats/ini.d.mts +5 -0
  12. package/dist/formats/ini.mjs +158 -0
  13. package/dist/formats/json.d.mts +6 -0
  14. package/dist/formats/json.mjs +10 -0
  15. package/dist/formats/json5.d.mts +5 -0
  16. package/dist/formats/json5.mjs +143 -0
  17. package/dist/formats/jsonc.d.mts +6 -0
  18. package/dist/formats/jsonc.mjs +10 -0
  19. package/dist/formats/php.d.mts +5 -0
  20. package/dist/formats/php.mjs +198 -0
  21. package/dist/formats/po.d.mts +5 -0
  22. package/dist/formats/po.mjs +177 -0
  23. package/dist/formats/properties.d.mts +5 -0
  24. package/dist/formats/properties.mjs +123 -0
  25. package/dist/formats/resx.d.mts +6 -0
  26. package/dist/formats/resx.mjs +202 -0
  27. package/dist/formats/yaml.d.mts +5 -0
  28. package/dist/formats/yaml.mjs +140 -0
  29. package/dist/formats.d.mts +10 -34
  30. package/dist/formats.mjs +61 -1
  31. package/dist/index.d.mts +2 -2
  32. package/dist/index.mjs +30 -22
  33. package/dist/{vue-CF4pe-Yr.mjs → js-CV-ECNJG.mjs} +67 -222
  34. package/dist/json-CGNSGS97.mjs +109 -0
  35. package/dist/json-CyjI8bjp.d.mts +8 -0
  36. package/dist/jsx-templates-B1J0no3i.mjs +17 -0
  37. package/dist/literal-gIdB1VGy.mjs +125 -0
  38. package/dist/locale-root-C_rch3IQ.mjs +15 -0
  39. package/dist/manifests.d.mts +8 -0
  40. package/dist/manifests.mjs +66 -2
  41. package/dist/placeholders.d.mts +11 -0
  42. package/dist/placeholders.mjs +28 -1
  43. package/dist/plugin-Cb1b0axD.mjs +83 -0
  44. package/dist/plural-forms-B7_QX4nG.mjs +12 -0
  45. package/dist/presets/cargo-i18n.d.mts +6 -0
  46. package/dist/presets/cargo-i18n.mjs +28 -0
  47. package/dist/presets/chrome-extension.d.mts +6 -0
  48. package/dist/presets/chrome-extension.mjs +52 -0
  49. package/dist/presets/dotnet-resx.d.mts +6 -0
  50. package/dist/presets/dotnet-resx.mjs +64 -0
  51. package/dist/presets/easy-localization.d.mts +6 -0
  52. package/dist/presets/easy-localization.mjs +36 -0
  53. package/dist/presets/ember-intl.d.mts +5 -0
  54. package/dist/presets/ember-intl.mjs +31 -0
  55. package/dist/presets/fluent-react.d.mts +5 -0
  56. package/dist/presets/fluent-react.mjs +46 -0
  57. package/dist/presets/fluent-vue.d.mts +5 -0
  58. package/dist/presets/fluent-vue.mjs +51 -0
  59. package/dist/presets/flutter-translate.d.mts +6 -0
  60. package/dist/presets/flutter-translate.mjs +30 -0
  61. package/dist/presets/flutter.d.mts +6 -0
  62. package/dist/presets/flutter.mjs +21 -0
  63. package/dist/presets/general.d.mts +6 -0
  64. package/dist/presets/general.mjs +17 -0
  65. package/dist/presets/globalize.d.mts +5 -0
  66. package/dist/presets/globalize.mjs +25 -0
  67. package/dist/presets/gravity-ui-i18n.d.mts +6 -0
  68. package/dist/presets/gravity-ui-i18n.mjs +41 -0
  69. package/dist/presets/i18n-tag.d.mts +5 -0
  70. package/dist/presets/i18n-tag.mjs +21 -0
  71. package/dist/presets/i18next-shopify.d.mts +6 -0
  72. package/dist/presets/i18next-shopify.mjs +23 -0
  73. package/dist/presets/i18next.d.mts +5 -0
  74. package/dist/presets/i18next.mjs +10 -0
  75. package/dist/presets/i18nice.d.mts +6 -0
  76. package/dist/presets/i18nice.mjs +29 -0
  77. package/dist/presets/jekyll.d.mts +5 -0
  78. package/dist/presets/jekyll.mjs +23 -0
  79. package/dist/presets/laravel-vue-i18n.d.mts +6 -0
  80. package/dist/presets/laravel-vue-i18n.mjs +54 -0
  81. package/dist/presets/laravel.d.mts +6 -0
  82. package/dist/presets/laravel.mjs +23 -0
  83. package/dist/presets/lingui.d.mts +5 -0
  84. package/dist/presets/lingui.mjs +61 -0
  85. package/dist/presets/next-international.d.mts +5 -0
  86. package/dist/presets/next-international.mjs +27 -0
  87. package/dist/presets/next-intl.d.mts +5 -0
  88. package/dist/presets/next-intl.mjs +55 -0
  89. package/dist/presets/next-translate.d.mts +5 -0
  90. package/dist/presets/next-translate.mjs +53 -0
  91. package/dist/presets/ngx-translate.d.mts +5 -0
  92. package/dist/presets/ngx-translate.mjs +41 -0
  93. package/dist/presets/nuxt-i18n-micro.d.mts +5 -0
  94. package/dist/presets/nuxt-i18n-micro.mjs +81 -0
  95. package/dist/presets/nuxt-i18n.d.mts +5 -0
  96. package/dist/presets/nuxt-i18n.mjs +23 -0
  97. package/dist/presets/paraglide.d.mts +5 -0
  98. package/dist/presets/paraglide.mjs +38 -0
  99. package/dist/presets/php-gettext.d.mts +6 -0
  100. package/dist/presets/php-gettext.mjs +27 -0
  101. package/dist/presets/php-joomla.d.mts +6 -0
  102. package/dist/presets/php-joomla.mjs +22 -0
  103. package/dist/presets/polyglot.d.mts +5 -0
  104. package/dist/presets/polyglot.mjs +23 -0
  105. package/dist/presets/python-gettext.d.mts +6 -0
  106. package/dist/presets/python-gettext.mjs +44 -0
  107. package/dist/presets/react-i18next.d.mts +5 -0
  108. package/dist/presets/react-i18next.mjs +67 -0
  109. package/dist/presets/react-intl.d.mts +5 -0
  110. package/dist/presets/react-intl.mjs +47 -0
  111. package/dist/presets/ruby-i18n-js.d.mts +5 -0
  112. package/dist/presets/ruby-i18n-js.mjs +19 -0
  113. package/dist/presets/ruby-rails.d.mts +7 -0
  114. package/dist/presets/ruby-rails.mjs +44 -0
  115. package/dist/presets/solid-primitives-i18n.d.mts +5 -0
  116. package/dist/presets/solid-primitives-i18n.mjs +29 -0
  117. package/dist/presets/svelte-i18n.d.mts +5 -0
  118. package/dist/presets/svelte-i18n.mjs +33 -0
  119. package/dist/presets/svelte-i18next.d.mts +5 -0
  120. package/dist/presets/svelte-i18next.mjs +27 -0
  121. package/dist/presets/transloco.d.mts +5 -0
  122. package/dist/presets/transloco.mjs +44 -0
  123. package/dist/presets/typesafe-i18n.d.mts +6 -0
  124. package/dist/presets/typesafe-i18n.mjs +61 -0
  125. package/dist/presets/ui5.d.mts +5 -0
  126. package/dist/presets/ui5.mjs +35 -0
  127. package/dist/presets/vscode-extension.d.mts +5 -0
  128. package/dist/presets/vscode-extension.mjs +53 -0
  129. package/dist/presets/vue-i18n.d.mts +5 -0
  130. package/dist/presets/vue-i18n.mjs +59 -0
  131. package/dist/presets.d.mts +7 -54
  132. package/dist/presets.mjs +346 -1
  133. package/dist/reporters/github.d.mts +6 -0
  134. package/dist/reporters/github.mjs +27 -0
  135. package/dist/reporters/json.d.mts +6 -0
  136. package/dist/reporters/json.mjs +24 -0
  137. package/dist/reporters/markdown.d.mts +6 -0
  138. package/dist/reporters/markdown.mjs +37 -0
  139. package/dist/reporters/pretty.d.mts +6 -0
  140. package/dist/reporters/pretty.mjs +64 -0
  141. package/dist/reporters/sarif.d.mts +6 -0
  142. package/dist/reporters/sarif.mjs +48 -0
  143. package/dist/reporters.d.mts +5 -12
  144. package/dist/reporters.mjs +8 -218
  145. package/dist/reviews.d.mts +6 -0
  146. package/dist/reviews.mjs +35 -0
  147. package/dist/scanners/astro.d.mts +6 -0
  148. package/dist/scanners/astro.mjs +256 -0
  149. package/dist/scanners/js.d.mts +6 -0
  150. package/dist/scanners/js.mjs +33 -0
  151. package/dist/scanners/regex-scopes.d.mts +14 -0
  152. package/dist/scanners/regex-scopes.mjs +41 -0
  153. package/dist/scanners/regex.d.mts +9 -0
  154. package/dist/{regex-AYVhuSb6.mjs → scanners/regex.mjs} +2 -40
  155. package/dist/scanners/svelte.d.mts +6 -0
  156. package/dist/{scanners-DhnnVp7s.mjs → scanners/svelte.mjs} +3 -3
  157. package/dist/scanners/vue.d.mts +6 -0
  158. package/dist/scanners/vue.mjs +172 -0
  159. package/dist/scanners.d.mts +9 -50
  160. package/dist/scanners.mjs +36 -4
  161. package/dist/sfc-blocks-DaGKDZsb.mjs +213 -0
  162. package/dist/shared-C7ceptwi.mjs +55 -0
  163. package/dist/shared-D-tbsYmc.mjs +30 -0
  164. package/dist/shared-D4NJBKEP.mjs +17 -0
  165. package/dist/shared-Tq06G0gp.mjs +6 -0
  166. package/dist/shared-meYeVckh.mjs +11 -0
  167. package/dist/vue-compiler-0sfLIiiL.mjs +8 -0
  168. package/package.json +68 -3
  169. package/dist/formats-CFkM5co0.mjs +0 -1370
  170. package/dist/presets-Co5SlnKr.mjs +0 -1187
  171. package/dist/sfc-blocks-BqQ8m9rX.mjs +0 -161
  172. package/dist/yaml-plugin.d.mts +0 -8
  173. package/dist/yaml-plugin.mjs +0 -68
@@ -0,0 +1,158 @@
1
+ import { a as splice, i as leafText, n as detectEol, o as splitLines, t as appendLines } from "../shared-C7ceptwi.mjs";
2
+ import { buildTree, diffText, errors, isMessageLeaf, pathId } from "@x18n/core";
3
+ //#region src/formats/ini/index.ts
4
+ /** Reads the value after `=`; `start` is its first non-blank offset. */
5
+ function readValue(text, start, end, fail) {
6
+ const quote = text[start];
7
+ if (quote === "\"" || quote === "'") {
8
+ const close = quote === "\"" ? /^"(?:[^"\\]|\\.)*"/.exec(text.slice(start, end)) : /^'[^']*'/.exec(text.slice(start, end));
9
+ if (!close || !/^\s*(?:[;#].*)?$/.test(text.slice(start + close[0].length, end))) fail("unterminated or malformed quoted value");
10
+ const raw = close[0];
11
+ let value = raw.slice(1, -1);
12
+ if (quote === "\"") try {
13
+ value = JSON.parse(raw);
14
+ } catch {
15
+ fail(`invalid escape in ${raw}`);
16
+ }
17
+ return {
18
+ value,
19
+ source: {
20
+ start,
21
+ end: start + raw.length
22
+ },
23
+ inner: {
24
+ start: start + 1,
25
+ end: start + raw.length - 1
26
+ }
27
+ };
28
+ }
29
+ const comment = /\s[;#]/.exec(text.slice(start, end));
30
+ const valueEnd = start + text.slice(start, comment ? start + comment.index : end).trimEnd().length;
31
+ const range = {
32
+ start,
33
+ end: valueEnd
34
+ };
35
+ return {
36
+ value: text.slice(start, valueEnd),
37
+ source: range,
38
+ inner: range
39
+ };
40
+ }
41
+ function read(text, path) {
42
+ const entries = [];
43
+ const sections = [];
44
+ let section = "";
45
+ let lineNumber = 0;
46
+ const fail = (message) => {
47
+ throw errors.X18N2002({
48
+ path,
49
+ line: lineNumber,
50
+ reason: message
51
+ });
52
+ };
53
+ for (const line of splitLines(text)) {
54
+ lineNumber++;
55
+ const content = text.slice(line.start, line.end);
56
+ const trimmed = content.trim();
57
+ if (trimmed === "" || trimmed.startsWith(";") || trimmed.startsWith("#")) continue;
58
+ const header = /^\s*\[([^\]]+)\]\s*(?:[;#].*)?$/.exec(content);
59
+ if (header) {
60
+ section = header[1].trim();
61
+ sections.push({
62
+ name: section,
63
+ line
64
+ });
65
+ continue;
66
+ }
67
+ const eq = content.indexOf("=");
68
+ if (eq === -1) fail(`expected "key = value", got "${trimmed.slice(0, 20)}"`);
69
+ const key = content.slice(0, eq).trim();
70
+ if (key === "") fail("empty key");
71
+ const keyStart = line.start + content.indexOf(key);
72
+ const { value, source, inner } = readValue(text, line.start + eq + 1 + /^\s*/.exec(content.slice(eq + 1))[0].length, line.end, fail);
73
+ entries.push({
74
+ path: [...section ? section.split(".") : [], key],
75
+ section,
76
+ value,
77
+ range: {
78
+ key: {
79
+ start: keyStart,
80
+ end: keyStart + key.length
81
+ },
82
+ value: inner
83
+ },
84
+ source,
85
+ line
86
+ });
87
+ }
88
+ return {
89
+ entries,
90
+ sections
91
+ };
92
+ }
93
+ function encode(value, quote) {
94
+ if (quote === "'" && !/['\r\n]/.test(value)) return `'${value}'`;
95
+ return quote === "\"" || quote === "'" || /^\s|\s$|[\r\n"';#]|^\[/.test(value) ? JSON.stringify(value) : value;
96
+ }
97
+ function insertLine(text, at, line) {
98
+ const eol = detectEol(text);
99
+ const lead = at === text.length && text !== "" && !text.endsWith("\n") ? eol : "";
100
+ return splice(text, {
101
+ start: at,
102
+ end: at
103
+ }, `${lead}${line}${eol}`);
104
+ }
105
+ function applyOp(text, op, path) {
106
+ const { entries, sections } = read(text, path);
107
+ const id = pathId(op.path);
108
+ const entry = entries.findLast((e) => pathId(e.path) === id);
109
+ if (op.type === "delete") return entry ? splice(text, {
110
+ start: entry.line.start,
111
+ end: entry.line.next
112
+ }, "") : text;
113
+ const value = leafText(op.value);
114
+ if (entry) return splice(text, entry.source, encode(value, text[entry.source.start]));
115
+ const section = op.path.slice(0, -1).join(".");
116
+ const last = entries.findLast((e) => e.source.end > e.source.start);
117
+ const line = `${op.path.at(-1)}${last ? text.slice(last.range.key.end, last.source.start) : " = "}${encode(value, void 0)}`;
118
+ const anchor = entries.findLast((e) => e.section === section)?.line ?? sections.find((s) => s.name === section)?.line;
119
+ if (anchor) return insertLine(text, anchor.next, line);
120
+ if (section === "") return insertLine(text, sections[0]?.line.start ?? text.length, line);
121
+ return appendLines(text, `${text.trim() === "" ? "" : "\n"}[${section}]\n${line}\n`);
122
+ }
123
+ function serialize(tree) {
124
+ const blocks = [];
125
+ const visit = (node, path) => {
126
+ const children = Object.entries(node);
127
+ const leaves = children.filter((child) => isMessageLeaf(child[1]));
128
+ if (leaves.length > 0) blocks.push(`${path.length > 0 ? `[${path.join(".")}]\n` : ""}${leaves.map(([key, value]) => `${key} = ${encode(leafText(value), void 0)}\n`).join("")}`);
129
+ for (const [key, child] of children) if (!isMessageLeaf(child)) visit(child, [...path, key]);
130
+ };
131
+ visit(tree, []);
132
+ return blocks.join("\n");
133
+ }
134
+ function ini() {
135
+ return {
136
+ name: "x18n:format-ini",
137
+ formats: [{
138
+ id: "ini",
139
+ extensions: ["ini"],
140
+ parse(text, ctx) {
141
+ const { entries } = read(text, ctx.path);
142
+ const ranges = new Map(entries.map((e) => [pathId(e.path), e.range]));
143
+ return {
144
+ tree: buildTree(entries),
145
+ ranges
146
+ };
147
+ },
148
+ edit(text, ops, ctx) {
149
+ let next = text;
150
+ for (const op of ops) next = applyOp(next, op, ctx.path);
151
+ return diffText(text, next);
152
+ },
153
+ serialize
154
+ }]
155
+ };
156
+ }
157
+ //#endregion
158
+ export { ini as default, ini };
@@ -0,0 +1,6 @@
1
+ import { t as JsonOptions } from "../json-CyjI8bjp.mjs";
2
+ import { Plugin } from "@x18n/core";
3
+ //#region src/formats/json/index.d.ts
4
+ export declare function json(options?: JsonOptions): Plugin;
5
+ //#endregion
6
+ export { type JsonOptions, json as default };
@@ -0,0 +1,10 @@
1
+ import { t as createJsonFormat } from "../json-CGNSGS97.mjs";
2
+ //#region src/formats/json/index.ts
3
+ function json(options = {}) {
4
+ return {
5
+ name: "x18n:format-json",
6
+ formats: [createJsonFormat("json", ["json"], true, options.indent)]
7
+ };
8
+ }
9
+ //#endregion
10
+ export { json as default, json };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "@x18n/core";
2
+ //#region src/formats/json5/index.d.ts
3
+ export declare function json5(): Plugin;
4
+ //#endregion
5
+ export { json5 as default };
@@ -0,0 +1,143 @@
1
+ import { r as indentUnit } from "../shared-C7ceptwi.mjs";
2
+ import { t as editLiteral } from "../literal-gIdB1VGy.mjs";
3
+ import { diffText, errors, isMessageTree, pathId } from "@x18n/core";
4
+ import JSON5 from "json5";
5
+ //#region src/formats/json5/index.ts
6
+ const stringToken = /^(?:"(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*')/;
7
+ function parse(text, path) {
8
+ let data;
9
+ try {
10
+ data = JSON5.parse(text);
11
+ } catch (error) {
12
+ throw errors.X18N2002({
13
+ path,
14
+ reason: error instanceof Error ? error.message : String(error),
15
+ cause: error
16
+ });
17
+ }
18
+ if (!isMessageTree(data)) throw errors.X18N2003({ path });
19
+ return data;
20
+ }
21
+ /** Where the keys and values of valid JSON5 that holds a message tree are. */
22
+ function scan(text) {
23
+ const ranges = /* @__PURE__ */ new Map();
24
+ let pos = 0;
25
+ const skip = () => {
26
+ pos += /^(?:\s|\/\/.*|\/\*[\s\S]*?\*\/)*/.exec(text.slice(pos))[0].length;
27
+ };
28
+ const token = (pattern) => {
29
+ const start = pos;
30
+ pos += pattern.exec(text.slice(pos))[0].length;
31
+ return {
32
+ start,
33
+ end: pos
34
+ };
35
+ };
36
+ const inner = (range, quoted) => quoted ? {
37
+ start: range.start + 1,
38
+ end: range.end - 1
39
+ } : range;
40
+ const scalar = () => {
41
+ const quote = text[pos] === "\"" || text[pos] === "'" ? text[pos] : void 0;
42
+ return {
43
+ kind: "scalar",
44
+ range: token(quote ? stringToken : /^[^\s,}/]+/),
45
+ quote
46
+ };
47
+ };
48
+ const object = (path) => {
49
+ const start = pos++;
50
+ const items = [];
51
+ skip();
52
+ while (text[pos] !== "}") {
53
+ const quoted = text[pos] === "\"" || text[pos] === "'";
54
+ const keyRange = token(quoted ? stringToken : /^[^\s:/]+/);
55
+ const key = Object.keys(JSON5.parse(`{${text.slice(keyRange.start, keyRange.end)}:0}`))[0];
56
+ skip();
57
+ pos++;
58
+ skip();
59
+ const value = text[pos] === "{" ? object([...path, key]) : scalar();
60
+ ranges.set(pathId([...path, key]), {
61
+ key: inner(keyRange, quoted),
62
+ value: inner(value.range, value.kind === "scalar" && value.quote !== void 0)
63
+ });
64
+ items.push({
65
+ key,
66
+ range: {
67
+ start: keyRange.start,
68
+ end: value.range.end
69
+ },
70
+ value
71
+ });
72
+ skip();
73
+ if (text[pos] === ",") pos++;
74
+ skip();
75
+ }
76
+ pos++;
77
+ return {
78
+ kind: "object",
79
+ range: {
80
+ start,
81
+ end: pos
82
+ },
83
+ items
84
+ };
85
+ };
86
+ skip();
87
+ return {
88
+ root: object([]),
89
+ ranges
90
+ };
91
+ }
92
+ function firstQuote(object) {
93
+ for (const { value } of object.items) {
94
+ const quote = value.kind === "scalar" ? value.quote : firstQuote(value);
95
+ if (quote) return quote;
96
+ }
97
+ }
98
+ /** New keys and strings follow the file: quoted keys if its first key is quoted, and the quote of its first string. */
99
+ function syntaxOf(text, root, indent) {
100
+ const first = root.items[0];
101
+ const keyQuote = first && /^["']/.test(text[first.range.start]) ? text[first.range.start] : void 0;
102
+ const quote = firstQuote(root) ?? "\"";
103
+ return {
104
+ open: "{",
105
+ close: "}",
106
+ separator: ": ",
107
+ key: (key) => keyQuote ? JSON5.stringify(key, { quote: keyQuote }) : /^[a-z_$][\w$]*$/i.test(key) ? key : JSON5.stringify(key, { quote }),
108
+ leaf: (value, current) => JSON5.stringify(value, { quote: current ?? quote }),
109
+ unit: indentUnit(text, indent, " "),
110
+ trailingComma: false
111
+ };
112
+ }
113
+ function json5() {
114
+ return {
115
+ name: "x18n:format-json5",
116
+ formats: [{
117
+ id: "json5",
118
+ extensions: ["json5"],
119
+ parse(text, ctx) {
120
+ if (text.trim() === "") return {
121
+ tree: {},
122
+ ranges: /* @__PURE__ */ new Map()
123
+ };
124
+ return {
125
+ tree: parse(text, ctx.path),
126
+ ranges: scan(text).ranges
127
+ };
128
+ },
129
+ edit(text, ops, ctx) {
130
+ let next = text.trim() === "" ? "{}\n" : text;
131
+ for (const op of ops) {
132
+ parse(next, ctx.path);
133
+ const { root } = scan(next);
134
+ next = editLiteral(next, root, op, syntaxOf(next, root, ctx.indent));
135
+ }
136
+ return diffText(text, next);
137
+ },
138
+ serialize: (tree, ctx) => `${JSON5.stringify(tree, null, ctx.indent === "tab" ? " " : ctx.indent ?? 2)}\n`
139
+ }]
140
+ };
141
+ }
142
+ //#endregion
143
+ export { json5 as default, json5 };
@@ -0,0 +1,6 @@
1
+ import { t as JsonOptions } from "../json-CyjI8bjp.mjs";
2
+ import { Plugin } from "@x18n/core";
3
+ //#region src/formats/jsonc/index.d.ts
4
+ export declare function jsonc(options?: JsonOptions): Plugin;
5
+ //#endregion
6
+ export { jsonc as default };
@@ -0,0 +1,10 @@
1
+ import { t as createJsonFormat } from "../json-CGNSGS97.mjs";
2
+ //#region src/formats/jsonc/index.ts
3
+ function jsonc(options = {}) {
4
+ return {
5
+ name: "x18n:format-jsonc",
6
+ formats: [createJsonFormat("jsonc", ["jsonc"], true, options.indent)]
7
+ };
8
+ }
9
+ //#endregion
10
+ export { jsonc as default, jsonc };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "@x18n/core";
2
+ //#region src/formats/php/index.d.ts
3
+ export declare function php(): Plugin;
4
+ //#endregion
5
+ export { php as default };
@@ -0,0 +1,198 @@
1
+ import { n as literalText, t as editLiteral } from "../literal-gIdB1VGy.mjs";
2
+ import { applyMessageOps, diffText, errors, pathId } from "@x18n/core";
3
+ //#region src/formats/php/index.ts
4
+ const doubleEscapes = {
5
+ "n": "\n",
6
+ "t": " ",
7
+ "r": "\r",
8
+ "v": "\v",
9
+ "e": "\x1B",
10
+ "f": "\f",
11
+ "\\": "\\",
12
+ "$": "$",
13
+ "\"": "\""
14
+ };
15
+ function decodeDouble(raw, fail) {
16
+ if (/(?:^|[^\\])(?:\\\\)*(?:\$[a-z_{]|\{\$)/i.test(raw)) fail("X18N2004", "variable interpolation in a string");
17
+ return raw.replace(/\\(u\{[0-9a-f]+\}|x[0-9a-f]{1,2}|[0-7]{1,3}|[\s\S])/gi, (match, escape) => {
18
+ if (/^u\{/i.test(escape)) return String.fromCodePoint(Number.parseInt(escape.slice(2, -1), 16));
19
+ if (/^x[0-9a-f]/i.test(escape)) return String.fromCharCode(Number.parseInt(escape.slice(1), 16));
20
+ if (/^[0-7]/.test(escape)) return String.fromCharCode(Number.parseInt(escape, 8));
21
+ return doubleEscapes[escape] ?? match;
22
+ });
23
+ }
24
+ function parseFile(text, path) {
25
+ let pos = 0;
26
+ const fail = (code, reason) => {
27
+ throw errors[code]({
28
+ path,
29
+ line: text.slice(0, pos).split("\n").length,
30
+ reason
31
+ });
32
+ };
33
+ const skip = () => {
34
+ for (;;) {
35
+ const rest = text.slice(pos);
36
+ const blank = /^(?:\s+|\/\/[^\n]*|#(?!\[)[^\n]*|\/\*[\s\S]*?\*\/)/.exec(rest);
37
+ if (!blank) return;
38
+ pos += blank[0].length;
39
+ }
40
+ };
41
+ const eat = (pattern) => {
42
+ skip();
43
+ const match = pattern.exec(text.slice(pos));
44
+ if (match) pos += match[0].length;
45
+ return match?.[0];
46
+ };
47
+ const parseString = (quote) => {
48
+ const start = pos;
49
+ const match = (quote === "'" ? /^'(?:[^'\\]|\\[\s\S])*'/ : /^"(?:[^"\\]|\\[\s\S])*"/).exec(text.slice(pos));
50
+ if (!match) return fail("X18N2002", "unterminated string");
51
+ pos += match[0].length;
52
+ const raw = match[0].slice(1, -1);
53
+ const value = quote === "'" ? raw.replace(/\\([\\'])/g, "$1") : decodeDouble(raw, fail);
54
+ return {
55
+ kind: "scalar",
56
+ range: {
57
+ start,
58
+ end: pos
59
+ },
60
+ value,
61
+ quote
62
+ };
63
+ };
64
+ const parseArray = (start, close) => {
65
+ const closing = close === "]" ? /^\]/ : /^\)/;
66
+ const items = [];
67
+ while (!eat(closing)) {
68
+ const key = parseValue();
69
+ if (!eat(/^=>/)) return fail("X18N2003", "array item without a key");
70
+ if (key.kind !== "scalar" || typeof key.value !== "string" && typeof key.value !== "number") return fail("X18N2004", "array keys must be strings or integers");
71
+ const value = parseValue();
72
+ items.push({
73
+ key: String(key.value),
74
+ range: {
75
+ start: key.range.start,
76
+ end: value.range.end
77
+ },
78
+ keyRange: key.quote ? {
79
+ start: key.range.start + 1,
80
+ end: key.range.end - 1
81
+ } : key.range,
82
+ value
83
+ });
84
+ if (eat(/^,/)) continue;
85
+ skip();
86
+ if (text[pos] !== close) return fail("X18N2004", `expected "," or "${close}"; expressions are not static`);
87
+ }
88
+ return {
89
+ kind: "object",
90
+ range: {
91
+ start,
92
+ end: pos
93
+ },
94
+ items
95
+ };
96
+ };
97
+ function parseValue() {
98
+ skip();
99
+ const start = pos;
100
+ if (eat(/^\[/)) return parseArray(start, "]");
101
+ if (eat(/^array\s*\(/i)) return parseArray(start, ")");
102
+ if (text[pos] === "'" || text[pos] === "\"") return parseString(text[pos]);
103
+ const literal = eat(/^(?:-?\d+(?:\.\d+)?(?:e[+-]?\d+)?|true|false|null)\b/i);
104
+ if (literal === void 0) return fail("X18N2004", `"${text.slice(pos, pos + 20).split("\n")[0]}" is not a static value`);
105
+ const lower = literal.toLowerCase();
106
+ const value = lower === "null" ? null : lower === "true" ? true : lower === "false" ? false : Number(literal);
107
+ return {
108
+ kind: "scalar",
109
+ range: {
110
+ start,
111
+ end: pos
112
+ },
113
+ value,
114
+ quote: void 0
115
+ };
116
+ }
117
+ eat(/^<\?php\b/i);
118
+ if (eat(/^$/) !== void 0) return void 0;
119
+ eat(/^declare\s*\([^)]*\)\s*;/i);
120
+ if (!eat(/^return\b/i)) fail("X18N2004", "expected `return [ ... ];`");
121
+ const root = parseValue();
122
+ if (root.kind !== "object") fail("X18N2003", "the file must return an array");
123
+ if (!eat(/^;/)) fail("X18N2004", "expected \";\" after the array; expressions are not static");
124
+ eat(/^\?>/);
125
+ if (eat(/^$/) === void 0) fail("X18N2002", "unexpected text after the array");
126
+ return root;
127
+ }
128
+ function readTree(value, path, ranges) {
129
+ const out = {};
130
+ if (value.kind !== "object") return out;
131
+ for (const item of value.items) {
132
+ const childPath = [...path, item.key];
133
+ const inner = item.value.kind === "scalar" && item.value.quote ? {
134
+ start: item.value.range.start + 1,
135
+ end: item.value.range.end - 1
136
+ } : item.value.range;
137
+ ranges.set(pathId(childPath), {
138
+ key: item.keyRange,
139
+ value: inner
140
+ });
141
+ out[item.key] = item.value.kind === "object" ? readTree(item.value, childPath, ranges) : item.value.value;
142
+ }
143
+ return out;
144
+ }
145
+ const doubleEncodings = {
146
+ "\n": "\\n",
147
+ " ": "\\t",
148
+ "\r": "\\r",
149
+ "\v": "\\v",
150
+ "\f": "\\f"
151
+ };
152
+ function literal(value, quote) {
153
+ if (typeof value !== "string") return String(value);
154
+ if (quote === "\"" || /[\n\r\t\v\f]/.test(value)) return `"${value.replace(/[\\"$\n\t\r\v\f]/g, (char) => doubleEncodings[char] ?? `\\${char}`)}"`;
155
+ return `'${value.replace(/[\\']/g, "\\$&")}'`;
156
+ }
157
+ /** The indent unit is the configured one, else the file's (first indented item), else 4 spaces. */
158
+ function syntaxOf(text, indent) {
159
+ return {
160
+ open: "[",
161
+ close: "]",
162
+ separator: " => ",
163
+ key: (key) => literal(key, "'"),
164
+ leaf: (value, quote) => literal(value, quote),
165
+ unit: indent === void 0 ? /^([ \t]+)['"\]]/m.exec(text)?.[1] ?? " " : indent === "tab" ? " " : " ".repeat(indent),
166
+ trailingComma: true
167
+ };
168
+ }
169
+ function applyOp(text, op, path, syntax) {
170
+ const root = parseFile(text, path);
171
+ return root ? editLiteral(text, root, op, syntax) : `${text.trim() === "" ? "<?php" : text.trimEnd()}\n\nreturn ${literalText(applyMessageOps({}, [op]), syntax)};\n`;
172
+ }
173
+ function php() {
174
+ return {
175
+ name: "x18n:format-php",
176
+ formats: [{
177
+ id: "php",
178
+ extensions: ["php"],
179
+ parse(text, ctx) {
180
+ const root = parseFile(text, ctx.path);
181
+ const ranges = /* @__PURE__ */ new Map();
182
+ return {
183
+ tree: root ? readTree(root, [], ranges) : {},
184
+ ranges
185
+ };
186
+ },
187
+ edit(text, ops, ctx) {
188
+ const syntax = syntaxOf(text, ctx.indent);
189
+ let next = text;
190
+ for (const op of ops) next = applyOp(next, op, ctx.path, syntax);
191
+ return diffText(text, next);
192
+ },
193
+ serialize: (tree, ctx) => `<?php\n\nreturn ${literalText(tree, syntaxOf("", ctx.indent))};\n`
194
+ }]
195
+ };
196
+ }
197
+ //#endregion
198
+ export { php as default, php };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "@x18n/core";
2
+ //#region src/formats/po/index.d.ts
3
+ export declare function po(): Plugin;
4
+ //#endregion
5
+ export { po as default };