@vocoder/cli 0.8.0 → 0.10.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/dist/bin.mjs +63 -42
- package/dist/bin.mjs.map +1 -1
- package/dist/{chunk-7LFRSUPU.mjs → chunk-73U4VZYP.mjs} +314 -212
- package/dist/{chunk-7LFRSUPU.mjs.map → chunk-73U4VZYP.mjs.map} +1 -1
- package/dist/lib.d.mts +34 -5
- package/dist/lib.mjs +1 -1
- package/dist/lib.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -43584,7 +43584,8 @@ function detectLocalEcosystem(cwd = process.cwd()) {
|
|
|
43584
43584
|
hasExtractor: false,
|
|
43585
43585
|
hasConfig: false,
|
|
43586
43586
|
hasUiPackage: false,
|
|
43587
|
-
sourceLocale: null
|
|
43587
|
+
sourceLocale: null,
|
|
43588
|
+
isTypeScript: existsSync(join(cwd, "tsconfig.json"))
|
|
43588
43589
|
};
|
|
43589
43590
|
}
|
|
43590
43591
|
const allDeps = {
|
|
@@ -43594,6 +43595,7 @@ function detectLocalEcosystem(cwd = process.cwd()) {
|
|
|
43594
43595
|
const hasUnplugin = "@vocoder/plugin" in allDeps;
|
|
43595
43596
|
const hasExtractor = "@vocoder/extractor" in allDeps;
|
|
43596
43597
|
const hasConfig = "@vocoder/config" in allDeps;
|
|
43598
|
+
const isTypeScript = existsSync(join(cwd, "tsconfig.json")) || "typescript" in allDeps;
|
|
43597
43599
|
const { ecosystem, framework, uiPackage } = detectFromDeps(allDeps, cwd);
|
|
43598
43600
|
const hasUiPackage = uiPackage !== null && uiPackage in allDeps;
|
|
43599
43601
|
return {
|
|
@@ -43605,7 +43607,8 @@ function detectLocalEcosystem(cwd = process.cwd()) {
|
|
|
43605
43607
|
hasExtractor,
|
|
43606
43608
|
hasConfig,
|
|
43607
43609
|
hasUiPackage,
|
|
43608
|
-
sourceLocale: null
|
|
43610
|
+
sourceLocale: null,
|
|
43611
|
+
isTypeScript
|
|
43609
43612
|
};
|
|
43610
43613
|
}
|
|
43611
43614
|
function detectPackageManager(cwd) {
|
|
@@ -43906,6 +43909,12 @@ function extractFromObject(obj) {
|
|
|
43906
43909
|
if (key === "localesPath" && prop.value.type === "StringLiteral") {
|
|
43907
43910
|
config.localesPath = prop.value.value;
|
|
43908
43911
|
}
|
|
43912
|
+
if (key === "appIndustry" && prop.value.type === "StringLiteral") {
|
|
43913
|
+
config.appIndustry = prop.value.value;
|
|
43914
|
+
}
|
|
43915
|
+
if (key === "formality" && prop.value.type === "StringLiteral") {
|
|
43916
|
+
config.formality = prop.value.value;
|
|
43917
|
+
}
|
|
43909
43918
|
}
|
|
43910
43919
|
return config;
|
|
43911
43920
|
}
|
|
@@ -50390,242 +50399,335 @@ var StringExtractor = class {
|
|
|
50390
50399
|
const sortedFiles = Array.from(allFiles).sort();
|
|
50391
50400
|
for (const file of sortedFiles) {
|
|
50392
50401
|
try {
|
|
50393
|
-
const
|
|
50402
|
+
const code = readFileSync3(file, "utf-8");
|
|
50403
|
+
const relPath = pathRelative(projectRoot, file).split("\\").join("/");
|
|
50404
|
+
const strings = _extractFromContent(relPath, code);
|
|
50394
50405
|
allStrings.push(...strings);
|
|
50395
50406
|
} catch (error) {
|
|
50396
50407
|
console.warn(`Warning: Failed to extract from ${file}:`, error);
|
|
50397
50408
|
}
|
|
50398
50409
|
}
|
|
50399
|
-
return
|
|
50410
|
+
return deduplicateStrings(allStrings);
|
|
50400
50411
|
}
|
|
50401
|
-
|
|
50402
|
-
|
|
50403
|
-
|
|
50404
|
-
|
|
50405
|
-
|
|
50406
|
-
|
|
50407
|
-
|
|
50408
|
-
|
|
50409
|
-
|
|
50410
|
-
|
|
50411
|
-
|
|
50412
|
-
|
|
50413
|
-
|
|
50414
|
-
|
|
50415
|
-
|
|
50416
|
-
|
|
50417
|
-
|
|
50418
|
-
|
|
50419
|
-
|
|
50420
|
-
|
|
50421
|
-
|
|
50422
|
-
|
|
50423
|
-
|
|
50424
|
-
|
|
50425
|
-
|
|
50412
|
+
};
|
|
50413
|
+
function propNameToUiRole(propName) {
|
|
50414
|
+
switch (propName) {
|
|
50415
|
+
case "placeholder":
|
|
50416
|
+
return "input_placeholder";
|
|
50417
|
+
case "aria-label":
|
|
50418
|
+
case "aria-description":
|
|
50419
|
+
case "label":
|
|
50420
|
+
return "input_label";
|
|
50421
|
+
case "alt":
|
|
50422
|
+
return "image_alt";
|
|
50423
|
+
case "title":
|
|
50424
|
+
return "tooltip";
|
|
50425
|
+
default:
|
|
50426
|
+
return "unknown";
|
|
50427
|
+
}
|
|
50428
|
+
}
|
|
50429
|
+
function elementNameToUiRole(name) {
|
|
50430
|
+
if (!name) return "unknown";
|
|
50431
|
+
switch (name.toLowerCase()) {
|
|
50432
|
+
case "button":
|
|
50433
|
+
return "button_label";
|
|
50434
|
+
case "h1":
|
|
50435
|
+
case "h2":
|
|
50436
|
+
case "h3":
|
|
50437
|
+
case "h4":
|
|
50438
|
+
case "h5":
|
|
50439
|
+
case "h6":
|
|
50440
|
+
return "heading";
|
|
50441
|
+
case "label":
|
|
50442
|
+
return "input_label";
|
|
50443
|
+
case "th":
|
|
50444
|
+
return "table_header";
|
|
50445
|
+
case "option":
|
|
50446
|
+
return "option_label";
|
|
50447
|
+
case "title":
|
|
50448
|
+
return "page_title";
|
|
50449
|
+
case "p":
|
|
50450
|
+
case "li":
|
|
50451
|
+
case "dd":
|
|
50452
|
+
return "body_text";
|
|
50453
|
+
// Custom component name heuristics
|
|
50454
|
+
default: {
|
|
50455
|
+
const lower = name.toLowerCase();
|
|
50456
|
+
if (/button|btn|submit|cta/.test(lower)) return "button_label";
|
|
50457
|
+
if (/heading|headline/.test(lower)) return "heading";
|
|
50458
|
+
if (/label/.test(lower)) return "input_label";
|
|
50459
|
+
if (/tooltip|hint|popover/.test(lower)) return "tooltip";
|
|
50460
|
+
if (/badge|chip|tag|pill/.test(lower)) return "badge";
|
|
50461
|
+
if (/toast|snackbar|notification/.test(lower)) return "toast";
|
|
50462
|
+
if (/navitem|menuitem/.test(lower)) return "nav_item";
|
|
50463
|
+
return "unknown";
|
|
50464
|
+
}
|
|
50465
|
+
}
|
|
50466
|
+
}
|
|
50467
|
+
function detectUiRole(path2) {
|
|
50468
|
+
const parent = path2.parent;
|
|
50469
|
+
if (!parent) return "unknown";
|
|
50470
|
+
if (parent.type === "JSXExpressionContainer") {
|
|
50471
|
+
const attrNode = path2.parentPath?.parent;
|
|
50472
|
+
if (attrNode?.type === "JSXAttribute") {
|
|
50473
|
+
const propName = attrNode.name?.type === "JSXNamespacedName" ? `${attrNode.name.namespace.name}-${attrNode.name.name.name}` : attrNode.name?.name ?? "";
|
|
50474
|
+
return propNameToUiRole(propName);
|
|
50475
|
+
}
|
|
50476
|
+
}
|
|
50477
|
+
if (parent.type === "JSXElement") {
|
|
50478
|
+
const opening = parent.openingElement;
|
|
50479
|
+
const tagName = opening?.name?.type === "JSXMemberExpression" ? "unknown" : opening?.name?.name ?? "";
|
|
50480
|
+
return elementNameToUiRole(tagName);
|
|
50481
|
+
}
|
|
50482
|
+
return "unknown";
|
|
50483
|
+
}
|
|
50484
|
+
var FEATURE_PATTERNS = [
|
|
50485
|
+
[/\/(checkout|cart|basket)/, "checkout"],
|
|
50486
|
+
[/\/(auth|login|signup|sign-up|register|forgot|reset-password|verify)/, "auth"],
|
|
50487
|
+
[/\/(onboarding|welcome|setup)/, "onboarding"],
|
|
50488
|
+
[/\/(dashboard|overview|home)/, "dashboard"],
|
|
50489
|
+
[/\/(settings|preferences|profile|account)/, "settings"],
|
|
50490
|
+
[/\/(search|results|explore)/, "search"],
|
|
50491
|
+
[/\/(product|item|detail|pdp)/, "product"],
|
|
50492
|
+
[/\/(pricing|plans|billing|upgrade)/, "pricing"],
|
|
50493
|
+
[/\/(admin|manage)/, "admin"],
|
|
50494
|
+
[/\/(help|support|faq|docs)/, "support"]
|
|
50495
|
+
];
|
|
50496
|
+
function inferFeatureArea(filePath) {
|
|
50497
|
+
const normalized = filePath.replace(/\\/g, "/").toLowerCase();
|
|
50498
|
+
for (const [pattern, area] of FEATURE_PATTERNS) {
|
|
50499
|
+
if (pattern.test(normalized)) return area;
|
|
50500
|
+
}
|
|
50501
|
+
return void 0;
|
|
50502
|
+
}
|
|
50503
|
+
function _extractFromContent(filePath, content) {
|
|
50504
|
+
const strings = [];
|
|
50505
|
+
try {
|
|
50506
|
+
const ast = (0, import_parser2.parse)(content, {
|
|
50507
|
+
sourceType: "module",
|
|
50508
|
+
plugins: ["jsx", "typescript"]
|
|
50509
|
+
});
|
|
50510
|
+
const vocoderImports = /* @__PURE__ */ new Map();
|
|
50511
|
+
const tFunctionNames = /* @__PURE__ */ new Set();
|
|
50512
|
+
traverse2(ast, {
|
|
50513
|
+
ImportDeclaration: (path2) => {
|
|
50514
|
+
const source = path2.node.source.value;
|
|
50515
|
+
if (source === "@vocoder/react") {
|
|
50516
|
+
path2.node.specifiers.forEach((spec) => {
|
|
50517
|
+
if (spec.type === "ImportSpecifier") {
|
|
50518
|
+
const imported = spec.imported.type === "Identifier" ? spec.imported.name : null;
|
|
50519
|
+
const local = spec.local.name;
|
|
50520
|
+
if (imported === "T") {
|
|
50521
|
+
vocoderImports.set(local, "T");
|
|
50426
50522
|
}
|
|
50427
|
-
|
|
50428
|
-
|
|
50429
|
-
},
|
|
50430
|
-
VariableDeclarator: (path2) => {
|
|
50431
|
-
const init = path2.node.init;
|
|
50432
|
-
if (init && init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "useVocoder" && path2.node.id.type === "ObjectPattern") {
|
|
50433
|
-
path2.node.id.properties.forEach((prop) => {
|
|
50434
|
-
if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.key.name === "t") {
|
|
50435
|
-
const localName = prop.value.type === "Identifier" ? prop.value.name : "t";
|
|
50436
|
-
tFunctionNames.add(localName);
|
|
50523
|
+
if (imported === "t") {
|
|
50524
|
+
tFunctionNames.add(local);
|
|
50437
50525
|
}
|
|
50438
|
-
}
|
|
50439
|
-
}
|
|
50440
|
-
}
|
|
50441
|
-
|
|
50442
|
-
|
|
50443
|
-
|
|
50444
|
-
|
|
50445
|
-
|
|
50446
|
-
|
|
50447
|
-
|
|
50448
|
-
|
|
50449
|
-
|
|
50450
|
-
}
|
|
50451
|
-
|
|
50452
|
-
|
|
50453
|
-
|
|
50454
|
-
|
|
50455
|
-
|
|
50456
|
-
|
|
50457
|
-
|
|
50458
|
-
|
|
50459
|
-
|
|
50460
|
-
|
|
50461
|
-
|
|
50462
|
-
|
|
50463
|
-
|
|
50464
|
-
|
|
50465
|
-
|
|
50466
|
-
|
|
50467
|
-
|
|
50468
|
-
|
|
50469
|
-
|
|
50526
|
+
}
|
|
50527
|
+
});
|
|
50528
|
+
}
|
|
50529
|
+
},
|
|
50530
|
+
VariableDeclarator: (path2) => {
|
|
50531
|
+
const init = path2.node.init;
|
|
50532
|
+
if (init && init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "useVocoder" && path2.node.id.type === "ObjectPattern") {
|
|
50533
|
+
path2.node.id.properties.forEach((prop) => {
|
|
50534
|
+
if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.key.name === "t") {
|
|
50535
|
+
const localName = prop.value.type === "Identifier" ? prop.value.name : "t";
|
|
50536
|
+
tFunctionNames.add(localName);
|
|
50537
|
+
}
|
|
50538
|
+
});
|
|
50539
|
+
}
|
|
50540
|
+
},
|
|
50541
|
+
CallExpression: (path2) => {
|
|
50542
|
+
const callee = path2.node.callee;
|
|
50543
|
+
const isTFunction = callee.type === "Identifier" && tFunctionNames.has(callee.name);
|
|
50544
|
+
if (!isTFunction) return;
|
|
50545
|
+
const firstArg = path2.node.arguments[0];
|
|
50546
|
+
if (!firstArg) return;
|
|
50547
|
+
let text = null;
|
|
50548
|
+
if (firstArg.type === "StringLiteral") {
|
|
50549
|
+
text = firstArg.value;
|
|
50550
|
+
} else if (firstArg.type === "TemplateLiteral") {
|
|
50551
|
+
text = extractTemplateText(firstArg);
|
|
50552
|
+
}
|
|
50553
|
+
if (!text || text.trim().length === 0) return;
|
|
50554
|
+
const optionsArg = path2.node.arguments[2];
|
|
50555
|
+
let context;
|
|
50556
|
+
let formality;
|
|
50557
|
+
let explicitKey;
|
|
50558
|
+
if (optionsArg && optionsArg.type === "ObjectExpression") {
|
|
50559
|
+
optionsArg.properties.forEach((prop) => {
|
|
50560
|
+
if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
|
|
50561
|
+
if (prop.key.name === "context" && prop.value.type === "StringLiteral") {
|
|
50562
|
+
context = prop.value.value;
|
|
50470
50563
|
}
|
|
50471
|
-
|
|
50472
|
-
|
|
50473
|
-
|
|
50474
|
-
|
|
50475
|
-
|
|
50476
|
-
|
|
50477
|
-
|
|
50478
|
-
file: filePath,
|
|
50479
|
-
line,
|
|
50480
|
-
context,
|
|
50481
|
-
formality
|
|
50564
|
+
if (prop.key.name === "formality" && prop.value.type === "StringLiteral") {
|
|
50565
|
+
formality = prop.value.value;
|
|
50566
|
+
}
|
|
50567
|
+
if (prop.key.name === "id" && prop.value.type === "StringLiteral") {
|
|
50568
|
+
explicitKey = prop.value.value.trim();
|
|
50569
|
+
}
|
|
50570
|
+
}
|
|
50482
50571
|
});
|
|
50483
|
-
}
|
|
50484
|
-
|
|
50485
|
-
|
|
50486
|
-
|
|
50487
|
-
|
|
50488
|
-
|
|
50489
|
-
|
|
50490
|
-
|
|
50491
|
-
|
|
50492
|
-
|
|
50493
|
-
|
|
50572
|
+
}
|
|
50573
|
+
const line = path2.node.loc?.start.line || 0;
|
|
50574
|
+
const key = explicitKey && explicitKey.length > 0 ? explicitKey : generateMessageHash(text.trim(), context);
|
|
50575
|
+
const uiRole = detectUiRole(path2);
|
|
50576
|
+
const featureArea = inferFeatureArea(filePath);
|
|
50577
|
+
strings.push({
|
|
50578
|
+
key,
|
|
50579
|
+
text: text.trim(),
|
|
50580
|
+
file: filePath,
|
|
50581
|
+
line,
|
|
50582
|
+
context,
|
|
50583
|
+
formality,
|
|
50584
|
+
uiRole: uiRole !== "unknown" ? uiRole : void 0,
|
|
50585
|
+
featureArea
|
|
50586
|
+
});
|
|
50587
|
+
},
|
|
50588
|
+
JSXElement: (path2) => {
|
|
50589
|
+
const opening = path2.node.openingElement;
|
|
50590
|
+
const tagName = opening.name.type === "JSXIdentifier" ? opening.name.name : null;
|
|
50591
|
+
if (!tagName) return;
|
|
50592
|
+
const isTranslationComponent = vocoderImports.has(tagName);
|
|
50593
|
+
if (!isTranslationComponent) return;
|
|
50594
|
+
const msgAttribute = getStringAttribute(opening.attributes, "message");
|
|
50595
|
+
let text = null;
|
|
50596
|
+
if (msgAttribute) {
|
|
50597
|
+
text = msgAttribute;
|
|
50598
|
+
} else {
|
|
50599
|
+
const pluralSelectICU = extractPluralSelectICU(opening.attributes);
|
|
50600
|
+
if (pluralSelectICU) {
|
|
50601
|
+
text = pluralSelectICU;
|
|
50494
50602
|
} else {
|
|
50495
|
-
|
|
50496
|
-
opening.attributes
|
|
50497
|
-
);
|
|
50498
|
-
if (pluralSelectICU) {
|
|
50499
|
-
text = pluralSelectICU;
|
|
50500
|
-
} else {
|
|
50501
|
-
text = extractTextContentFromNodes(path2.node.children, { count: 0 });
|
|
50502
|
-
}
|
|
50603
|
+
text = extractTextContentFromNodes(path2.node.children, { count: 0 });
|
|
50503
50604
|
}
|
|
50504
|
-
if (!text || text.trim().length === 0) return;
|
|
50505
|
-
const id = this.getStringAttribute(opening.attributes, "id");
|
|
50506
|
-
const context = this.getStringAttribute(
|
|
50507
|
-
opening.attributes,
|
|
50508
|
-
"context"
|
|
50509
|
-
);
|
|
50510
|
-
const formality = this.getStringAttribute(
|
|
50511
|
-
opening.attributes,
|
|
50512
|
-
"formality"
|
|
50513
|
-
);
|
|
50514
|
-
const line = path2.node.loc?.start.line || 0;
|
|
50515
|
-
const key = id && id.trim().length > 0 ? id.trim() : generateMessageHash(text.trim(), context);
|
|
50516
|
-
strings.push({
|
|
50517
|
-
key,
|
|
50518
|
-
text: text.trim(),
|
|
50519
|
-
file: filePath,
|
|
50520
|
-
line,
|
|
50521
|
-
context,
|
|
50522
|
-
formality
|
|
50523
|
-
});
|
|
50524
50605
|
}
|
|
50525
|
-
|
|
50526
|
-
|
|
50527
|
-
|
|
50528
|
-
|
|
50529
|
-
|
|
50530
|
-
|
|
50531
|
-
|
|
50532
|
-
|
|
50533
|
-
|
|
50534
|
-
|
|
50535
|
-
|
|
50536
|
-
|
|
50537
|
-
|
|
50538
|
-
|
|
50539
|
-
|
|
50540
|
-
|
|
50541
|
-
|
|
50542
|
-
|
|
50543
|
-
|
|
50544
|
-
|
|
50545
|
-
|
|
50546
|
-
continue;
|
|
50547
|
-
}
|
|
50548
|
-
if (name === "gender") {
|
|
50549
|
-
hasGender = true;
|
|
50550
|
-
continue;
|
|
50551
|
-
}
|
|
50552
|
-
const value = attr.value?.type === "StringLiteral" ? attr.value.value : null;
|
|
50553
|
-
if (!value) continue;
|
|
50554
|
-
if (PLURAL_CLDR.has(name) || /^_\d+$/.test(name)) {
|
|
50555
|
-
pluralProps[name] = value;
|
|
50556
|
-
hasPlural = true;
|
|
50557
|
-
} else if (name === "other") {
|
|
50558
|
-
otherValue = value;
|
|
50559
|
-
} else if (/^_[a-zA-Z]/.test(name)) {
|
|
50560
|
-
selectProps[name] = value;
|
|
50561
|
-
hasSelect = true;
|
|
50606
|
+
if (!text || text.trim().length === 0) return;
|
|
50607
|
+
const id = getStringAttribute(opening.attributes, "id");
|
|
50608
|
+
const context = getStringAttribute(opening.attributes, "context");
|
|
50609
|
+
const formality = getStringAttribute(
|
|
50610
|
+
opening.attributes,
|
|
50611
|
+
"formality"
|
|
50612
|
+
);
|
|
50613
|
+
const line = path2.node.loc?.start.line || 0;
|
|
50614
|
+
const key = id && id.trim().length > 0 ? id.trim() : generateMessageHash(text.trim(), context);
|
|
50615
|
+
const uiRole = detectUiRole(path2);
|
|
50616
|
+
const featureArea = inferFeatureArea(filePath);
|
|
50617
|
+
strings.push({
|
|
50618
|
+
key,
|
|
50619
|
+
text: text.trim(),
|
|
50620
|
+
file: filePath,
|
|
50621
|
+
line,
|
|
50622
|
+
context,
|
|
50623
|
+
formality,
|
|
50624
|
+
uiRole: uiRole !== "unknown" ? uiRole : void 0,
|
|
50625
|
+
featureArea
|
|
50626
|
+
});
|
|
50562
50627
|
}
|
|
50628
|
+
});
|
|
50629
|
+
} catch (error) {
|
|
50630
|
+
throw new Error(
|
|
50631
|
+
`Failed to parse ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
50632
|
+
);
|
|
50633
|
+
}
|
|
50634
|
+
return strings;
|
|
50635
|
+
}
|
|
50636
|
+
function extractPluralSelectICU(attributes) {
|
|
50637
|
+
const pluralProps = {};
|
|
50638
|
+
const selectProps = {};
|
|
50639
|
+
let otherValue;
|
|
50640
|
+
let hasPlural = false;
|
|
50641
|
+
let hasSelect = false;
|
|
50642
|
+
let isOrdinal = false;
|
|
50643
|
+
let hasGender = false;
|
|
50644
|
+
for (const attr of attributes) {
|
|
50645
|
+
if (attr.type !== "JSXAttribute") continue;
|
|
50646
|
+
const name = attr.name.name;
|
|
50647
|
+
if (name === "ordinal") {
|
|
50648
|
+
isOrdinal = true;
|
|
50649
|
+
continue;
|
|
50563
50650
|
}
|
|
50564
|
-
if (
|
|
50565
|
-
|
|
50566
|
-
|
|
50567
|
-
return `{gender, select, masculine {${ordinalICU}} feminine {${ordinalICU}} other {${ordinalICU}}}`;
|
|
50568
|
-
}
|
|
50569
|
-
return ordinalICU;
|
|
50651
|
+
if (name === "gender") {
|
|
50652
|
+
hasGender = true;
|
|
50653
|
+
continue;
|
|
50570
50654
|
}
|
|
50571
|
-
|
|
50572
|
-
if (
|
|
50573
|
-
|
|
50574
|
-
|
|
50655
|
+
const value = attr.value?.type === "StringLiteral" ? attr.value.value : null;
|
|
50656
|
+
if (!value) continue;
|
|
50657
|
+
if (PLURAL_CLDR.has(name) || /^_\d+$/.test(name)) {
|
|
50658
|
+
pluralProps[name] = value;
|
|
50659
|
+
hasPlural = true;
|
|
50660
|
+
} else if (name === "other") {
|
|
50661
|
+
otherValue = value;
|
|
50662
|
+
} else if (/^_[a-zA-Z]/.test(name)) {
|
|
50663
|
+
selectProps[name] = value;
|
|
50664
|
+
hasSelect = true;
|
|
50575
50665
|
}
|
|
50576
|
-
|
|
50577
|
-
|
|
50578
|
-
|
|
50666
|
+
}
|
|
50667
|
+
if (isOrdinal) {
|
|
50668
|
+
const ordinalICU = "{count, selectordinal, other {#}}";
|
|
50669
|
+
if (hasGender) {
|
|
50670
|
+
return `{gender, select, masculine {${ordinalICU}} feminine {${ordinalICU}} other {${ordinalICU}}}`;
|
|
50579
50671
|
}
|
|
50580
|
-
return
|
|
50672
|
+
return ordinalICU;
|
|
50581
50673
|
}
|
|
50582
|
-
|
|
50583
|
-
|
|
50584
|
-
|
|
50585
|
-
|
|
50586
|
-
|
|
50587
|
-
|
|
50588
|
-
|
|
50589
|
-
|
|
50590
|
-
|
|
50591
|
-
|
|
50592
|
-
|
|
50593
|
-
|
|
50674
|
+
if (!hasPlural && !hasSelect) return null;
|
|
50675
|
+
if (hasPlural) {
|
|
50676
|
+
if (otherValue !== void 0) pluralProps.other = otherValue;
|
|
50677
|
+
return buildPluralICU(pluralProps, false);
|
|
50678
|
+
}
|
|
50679
|
+
if (hasSelect) {
|
|
50680
|
+
if (otherValue !== void 0) selectProps.other = otherValue;
|
|
50681
|
+
return buildSelectICU(selectProps);
|
|
50682
|
+
}
|
|
50683
|
+
return null;
|
|
50684
|
+
}
|
|
50685
|
+
function extractTemplateText(node) {
|
|
50686
|
+
let text = "";
|
|
50687
|
+
for (let i = 0; i < node.quasis.length; i++) {
|
|
50688
|
+
const quasi = node.quasis[i];
|
|
50689
|
+
text += quasi.value.raw;
|
|
50690
|
+
if (i < node.expressions.length) {
|
|
50691
|
+
const expr = node.expressions[i];
|
|
50692
|
+
if (expr.type === "Identifier") {
|
|
50693
|
+
text += `{${expr.name}}`;
|
|
50694
|
+
} else {
|
|
50695
|
+
text += "{value}";
|
|
50594
50696
|
}
|
|
50595
50697
|
}
|
|
50596
|
-
return text;
|
|
50597
50698
|
}
|
|
50598
|
-
|
|
50599
|
-
|
|
50600
|
-
|
|
50601
|
-
|
|
50602
|
-
|
|
50603
|
-
|
|
50604
|
-
|
|
50699
|
+
return text;
|
|
50700
|
+
}
|
|
50701
|
+
function getStringAttribute(attributes, name) {
|
|
50702
|
+
const attr = attributes.find(
|
|
50703
|
+
(a) => a.type === "JSXAttribute" && a.name.name === name
|
|
50704
|
+
);
|
|
50705
|
+
if (!attr || !attr.value) return void 0;
|
|
50706
|
+
if (attr.value.type === "StringLiteral") {
|
|
50707
|
+
return attr.value.value;
|
|
50708
|
+
}
|
|
50709
|
+
if (attr.value.type === "JSXExpressionContainer") {
|
|
50710
|
+
const expr = attr.value.expression;
|
|
50711
|
+
if (expr.type === "TemplateLiteral") {
|
|
50712
|
+
return extractTemplateText(expr);
|
|
50605
50713
|
}
|
|
50606
|
-
if (
|
|
50607
|
-
|
|
50608
|
-
if (expr.type === "TemplateLiteral") {
|
|
50609
|
-
return this.extractTemplateText(expr);
|
|
50610
|
-
}
|
|
50611
|
-
if (expr.type === "StringLiteral") {
|
|
50612
|
-
return expr.value;
|
|
50613
|
-
}
|
|
50714
|
+
if (expr.type === "StringLiteral") {
|
|
50715
|
+
return expr.value;
|
|
50614
50716
|
}
|
|
50615
|
-
return void 0;
|
|
50616
50717
|
}
|
|
50617
|
-
|
|
50618
|
-
|
|
50619
|
-
|
|
50620
|
-
|
|
50621
|
-
|
|
50622
|
-
|
|
50623
|
-
|
|
50624
|
-
|
|
50718
|
+
return void 0;
|
|
50719
|
+
}
|
|
50720
|
+
function deduplicateStrings(strings) {
|
|
50721
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50722
|
+
const unique = [];
|
|
50723
|
+
for (const str of strings) {
|
|
50724
|
+
if (!seen.has(str.key)) {
|
|
50725
|
+
seen.add(str.key);
|
|
50726
|
+
unique.push(str);
|
|
50625
50727
|
}
|
|
50626
|
-
return unique;
|
|
50627
50728
|
}
|
|
50628
|
-
|
|
50729
|
+
return unique;
|
|
50730
|
+
}
|
|
50629
50731
|
|
|
50630
50732
|
export {
|
|
50631
50733
|
detectLocalEcosystem,
|
|
@@ -50635,4 +50737,4 @@ export {
|
|
|
50635
50737
|
loadVocoderConfig,
|
|
50636
50738
|
StringExtractor
|
|
50637
50739
|
};
|
|
50638
|
-
//# sourceMappingURL=chunk-
|
|
50740
|
+
//# sourceMappingURL=chunk-73U4VZYP.mjs.map
|