@x18n/builtins 0.0.0 → 0.0.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.
- package/package.json +2 -2
- package/dist/checks.d.mts +0 -19
- package/dist/checks.mjs +0 -330
- package/dist/extractors.d.mts +0 -51
- package/dist/extractors.mjs +0 -247
- package/dist/finders-Cf-IEaDm.mjs +0 -188
- package/dist/finders.d.mts +0 -29
- package/dist/finders.mjs +0 -3
- package/dist/formats-BAogSrvw.mjs +0 -1331
- package/dist/formats.d.mts +0 -34
- package/dist/formats.mjs +0 -1
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -38
- package/dist/manifests.d.mts +0 -10
- package/dist/manifests.mjs +0 -49
- package/dist/placeholders.d.mts +0 -27
- package/dist/placeholders.mjs +0 -131
- package/dist/presets-CxJ8CsTD.mjs +0 -1096
- package/dist/presets.d.mts +0 -58
- package/dist/presets.mjs +0 -1
- package/dist/regex-350J_An-.mjs +0 -89
- package/dist/reporters.d.mts +0 -14
- package/dist/reporters.mjs +0 -203
- package/dist/scanners--prozYaE.mjs +0 -119
- package/dist/scanners.d.mts +0 -48
- package/dist/scanners.mjs +0 -4
- package/dist/sfc-blocks-CQhgEeT6.mjs +0 -161
- package/dist/vue-6FYzIrQl.mjs +0 -730
- package/dist/yaml-plugin.d.mts +0 -8
- package/dist/yaml-plugin.mjs +0 -67
package/dist/presets.d.mts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Preset, PresetFactory } from "@x18n/core";
|
|
2
|
-
//#region src/presets/angular.d.ts
|
|
3
|
-
export declare function ngxTranslate(): Preset;
|
|
4
|
-
export declare function transloco(): Preset;
|
|
5
|
-
//#endregion
|
|
6
|
-
//#region src/presets/js.d.ts
|
|
7
|
-
export declare function vueI18n(): Preset;
|
|
8
|
-
export declare function nuxtI18n(): Preset;
|
|
9
|
-
export declare function i18next(): Preset;
|
|
10
|
-
export declare function reactI18next(): Preset;
|
|
11
|
-
export declare function nextIntl(): Preset;
|
|
12
|
-
export declare function reactIntl(): Preset;
|
|
13
|
-
export declare function svelteI18n(): Preset;
|
|
14
|
-
export declare function vscodeExtension(): Preset;
|
|
15
|
-
/** Always last: hard-string extraction templates for plain JS, TS and HTML. */
|
|
16
|
-
export declare function general(): Preset;
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/presets/mobile.d.ts
|
|
19
|
-
/** Flutter with `flutter_i18n`: JSON or YAML assets, `FlutterI18n.translate(context, 'key')`. */
|
|
20
|
-
export declare function flutter(): Preset;
|
|
21
|
-
//#endregion
|
|
22
|
-
//#region src/presets/server.d.ts
|
|
23
|
-
/** Laravel: `lang/{locale}/{file}.php` arrays and `lang/{locale}.json`; keys are `file.key`. Exclusive like i18n-ally. */
|
|
24
|
-
export declare function laravel(): Preset;
|
|
25
|
-
/** Joomla: INI language files, `Text::_('KEY')`. */
|
|
26
|
-
export declare function phpJoomla(): Preset;
|
|
27
|
-
/** PHP gettext with `.po` files. Exclusive and never detected, as in i18n-ally: list it in `presets`. */
|
|
28
|
-
export declare function phpGettext(): Preset;
|
|
29
|
-
/** `t('.title')` in `app/views/users/index.html.erb` means `users.index.title`. */
|
|
30
|
-
export declare function railsLazyKey(raw: string, path: string): string | undefined;
|
|
31
|
-
export declare function rubyRails(): Preset;
|
|
32
|
-
export declare function jekyll(): Preset;
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region src/presets/web.d.ts
|
|
35
|
-
export declare function nextInternational(): Preset;
|
|
36
|
-
export declare function nextTranslate(): Preset;
|
|
37
|
-
/** Shopify's i18next format: plural and ordinal forms as nested keys (`{key}.one`). */
|
|
38
|
-
export declare function i18nextShopify(): Preset;
|
|
39
|
-
export declare function i18nTag(): Preset;
|
|
40
|
-
export declare function fluentVue(): Preset;
|
|
41
|
-
export declare function polyglot(): Preset;
|
|
42
|
-
export declare function globalize(): Preset;
|
|
43
|
-
export declare function ui5(): Preset;
|
|
44
|
-
export declare function lingui(): Preset;
|
|
45
|
-
export declare function emberIntl(): Preset;
|
|
46
|
-
export declare function i18nJs(): Preset;
|
|
47
|
-
/** Chrome and WebExtension `_locales/{locale}/messages.json`: `{ "name": { "message": "..." } }` reads as `name`. */
|
|
48
|
-
export declare function chromeExtension(): Preset;
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/presets/index.d.ts
|
|
51
|
-
/**
|
|
52
|
-
* Presets by name, in detection order: every i18n-ally framework has one.
|
|
53
|
-
* Presets that share plugins (react-i18next and i18next) apply them once.
|
|
54
|
-
*/
|
|
55
|
-
export declare const presets: {
|
|
56
|
-
readonly [name: string]: PresetFactory;
|
|
57
|
-
};
|
|
58
|
-
//#endregion
|
package/dist/presets.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { n as chromeExtension, r as emberIntl, i as fluentVue, b as flutter, x as general, a as globalize, o as i18nJs, s as i18nTag, S as i18next, c as i18nextShopify, m as jekyll, h as laravel, l as lingui, u as nextInternational, C as nextIntl, d as nextTranslate, A as ngxTranslate, w as nuxtI18n, g as phpGettext, _ as phpJoomla, f as polyglot, t as presets, v as railsLazyKey, T as reactI18next, E as reactIntl, y as rubyRails, D as svelteI18n, j as transloco, p as ui5, O as vscodeExtension, k as vueI18n } from "./presets-CxJ8CsTD.mjs";
|
package/dist/regex-350J_An-.mjs
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
//#region src/scanners/regex.ts
|
|
2
|
-
/** The key part of i18n-ally `usageMatchRegex` patterns. */
|
|
3
|
-
const keyPattern = "[\\w\\d\\. \\-\\[\\]\\/:]+?";
|
|
4
|
-
/** Turns a pattern with a `{key}` placeholder into a regex whose first group is the key. */
|
|
5
|
-
function compileUsagePattern(pattern) {
|
|
6
|
-
const source = pattern.includes("{key}") ? pattern.replace("{key}", keyPattern) : pattern;
|
|
7
|
-
return new RegExp(source, "dg");
|
|
8
|
-
}
|
|
9
|
-
function scanWithRegex(text, regexes) {
|
|
10
|
-
const out = [];
|
|
11
|
-
for (const regex of regexes) {
|
|
12
|
-
regex.lastIndex = 0;
|
|
13
|
-
for (const match of text.matchAll(regex)) {
|
|
14
|
-
const indices = match.indices?.[1];
|
|
15
|
-
const raw = match[1];
|
|
16
|
-
if (!indices || raw === void 0) continue;
|
|
17
|
-
out.push({
|
|
18
|
-
raw,
|
|
19
|
-
range: {
|
|
20
|
-
start: indices[0],
|
|
21
|
-
end: indices[1]
|
|
22
|
-
},
|
|
23
|
-
kind: "call",
|
|
24
|
-
dynamic: false
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return out;
|
|
29
|
-
}
|
|
30
|
-
/** The `regex` scanner over `usage.regex` specs, plus extra specs given here (YAML plugins). */
|
|
31
|
-
function regex(specs = [], id = "regex") {
|
|
32
|
-
const cache = /* @__PURE__ */ new Map();
|
|
33
|
-
const regexesFor = (extension, all) => {
|
|
34
|
-
const key = `${extension}\0${all.length}`;
|
|
35
|
-
let list = cache.get(key);
|
|
36
|
-
if (!list) {
|
|
37
|
-
list = all.filter((spec) => spec.extensions.includes(extension)).flatMap((spec) => spec.patterns.map(compileUsagePattern));
|
|
38
|
-
cache.set(key, list);
|
|
39
|
-
}
|
|
40
|
-
return list;
|
|
41
|
-
};
|
|
42
|
-
let extensions = [...new Set(specs.flatMap((spec) => spec.extensions))];
|
|
43
|
-
const scanner = {
|
|
44
|
-
id,
|
|
45
|
-
get extensions() {
|
|
46
|
-
return extensions;
|
|
47
|
-
},
|
|
48
|
-
scan(file, ctx) {
|
|
49
|
-
const all = [...specs, ...ctx.config.usage.regex];
|
|
50
|
-
return { usages: scanWithRegex(file.text, regexesFor(file.extension, all)) };
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
return {
|
|
54
|
-
name: `x18n:scanner-${id}`,
|
|
55
|
-
configResolved(config) {
|
|
56
|
-
extensions = [...new Set([...specs, ...config.usage.regex].flatMap((spec) => spec.extensions))];
|
|
57
|
-
},
|
|
58
|
-
scanners: [scanner]
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Regions after each match of `pattern` (group 1 = namespace, or key prefix with `as: 'keyPrefix'`),
|
|
63
|
-
* up to the next match: i18n-ally `scopeRangeRegex`.
|
|
64
|
-
*/
|
|
65
|
-
function regexScopes(pattern, id = "scopes", options = {}) {
|
|
66
|
-
const re = new RegExp(pattern, "g");
|
|
67
|
-
return {
|
|
68
|
-
name: `x18n:scanner-${id}`,
|
|
69
|
-
scanners: [{
|
|
70
|
-
id,
|
|
71
|
-
extensions: options.extensions ?? ["*"],
|
|
72
|
-
scan(file) {
|
|
73
|
-
const matches = [...file.text.matchAll(re)];
|
|
74
|
-
return {
|
|
75
|
-
usages: [],
|
|
76
|
-
scopes: matches.map((match, i) => ({
|
|
77
|
-
range: {
|
|
78
|
-
start: match.index + match[0].length,
|
|
79
|
-
end: matches[i + 1]?.index ?? file.text.length
|
|
80
|
-
},
|
|
81
|
-
...options.as === "keyPrefix" ? { keyPrefix: match[1] } : { namespace: match[1] }
|
|
82
|
-
}))
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
}]
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
export { scanWithRegex as i, regex as n, regexScopes as r, compileUsagePattern as t };
|
package/dist/reporters.d.mts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Plugin, Reporter } from "@x18n/core";
|
|
2
|
-
//#region src/reporters/index.d.ts
|
|
3
|
-
/** tsc-style output: `path:line:col - error code: message`, code frames, then a summary. */
|
|
4
|
-
export declare const prettyReporter: Reporter;
|
|
5
|
-
/** The versioned JSON contract of `x18n check --json`. */
|
|
6
|
-
export declare const jsonReporter: Reporter;
|
|
7
|
-
/** Summary and tables for PR comments and agent context. */
|
|
8
|
-
export declare const markdownReporter: Reporter;
|
|
9
|
-
/** GitHub Actions workflow commands, which become annotations on the PR. */
|
|
10
|
-
export declare const githubReporter: Reporter;
|
|
11
|
-
/** SARIF 2.1.0 for code scanning. */
|
|
12
|
-
export declare const sarifReporter: Reporter;
|
|
13
|
-
export declare function reporters(): Plugin;
|
|
14
|
-
//#endregion
|
package/dist/reporters.mjs
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { createLineIndex, envelope, toWireDiagnostic } from "@x18n/core";
|
|
2
|
-
//#region src/reporters/index.ts
|
|
3
|
-
const codes = {
|
|
4
|
-
red: 31,
|
|
5
|
-
yellow: 33,
|
|
6
|
-
cyan: 36,
|
|
7
|
-
gray: 90,
|
|
8
|
-
blue: 34,
|
|
9
|
-
bold: 1
|
|
10
|
-
};
|
|
11
|
-
function paint(ctx, color, text) {
|
|
12
|
-
return ctx.color ? `\u001B[${codes[color]}m${text}\u001B[0m` : text;
|
|
13
|
-
}
|
|
14
|
-
function plural(count, word) {
|
|
15
|
-
return `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
16
|
-
}
|
|
17
|
-
function totals(inputs) {
|
|
18
|
-
return inputs.reduce((sum, input) => ({
|
|
19
|
-
errors: sum.errors + input.summary.errors,
|
|
20
|
-
warnings: sum.warnings + input.summary.warnings,
|
|
21
|
-
infos: sum.infos + input.summary.infos,
|
|
22
|
-
files: sum.files + input.summary.files
|
|
23
|
-
}), {
|
|
24
|
-
errors: 0,
|
|
25
|
-
warnings: 0,
|
|
26
|
-
infos: 0,
|
|
27
|
-
files: 0
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
const severityColor = {
|
|
31
|
-
error: "red",
|
|
32
|
-
warning: "yellow",
|
|
33
|
-
info: "blue",
|
|
34
|
-
hint: "gray"
|
|
35
|
-
};
|
|
36
|
-
function codeFrame(text, start, end, ctx) {
|
|
37
|
-
const index = createLineIndex(text);
|
|
38
|
-
const from = index.position(start);
|
|
39
|
-
const to = index.position(end);
|
|
40
|
-
const number = String(from.line + 1);
|
|
41
|
-
const line = index.line(from.line);
|
|
42
|
-
const width = Math.max(1, (to.line === from.line ? to.character : line.length) - from.character);
|
|
43
|
-
const gutter = " ".repeat(number.length);
|
|
44
|
-
return `${paint(ctx, "gray", number)} ${line}\n${gutter} ${" ".repeat(from.character)}${paint(ctx, "red", "~".repeat(width))}`;
|
|
45
|
-
}
|
|
46
|
-
/** tsc-style output: `path:line:col - error code: message`, code frames, then a summary. */
|
|
47
|
-
const prettyReporter = {
|
|
48
|
-
id: "pretty",
|
|
49
|
-
report(inputs, ctx) {
|
|
50
|
-
const out = [];
|
|
51
|
-
for (const input of inputs) for (const d of input.diagnostics) {
|
|
52
|
-
const head = `${paint(ctx, severityColor[d.severity], d.severity)} ${paint(ctx, "gray", d.code)}: ${d.message}`;
|
|
53
|
-
if (!d.location) {
|
|
54
|
-
out.push(`${head}\n`);
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const text = input.text(d.location.path);
|
|
58
|
-
const position = createLineIndex(text ?? "").position(d.location.range.start);
|
|
59
|
-
const where = `${paint(ctx, "cyan", ctx.displayPath(d.location.path, input.project))}:${paint(ctx, "yellow", String(position.line + 1))}:${paint(ctx, "yellow", String(position.character + 1))}`;
|
|
60
|
-
const frame = text !== void 0 && d.location.range.end > d.location.range.start ? `\n${codeFrame(text, d.location.range.start, d.location.range.end, ctx)}\n` : "";
|
|
61
|
-
out.push(`${where} - ${head}${frame}`);
|
|
62
|
-
}
|
|
63
|
-
const sum = totals(inputs);
|
|
64
|
-
if (sum.errors + sum.warnings === 0) out.push(paint(ctx, "gray", "Found no errors."));
|
|
65
|
-
else {
|
|
66
|
-
const parts = [sum.errors ? plural(sum.errors, "error") : "", sum.warnings ? plural(sum.warnings, "warning") : ""].filter(Boolean);
|
|
67
|
-
out.push(`${out.length && !out.at(-1).endsWith("\n") ? "\n" : ""}Found ${parts.join(" and ")} in ${plural(sum.files, "file")}.`);
|
|
68
|
-
}
|
|
69
|
-
return `${out.join("\n")}\n`;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
/** The versioned JSON contract of `x18n check --json`. */
|
|
73
|
-
const jsonReporter = {
|
|
74
|
-
id: "json",
|
|
75
|
-
report(inputs) {
|
|
76
|
-
const diagnostics = inputs.flatMap((input) => input.diagnostics.map((d) => toWireDiagnostic(input.project, d, input.text)));
|
|
77
|
-
const data = { projects: inputs.map((input) => ({
|
|
78
|
-
name: input.project,
|
|
79
|
-
summary: input.summary,
|
|
80
|
-
coverage: input.coverage.map((c) => ({
|
|
81
|
-
locale: c.locale,
|
|
82
|
-
total: c.total,
|
|
83
|
-
translated: c.translated,
|
|
84
|
-
missing: c.missing.length,
|
|
85
|
-
empty: c.empty.length
|
|
86
|
-
}))
|
|
87
|
-
})) };
|
|
88
|
-
return `${JSON.stringify(envelope("check", data, diagnostics), null, 2)}\n`;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
function escapeCell(text) {
|
|
92
|
-
return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
93
|
-
}
|
|
94
|
-
/** Summary and tables for PR comments and agent context. */
|
|
95
|
-
const markdownReporter = {
|
|
96
|
-
id: "markdown",
|
|
97
|
-
report(inputs, ctx) {
|
|
98
|
-
const sum = totals(inputs);
|
|
99
|
-
const out = [
|
|
100
|
-
"## x18n check",
|
|
101
|
-
"",
|
|
102
|
-
`**${plural(sum.errors, "error")}**, ${plural(sum.warnings, "warning")} in ${plural(sum.files, "file")}.`,
|
|
103
|
-
""
|
|
104
|
-
];
|
|
105
|
-
for (const input of inputs) {
|
|
106
|
-
if (inputs.length > 1) out.push(`### ${input.project}`, "");
|
|
107
|
-
out.push("| Locale | Translated | Missing | Empty |", "| --- | --- | --- | --- |");
|
|
108
|
-
for (const c of input.coverage) out.push(`| ${c.locale} | ${c.translated}/${c.total} | ${c.missing.length} | ${c.empty.length} |`);
|
|
109
|
-
out.push("");
|
|
110
|
-
if (input.diagnostics.length === 0) continue;
|
|
111
|
-
out.push("| Severity | Check | Location | Message |", "| --- | --- | --- | --- |");
|
|
112
|
-
for (const d of input.diagnostics.slice(0, 200)) {
|
|
113
|
-
const line = d.location ? createLineIndex(input.text(d.location.path) ?? "").position(d.location.range.start).line + 1 : void 0;
|
|
114
|
-
const where = d.location ? `\`${ctx.displayPath(d.location.path, input.project)}:${line}\`` : "";
|
|
115
|
-
out.push(`| ${d.severity} | \`${d.code}\` | ${where} | ${escapeCell(d.message)} |`);
|
|
116
|
-
}
|
|
117
|
-
if (input.diagnostics.length > 200) out.push("", `_${input.diagnostics.length - 200} more not shown._`);
|
|
118
|
-
out.push("");
|
|
119
|
-
}
|
|
120
|
-
return `${out.join("\n")}\n`;
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
function escapeProperty(text) {
|
|
124
|
-
return text.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/:/g, "%3A").replace(/,/g, "%2C");
|
|
125
|
-
}
|
|
126
|
-
function escapeData(text) {
|
|
127
|
-
return text.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A");
|
|
128
|
-
}
|
|
129
|
-
/** GitHub Actions workflow commands, which become annotations on the PR. */
|
|
130
|
-
const githubReporter = {
|
|
131
|
-
id: "github",
|
|
132
|
-
report(inputs, ctx) {
|
|
133
|
-
const out = [];
|
|
134
|
-
for (const input of inputs) for (const d of input.diagnostics) {
|
|
135
|
-
const level = d.severity === "error" ? "error" : d.severity === "warning" ? "warning" : "notice";
|
|
136
|
-
const props = [`title=${escapeProperty(`x18n ${d.code}`)}`];
|
|
137
|
-
if (d.location) {
|
|
138
|
-
const wire = toWireDiagnostic(input.project, d, input.text).range;
|
|
139
|
-
props.unshift(`file=${escapeProperty(ctx.displayPath(d.location.path, input.project))}`, `line=${wire.line}`, `col=${wire.column}`, `endLine=${wire.endLine}`, `endColumn=${wire.endColumn}`);
|
|
140
|
-
}
|
|
141
|
-
out.push(`::${level} ${props.join(",")}::${escapeData(d.message)}`);
|
|
142
|
-
}
|
|
143
|
-
return out.length ? `${out.join("\n")}\n` : "";
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
/** SARIF 2.1.0 for code scanning. */
|
|
147
|
-
const sarifReporter = {
|
|
148
|
-
id: "sarif",
|
|
149
|
-
report(inputs, ctx) {
|
|
150
|
-
const all = inputs.flatMap((input) => input.diagnostics.map((d) => ({
|
|
151
|
-
input,
|
|
152
|
-
d
|
|
153
|
-
})));
|
|
154
|
-
const rules = [...new Set(all.map(({ d }) => d.code))].sort();
|
|
155
|
-
const results = all.map(({ input, d }) => {
|
|
156
|
-
const wire = toWireDiagnostic(input.project, d, input.text);
|
|
157
|
-
return {
|
|
158
|
-
ruleId: d.code,
|
|
159
|
-
level: d.severity === "error" ? "error" : d.severity === "warning" ? "warning" : "note",
|
|
160
|
-
message: { text: d.message },
|
|
161
|
-
locations: d.location && wire.range ? [{ physicalLocation: {
|
|
162
|
-
artifactLocation: { uri: ctx.displayPath(d.location.path, input.project) },
|
|
163
|
-
region: {
|
|
164
|
-
startLine: wire.range.line,
|
|
165
|
-
startColumn: wire.range.column,
|
|
166
|
-
endLine: wire.range.endLine,
|
|
167
|
-
endColumn: wire.range.endColumn
|
|
168
|
-
}
|
|
169
|
-
} }] : []
|
|
170
|
-
};
|
|
171
|
-
});
|
|
172
|
-
const log = {
|
|
173
|
-
$schema: "https://json.schemastore.org/sarif-2.1.0.json",
|
|
174
|
-
version: "2.1.0",
|
|
175
|
-
runs: [{
|
|
176
|
-
tool: { driver: {
|
|
177
|
-
name: "x18n",
|
|
178
|
-
informationUri: "https://x18n.antfu.dev",
|
|
179
|
-
rules: rules.map((id) => ({
|
|
180
|
-
id,
|
|
181
|
-
helpUri: `https://x18n.antfu.dev/checks/${id}`
|
|
182
|
-
}))
|
|
183
|
-
} },
|
|
184
|
-
results
|
|
185
|
-
}]
|
|
186
|
-
};
|
|
187
|
-
return `${JSON.stringify(log, null, 2)}\n`;
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
function reporters() {
|
|
191
|
-
return {
|
|
192
|
-
name: "x18n:reporters",
|
|
193
|
-
reporters: [
|
|
194
|
-
prettyReporter,
|
|
195
|
-
jsonReporter,
|
|
196
|
-
markdownReporter,
|
|
197
|
-
githubReporter,
|
|
198
|
-
sarifReporter
|
|
199
|
-
]
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
//#endregion
|
|
203
|
-
export { githubReporter, jsonReporter, markdownReporter, prettyReporter, reporters, sarifReporter };
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { a as loadParser, o as scanSource } from "./vue-6FYzIrQl.mjs";
|
|
2
|
-
//#region src/scanners/svelte.ts
|
|
3
|
-
let compiler;
|
|
4
|
-
function isSvelteNode(value) {
|
|
5
|
-
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && "start" in value && typeof value.start === "number" && "end" in value && typeof value.end === "number";
|
|
6
|
-
}
|
|
7
|
-
const expressionTypes = /* @__PURE__ */ new Set([
|
|
8
|
-
"ExpressionTag",
|
|
9
|
-
"HtmlTag",
|
|
10
|
-
"ConstTag",
|
|
11
|
-
"RenderTag",
|
|
12
|
-
"IfBlock",
|
|
13
|
-
"EachBlock",
|
|
14
|
-
"AwaitBlock",
|
|
15
|
-
"KeyBlock"
|
|
16
|
-
]);
|
|
17
|
-
const ignoredAttributes = /* @__PURE__ */ new Set([
|
|
18
|
-
"class",
|
|
19
|
-
"style",
|
|
20
|
-
"id",
|
|
21
|
-
"name",
|
|
22
|
-
"type",
|
|
23
|
-
"href",
|
|
24
|
-
"src",
|
|
25
|
-
"for",
|
|
26
|
-
"role",
|
|
27
|
-
"lang",
|
|
28
|
-
"rel",
|
|
29
|
-
"target"
|
|
30
|
-
]);
|
|
31
|
-
function textHardString(node, data, attribute, out) {
|
|
32
|
-
const text = data.trim();
|
|
33
|
-
const name = typeof attribute?.name === "string" ? attribute.name : void 0;
|
|
34
|
-
if (!text || !/\p{L}/u.test(text) || name !== void 0 && ignoredAttributes.has(name)) return;
|
|
35
|
-
if (attribute) {
|
|
36
|
-
out.push({
|
|
37
|
-
text,
|
|
38
|
-
range: {
|
|
39
|
-
start: attribute.start,
|
|
40
|
-
end: attribute.end
|
|
41
|
-
},
|
|
42
|
-
kind: "svelte-attribute",
|
|
43
|
-
...name ? { attribute: name } : {}
|
|
44
|
-
});
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const start = node.start + data.indexOf(text);
|
|
48
|
-
out.push({
|
|
49
|
-
text,
|
|
50
|
-
range: {
|
|
51
|
-
start,
|
|
52
|
-
end: start + text.length
|
|
53
|
-
},
|
|
54
|
-
kind: "svelte-text"
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
/** Svelte components: `<script>` and template expressions through the `js` scanner. Node only at first. */
|
|
58
|
-
function svelte() {
|
|
59
|
-
return {
|
|
60
|
-
name: "x18n:scanner-svelte",
|
|
61
|
-
runtime: "node",
|
|
62
|
-
scanners: [{
|
|
63
|
-
id: "svelte",
|
|
64
|
-
extensions: ["svelte"],
|
|
65
|
-
runtime: "node",
|
|
66
|
-
async scan(file, ctx) {
|
|
67
|
-
compiler ??= import("svelte/compiler");
|
|
68
|
-
const [{ parse }, parseJs] = await Promise.all([compiler, loadParser()]);
|
|
69
|
-
const usages = [];
|
|
70
|
-
const keySlots = [];
|
|
71
|
-
const hardStrings = [];
|
|
72
|
-
const add = (result) => {
|
|
73
|
-
usages.push(...result.usages);
|
|
74
|
-
keySlots.push(...result.keySlots ?? []);
|
|
75
|
-
hardStrings.push(...result.hardStrings ?? []);
|
|
76
|
-
};
|
|
77
|
-
const ast = parse(file.text, { modern: true });
|
|
78
|
-
const scan = (text, offset, expression) => {
|
|
79
|
-
try {
|
|
80
|
-
add(scanSource(parseJs, text, {
|
|
81
|
-
calls: ctx.calls,
|
|
82
|
-
offset,
|
|
83
|
-
filename: "component.ts",
|
|
84
|
-
expression,
|
|
85
|
-
hardStrings: !expression
|
|
86
|
-
}));
|
|
87
|
-
} catch {}
|
|
88
|
-
};
|
|
89
|
-
const visit = (node, parentType, attribute) => {
|
|
90
|
-
if (Array.isArray(node)) {
|
|
91
|
-
node.forEach((child) => visit(child, parentType, attribute));
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (typeof node !== "object" || node === null) return;
|
|
95
|
-
if (!isSvelteNode(node)) {
|
|
96
|
-
for (const child of Object.values(node)) visit(child, parentType, attribute);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (node.type === "Script" && "content" in node && isSvelteNode(node.content)) {
|
|
100
|
-
scan(file.text.slice(node.content.start, node.content.end), node.content.start, false);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (expressionTypes.has(node.type) && "expression" in node && isSvelteNode(node.expression)) scan(file.text.slice(node.expression.start, node.expression.end), node.expression.start, true);
|
|
104
|
-
if (node.type === "Text" && "data" in node && typeof node.data === "string") textHardString(node, node.data, parentType === "Attribute" ? attribute : void 0, hardStrings);
|
|
105
|
-
const owner = node.type === "Attribute" ? node : attribute;
|
|
106
|
-
for (const [key, child] of Object.entries(node)) if (key !== "expression" && typeof child === "object") visit(child, node.type, owner);
|
|
107
|
-
};
|
|
108
|
-
visit(ast, "", void 0);
|
|
109
|
-
return {
|
|
110
|
-
usages,
|
|
111
|
-
keySlots,
|
|
112
|
-
hardStrings
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
}]
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
|
-
export { svelte as t };
|
package/dist/scanners.d.mts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { CallSpec, Plugin, RegexScannerSpec, ScanResult, UsageCandidate } from "@x18n/core";
|
|
2
|
-
import { Node } from "oxc-parser";
|
|
3
|
-
//#region src/scanners/js.d.ts
|
|
4
|
-
/** `a.b.c` for identifier and member chains, `this.` dropped; undefined for anything else. */
|
|
5
|
-
export declare function calleeName(node: Node): string | undefined;
|
|
6
|
-
type ParseSync = typeof import("oxc-parser").parseSync;
|
|
7
|
-
/** Loads oxc lazily: native in Node, WASM through the package's browser export. */
|
|
8
|
-
export declare function loadParser(): Promise<ParseSync>;
|
|
9
|
-
interface ScanSourceOptions {
|
|
10
|
-
readonly calls: readonly CallSpec[];
|
|
11
|
-
/** Offset of `text` in the file, for embedded code such as Vue `<script>`. */
|
|
12
|
-
readonly offset?: number;
|
|
13
|
-
readonly hardStrings?: boolean;
|
|
14
|
-
/** File name for the parser; picks JS, TS or JSX. */
|
|
15
|
-
readonly filename: string;
|
|
16
|
-
/** Parse `text` as one expression (template interpolations). */
|
|
17
|
-
readonly expression?: boolean;
|
|
18
|
-
/** Callees whose string arguments are never hard strings (`extract.ignoreCallees`). */
|
|
19
|
-
readonly ignoreCallees?: readonly string[] | undefined;
|
|
20
|
-
}
|
|
21
|
-
export declare function scanSource(parse: ParseSync, text: string, options: ScanSourceOptions): ScanResult;
|
|
22
|
-
/** The AST scanner for JS and TS, driven by call specs (`usage.calls`). */
|
|
23
|
-
export declare function js(): Plugin;
|
|
24
|
-
//#endregion
|
|
25
|
-
//#region src/scanners/regex.d.ts
|
|
26
|
-
/** Turns a pattern with a `{key}` placeholder into a regex whose first group is the key. */
|
|
27
|
-
export declare function compileUsagePattern(pattern: string): RegExp;
|
|
28
|
-
export declare function scanWithRegex(text: string, regexes: readonly RegExp[]): UsageCandidate[];
|
|
29
|
-
/** The `regex` scanner over `usage.regex` specs, plus extra specs given here (YAML plugins). */
|
|
30
|
-
export declare function regex(specs?: readonly RegexScannerSpec[], id?: string): Plugin;
|
|
31
|
-
/**
|
|
32
|
-
* Regions after each match of `pattern` (group 1 = namespace, or key prefix with `as: 'keyPrefix'`),
|
|
33
|
-
* up to the next match: i18n-ally `scopeRangeRegex`.
|
|
34
|
-
*/
|
|
35
|
-
export declare function regexScopes(pattern: string, id?: string, options?: {
|
|
36
|
-
readonly as?: "namespace" | "keyPrefix";
|
|
37
|
-
readonly extensions?: readonly string[];
|
|
38
|
-
}): Plugin;
|
|
39
|
-
//#endregion
|
|
40
|
-
//#region src/scanners/svelte.d.ts
|
|
41
|
-
/** Svelte components: `<script>` and template expressions through the `js` scanner. Node only at first. */
|
|
42
|
-
export declare function svelte(): Plugin;
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/scanners/vue.d.ts
|
|
45
|
-
/** Vue SFCs: `<script>` through the `js` scanner, template expressions, `v-t`, `<i18n-t keypath>`. */
|
|
46
|
-
export declare function vue(): Plugin;
|
|
47
|
-
//#endregion
|
|
48
|
-
export type { ScanSourceOptions };
|
package/dist/scanners.mjs
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { a as loadParser, i as js, n as vue, o as scanSource, r as calleeName } from "./vue-6FYzIrQl.mjs";
|
|
2
|
-
import { i as scanWithRegex, n as regex, r as regexScopes, t as compileUsagePattern } from "./regex-350J_An-.mjs";
|
|
3
|
-
import { t as svelte } from "./scanners--prozYaE.mjs";
|
|
4
|
-
export { calleeName, compileUsagePattern, js, loadParser, regex, regexScopes, scanSource, scanWithRegex, svelte, vue };
|