UNPKG

@intlayer/chokidar

Version:

Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.

128 lines (126 loc) 5.32 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_runtime = require('../_virtual/_rolldown/runtime.cjs'); let recast = require("recast"); recast = require_runtime.__toESM(recast); //#region src/writeContentDeclaration/transformJSONFile.ts const b = recast.types.builders; const n = recast.types.namedTypes; /** * Checks if a value is a plain object (and not null/array) */ const isPlainObject = (value) => { return typeof value === "object" && value !== null && !Array.isArray(value); }; /** * Checks if a recast AST node value matches the incoming primitive value. */ const isPrimitiveEqual = (astNode, val) => { if (val === null) return n.Literal.check(astNode) && astNode.value === null; if (typeof val === "string" || typeof val === "number" || typeof val === "boolean") return (n.Literal.check(astNode) || n.StringLiteral.check(astNode) || n.NumericLiteral.check(astNode) || n.BooleanLiteral.check(astNode)) && astNode.value === val; return false; }; /** * Robustly finds a property in a recast ObjectExpression. * Handles quoted ("key") or unquoted (key) properties. */ const getMatchingProperty = (node, key) => { return node.properties.find((prop) => { if (n.Property.check(prop) || n.ObjectProperty.check(prop)) { if (n.Identifier.check(prop.key) && prop.key.name === key) return true; if (n.StringLiteral.check(prop.key) && prop.key.value === key) return true; if (n.Literal.check(prop.key) && prop.key.value === key) return true; } return false; }); }; /** * Recursively builds a clean recast AST node from a plain JS value. * Because these nodes lack `loc` tracking, recast is forced to pretty-print them. */ const buildASTNode = (val) => { if (val === null) return b.literal(null); if (typeof val === "string" || typeof val === "number" || typeof val === "boolean") return b.literal(val); if (Array.isArray(val)) return b.arrayExpression(val.map((item) => buildASTNode(item))); if (isPlainObject(val)) return b.objectExpression(Object.entries(val).filter(([, v]) => v !== void 0).map(([k, v]) => b.property("init", b.stringLiteral(k), buildASTNode(v)))); return b.literal(null); }; /** * Recursively updates the AST object literal with new data. */ const updateObjectLiteral = (node, data) => { for (const [key, val] of Object.entries(data)) { if (val === void 0) continue; const existingProp = getMatchingProperty(node, key); if (existingProp?.comments) existingProp.comments.forEach((c) => { if ((c.type === "Line" || c.type === "CommentLine") && c.trailing) { c.type = c.type === "Line" ? "Block" : "CommentBlock"; c.value = `__INLINE_LINE__${c.value}`; c.leading = false; c.trailing = true; } }); if (isPlainObject(val)) if (existingProp && n.ObjectExpression.check(existingProp.value)) updateObjectLiteral(existingProp.value, val); else if (existingProp) { if (!(n.Literal.check(existingProp.value) && existingProp.value.value === val)) existingProp.value = buildASTNode(val); } else node.properties.push(b.property("init", b.stringLiteral(key), buildASTNode(val))); else if (existingProp) { if (!isPrimitiveEqual(existingProp.value, val)) existingProp.value = buildASTNode(val); } else node.properties.push(b.property("init", b.stringLiteral(key), buildASTNode(val))); } }; const transformJSONFile = (fileContent, dictionary, noMetadata) => { const wrappedContent = `const _config = ${fileContent.trim() || "{}"};`; let ast; try { ast = recast.parse(wrappedContent); } catch { return JSON.stringify(noMetadata ? dictionary.content : dictionary, null, 2); } const declaration = ast.program.body[0]; let objectLiteral; if (n.VariableDeclaration.check(declaration) && declaration.declarations.length > 0 && n.VariableDeclarator.check(declaration.declarations[0]) && n.ObjectExpression.check(declaration.declarations[0].init)) objectLiteral = declaration.declarations[0].init; if (noMetadata) { const metadataProperties = [ "id", "locale", "filled", "fill", "title", "description", "tags", "version", "priority", "contentAutoTransformation", "$schema" ]; for (let i = objectLiteral.properties.length - 1; i >= 0; i--) { const prop = objectLiteral.properties[i]; if (n.Property.check(prop) || n.ObjectProperty.check(prop)) { let propName = ""; if (n.Identifier.check(prop.key)) propName = prop.key.name; else if (n.StringLiteral.check(prop.key)) propName = prop.key.value; else if (n.Literal.check(prop.key)) propName = String(prop.key.value); if ([ "key", "content", ...metadataProperties ].includes(propName)) objectLiteral.properties.splice(i, 1); } } } updateObjectLiteral(objectLiteral, noMetadata ? dictionary.content : dictionary); const printedCode = recast.print(ast, { tabWidth: 2, quote: "double", trailingComma: false }).code; const startIndex = printedCode.indexOf("{"); const endIndex = printedCode.lastIndexOf("}"); let finalOutput = printedCode.substring(startIndex, endIndex + 1); finalOutput = finalOutput.replace(/\s*\/\*__INLINE_LINE__(.*?)\*\/(\s*,?)/g, "$2 //$1"); finalOutput = finalOutput.replace(/\n[ \t]*\n/g, "\n"); return finalOutput; }; //#endregion exports.transformJSONFile = transformJSONFile; //# sourceMappingURL=transformJSONFile.cjs.map