Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 49 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@localizesh/processor-yaml",
"description": "A Localize.sh processor for YAML files.",
"description": "A Localize.sh processor for YAML files",
"repository": "localizesh/processor-yaml",
"license": "Apache-2.0",
"author": "Localize.sh",
Expand All @@ -25,13 +25,12 @@
"test": "vitest run"
},
"dependencies": {
"@localizesh/sdk": "^2.0.0",
"@localizesh/sdk": "^2.1.0",
"yaml": "^2.8.2"
},
"devDependencies": {
"@types/hast": "^3.0.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^25.1.0",
"@types/node": "^25.2.0",
"@types/yaml": "^1.9.7",
"eol": "^0.10.0",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
Expand Down
14 changes: 6 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { text } from "@localizesh/sdk";
import { segment, text } from "@localizesh/sdk";
import yaml, { HastTypeNames, LayoutLevelTypeNames } from "./utils.js";
import {
Context,
Expand All @@ -22,25 +22,23 @@ function astToDocument(layout: LayoutRoot, ctx: Context): Document {
// @ts-ignore
const tags = child.tags;
// @ts-ignore
let text = child.value !== null ? child.value : "";
const text = child.value !== null ? child.value : "";

const id: string = idGenerator.generateId(text, tags, ctx);
const segment: Segment = {
segments.push({
id,
text,
...(tags && { tags }),
};

segments.push(segment);
});
// @ts-ignore
node.children = [{ type: LayoutLevelTypeNames.segment, id }];
node.children = [segment(id)];
};

visitParents(
layout,
(node: LayoutNode) =>
// @ts-ignore
node?.properties?.type === "yamlValue" ||
node?.properties?.kind === "yamlValue" ||
(node as LayoutElement).tagName === "p",
(node: LayoutNode) => {
const el = node as LayoutElement;
Expand Down
100 changes: 46 additions & 54 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import {
isSeq,
isMap,
} from "yaml";
import { RootData } from "hast";
import type { LayoutElement, LayoutRoot, LayoutNode } from "@localizesh/sdk";
import {
type LayoutElement,
type LayoutRoot,
type LayoutNode,
element,
text,
} from "@localizesh/sdk";

export enum HastTypeNames {
root = "root",
Expand Down Expand Up @@ -83,7 +88,7 @@ const astToString = (rootAst: LayoutRoot): string => {

pair.key = new Scalar(keyChild.value);
if (key.properties?.yaml) {
for (let [keyProp, prop] of Object.entries(key.properties.yaml)) {
for (const [keyProp, prop] of Object.entries(key.properties.yaml)) {
//@ts-ignore
pair.key[keyProp] = prop;
}
Expand All @@ -102,7 +107,7 @@ const astToString = (rootAst: LayoutRoot): string => {
isBool ? val === "true" : isNumber ? Number(val) : val.toString(),
);
if (yamlValueProps) {
for (let [key, value] of Object.entries(yamlValueProps)) {
for (const [key, value] of Object.entries(yamlValueProps)) {
result[key] = value;
}
}
Expand All @@ -111,10 +116,10 @@ const astToString = (rootAst: LayoutRoot): string => {
};

const yamlDoc = new YamlDoc(astToObjectRecursive(rootAst));
const docProps: RootData | undefined = rootAst.data;
const docProps = rootAst.data;

if (docProps) {
for (let [key, value] of Object.entries(docProps)) {
for (const [key, value] of Object.entries(docProps)) {
//@ts-ignore
yamlDoc[key] = value;
}
Expand All @@ -133,52 +138,37 @@ const stringToAst = (rootString: string): LayoutRoot => {
return {
type: LayoutLevelTypeNames.yaml,
tagName: "table",
children: [
{
type: HastTypeNames.element,
tagName: "tbody",
children: getPropertiesInYamlObj(yaml, stringToAstRecursive),
properties: {},
},
],
properties: {},
children: [ element("tbody", getPropertiesInYamlObj(yaml, stringToAstRecursive)) ],
};
} else if (isSeq(yamlContent)) {
return {
type: HastTypeNames.element,
tagName: "ul",
children: yaml.items.map((value: any) => {
return {
type: HastTypeNames.element,
tagName: "li",
children: [
return element(
"ul",
{
yaml: { flow: !!yaml?.flow, spaceBefore: yaml.spaceBefore },
},
yaml.items.map((value: any) => {
return element(
"li",
{ yaml: { spaceBefore: value.spaceBefore } },
element(
"p",
{
type: HastTypeNames.element,
tagName: "p",
children: [stringToAstRecursive(value)],
properties: {
typeof: typeof value.value,
yaml: {
type: value.type,
comment: value.comment,
commentBefore: value.commentBefore,
spaceBefore: value.spaceBefore,
},
typeof: typeof value.value,
yaml: {
type: value.type,
comment: value.comment,
commentBefore: value.commentBefore,
spaceBefore: value.spaceBefore,
},
},
],
properties: { yaml: { spaceBefore: value.spaceBefore } },
};
stringToAstRecursive(value),
),
);
}),
properties: {
yaml: { flow: !!yaml?.flow, spaceBefore: yaml.spaceBefore },
},
};
);
} else {
return {
type: HastTypeNames.text,
value: yaml.source,
};
return text(yaml.source);
}
};
const ast: LayoutElement = stringToAstRecursive(yamlObject);
Expand All @@ -197,18 +187,18 @@ function getPropertiesInYamlObj(
yaml: any,
stringToAstRecursive: any,
): LayoutElement[] {
const children: any[] = [];
const contentsItems: YAMLPair[] = yaml?.contents?.items || yaml?.items || [];

contentsItems.forEach((pair: YAMLPair) => {
if ("key" in pair) {
return contentsItems
.filter((pair: YAMLPair) => "key" in pair)
.map((pair: YAMLPair) => {
const yamlHastKey = stringToAstRecursive(pair.key);
const yamlHastValue = stringToAstRecursive(pair.value);

const yaVal: any = pair?.value;
const yaKey: any = pair?.key;
let yamlValueProperties = {
type: "yamlValue",
const yamlValueProperties: any = {
kind: "yamlValue",
typeof: typeof yaVal.value,
yaml: {},
};
Expand All @@ -221,7 +211,12 @@ function getPropertiesInYamlObj(
};
}

const value = {
// We manually construct the AST node here instead of using the 'element' helper from @localizesh/sdk.
// The 'element' helper (wrapper around 'hastscript') has two issues for our use case:
// 1. It interprets objects with a 'type' property as child nodes, forcing us to use 'kind' instead.
// 2. It sanitizes properties for HTML compliance, stringifying our complex 'yaml' object into "[object Object]",
// which breaks our logic that relies on the raw object reference.
return {
type: HastTypeNames.element,
tagName: "tr",
children: [
Expand All @@ -246,10 +241,7 @@ function getPropertiesInYamlObj(
],
properties: {},
};
children.push(value);
}
});
return children;
});
}

const yaml: {
Expand Down
Loading