UNPKG

@compas/code-gen

Version:

Generate various boring parts of your server

91 lines (77 loc) 2.57 kB
// @ts-nocheck import { AppError, isNil, isPlainObject } from "@compas/stdlib"; import { structureAddType } from "./structure/structureAddType.js"; import { upperCaseFirst } from "./utils.js"; /** * Provided that input is empty, copy over all enabled groups from structure, * automatically include references of groups that are not enabled. * * @param {CodeGenStructure} input * @param {CodeGenStructure} structure * @param {string[]} groups */ export function addGroupsToGeneratorInput(input, structure, groups) { for (const group of groups) { input[group] = structure[group] || {}; } includeReferenceTypes(structure, input); } /** * Find nested references and add to generatorInput in the correct group * * @param {CodeGenStructure} structure * @param {CodeGenStructure} input * @returns {void} */ export function includeReferenceTypes(structure, input) { const stack = [input]; while (stack.length) { const currentObject = stack.shift(); // handle values if (currentObject?.type === "reference") { const { group, name } = currentObject.reference; // ensure ref does not already exits if (!isNil(structure[group]?.[name]) && isNil(input[group]?.[name])) { structureAddType(input, structure[group][name]); // Note that we need the full referenced object here, since // currentObject.reference only contains { group, name, uniqueName } stack.push(input[group][name]); continue; } else if (isNil(structure[group]?.[name])) { throw new AppError("codeGen.app.followReferences", 500, { message: `Could not resolve reference '${ upperCaseFirst(group) + upperCaseFirst(name) }'`, }); } } // extend stack if (Array.isArray(currentObject)) { for (const it of currentObject) { stack.push(it); } } else if (isPlainObject(currentObject)) { for (const key of Object.keys(currentObject)) { stack.push(currentObject[key]); } } } } /** * Using some more memory, but ensures a mostly consistent output. * JS Object iterators mostly follow insert order. * We do this so diffs are more logical * * @param {CodeGenStructure} input * @param {CodeGenStructure} copy */ export function copyAndSort(input, copy) { const groups = Object.keys(input).sort(); for (const group of groups) { copy[group] = {}; const names = Object.keys(input[group]).sort(); for (const name of names) { copy[group][name] = input[group][name]; } } }