@x18n/builtins 0.0.2 → 0.0.5

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.
@@ -0,0 +1,161 @@
1
+ import { a as json5, o as json, t as yaml } from "./formats-BAogSrvw.mjs";
2
+ import { t as loadVueCompiler } from "./vue-5GFR5hft.mjs";
3
+ import { isMessageLeaf, pathId } from "@x18n/core";
4
+ //#region src/finders/sfc-blocks.ts
5
+ const formatOfLang = {
6
+ json: "json",
7
+ json5: "json5",
8
+ yaml: "yaml",
9
+ yml: "yaml"
10
+ };
11
+ /** A format for blocks that hold every locale (`{ "en": {...}, "de": {...} }`): each resource sees its locale's subtree. */
12
+ function localeRoot(base) {
13
+ return {
14
+ id: `sfc-${base.id}`,
15
+ extensions: [],
16
+ parse(text, ctx) {
17
+ const parsed = base.parse(text, ctx);
18
+ const subtree = parsed.tree[ctx.locale];
19
+ const tree = subtree && !isMessageLeaf(subtree) ? subtree : {};
20
+ const ranges = /* @__PURE__ */ new Map();
21
+ const prefix = `${pathId([ctx.locale])}\u0000`;
22
+ for (const [id, range] of parsed.ranges ?? []) if (id.startsWith(prefix)) ranges.set(id.slice(prefix.length), range);
23
+ return {
24
+ tree,
25
+ ranges
26
+ };
27
+ },
28
+ edit: base.edit ? (text, ops, ctx) => base.edit(text, ops.map((op) => ({
29
+ ...op,
30
+ path: [ctx.locale, ...op.path]
31
+ })), ctx) : void 0
32
+ };
33
+ }
34
+ /** Vue `<i18n>` blocks: one resource per block and locale (`locale="en"`, or every top-level locale key). */
35
+ function sfcBlocks() {
36
+ const bases = [
37
+ json(),
38
+ json5(),
39
+ yaml()
40
+ ].flatMap((plugin) => plugin.formats ?? []);
41
+ return {
42
+ name: "x18n:finder-sfc-blocks",
43
+ formats: bases.map(localeRoot),
44
+ localeFinders: [{
45
+ id: "sfc-blocks",
46
+ async find(ctx) {
47
+ const files = await ctx.host.glob(["**/*.vue"], {
48
+ ignore: ctx.config.usage.exclude,
49
+ gitignore: true
50
+ });
51
+ const { parse } = await loadVueCompiler();
52
+ const out = [];
53
+ for (const path of files) {
54
+ const text = await ctx.host.readFile(path);
55
+ if (!text?.includes("<i18n")) continue;
56
+ const { descriptor } = parse(text, {
57
+ filename: path,
58
+ sourceMap: false
59
+ });
60
+ descriptor.customBlocks.forEach((block, index) => {
61
+ if (block.type !== "i18n") return;
62
+ const lang = typeof block.attrs.lang === "string" ? block.attrs.lang : "json";
63
+ const formatId = formatOfLang[lang] ?? "json";
64
+ const blockInfo = {
65
+ index,
66
+ range: {
67
+ start: block.loc.start.offset,
68
+ end: block.loc.end.offset
69
+ },
70
+ lang
71
+ };
72
+ if (typeof block.attrs.locale === "string") {
73
+ out.push({
74
+ path,
75
+ locale: block.attrs.locale,
76
+ namespace: void 0,
77
+ format: formatId,
78
+ block: blockInfo
79
+ });
80
+ return;
81
+ }
82
+ const base = bases.find((f) => f.id === formatId);
83
+ try {
84
+ const tree = base.parse(block.content, {
85
+ path,
86
+ locale: "",
87
+ namespace: void 0,
88
+ indent: void 0
89
+ }).tree;
90
+ for (const locale of Object.keys(tree)) out.push({
91
+ path,
92
+ locale,
93
+ namespace: void 0,
94
+ format: `sfc-${formatId}`,
95
+ block: {
96
+ ...blockInfo,
97
+ index: index * 1e3 + Object.keys(tree).indexOf(locale)
98
+ }
99
+ });
100
+ } catch {
101
+ out.push({
102
+ path,
103
+ locale: ctx.config.sourceLocale,
104
+ namespace: void 0,
105
+ format: `sfc-${formatId}`,
106
+ block: blockInfo
107
+ });
108
+ }
109
+ });
110
+ }
111
+ return out;
112
+ }
113
+ }]
114
+ };
115
+ }
116
+ /** fluent-vue `<fluent locale="en">` blocks in Vue SFCs, read with the `ftl` format. */
117
+ function sfcFluentBlocks() {
118
+ return {
119
+ name: "x18n:finder-sfc-fluent-blocks",
120
+ localeFinders: [{
121
+ id: "sfc-fluent-blocks",
122
+ async find(ctx) {
123
+ const files = await ctx.host.glob(["**/*.vue"], {
124
+ ignore: ctx.config.usage.exclude,
125
+ gitignore: true
126
+ });
127
+ const { parse } = await loadVueCompiler();
128
+ const out = [];
129
+ for (const path of files) {
130
+ const text = await ctx.host.readFile(path);
131
+ if (!text?.includes("<fluent")) continue;
132
+ parse(text, {
133
+ filename: path,
134
+ sourceMap: false
135
+ }).descriptor.customBlocks.forEach((block, index) => {
136
+ if (block.type === "fluent" && typeof block.attrs.locale === "string") {
137
+ const range = {
138
+ start: block.loc.start.offset,
139
+ end: block.loc.end.offset
140
+ };
141
+ out.push({
142
+ path,
143
+ locale: block.attrs.locale,
144
+ namespace: void 0,
145
+ format: "ftl",
146
+ block: {
147
+ index,
148
+ range,
149
+ lang: "ftl"
150
+ }
151
+ });
152
+ }
153
+ });
154
+ }
155
+ return out;
156
+ }
157
+ }]
158
+ };
159
+ }
160
+ //#endregion
161
+ export { sfcFluentBlocks as n, sfcBlocks as t };