UNPKG

23.9 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.js","sources":["../src/util/find-command-end.ts","../src/util/index-object.ts","../src/util/replace-array-indexes.ts","../src/util/stringify.ts","../src/consume.ts","../src/t.ts","../src/util/read-compiler-options.ts","../src/writer.ts"],"sourcesContent":["import type { Commands, TemplateData } from '../types';\n\n/**\n * Returns the amount of keys that are part of a command\n *\n * @param keys Keys must start with the cmd\n * @returns 1, if the command is `each` and the next key is `/each`\n */\nexport function findCommandEnd<\n Arg extends string = string,\n T extends TemplateData = TemplateData\n>(command: string, keys: Commands<Arg, T>[]) {\n for (let index = 0, deep = 0; index < keys.length; index++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const key = keys[index]!;\n\n // Skips simple keys\n if (!key || typeof key === 'string') {\n continue;\n }\n\n switch (key[0]) {\n case command:\n deep++;\n break;\n case '/' + command:\n deep--;\n break;\n }\n\n // Found the end of the command\n if (deep === 0) {\n return index;\n }\n }\n\n throw new Error(`Command \"${command}\" is not closed.`);\n}\n\n/**\n * Returns the amount of keys that are part of a command\n *\n * @param keys Keys must start with the cmd\n * @returns 1, if the command is `each` and the next key is `/each`\n */\nexport function findElseClause<\n Arg extends string = string,\n T extends TemplateData = TemplateData\n>(keys: Commands<Arg, T>[]) {\n for (let index = 0, deep = 0; index < keys.length; index++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const key = keys[index]!;\n\n // Skips simple keys\n if (!key || typeof key === 'string') {\n continue;\n }\n\n switch (key[0]) {\n case 'if':\n deep++;\n break;\n case 'else':\n // Found the end of the command\n if (deep === 1) {\n return index;\n }\n break;\n case '/if':\n deep--;\n break;\n }\n }\n\n return undefined;\n}\n","/** Indexes an object using a dotted string path */\nexport function indexObject<R>(path: string, data: unknown): R {\n const paths = path.split('.');\n\n for (let index = 0; index < paths.length; index++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const p = paths[index]!;\n\n if (p === '@') {\n throw new Error(\n 'Cannot use \"@\" as a key, have you forget to wrap it in a ${[\\'each\\']}?'\n );\n }\n\n if (\n // Avoids `cannot use 'in' operator to search` error when data is primitive\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n typeof data === 'object' && data ? p in data : (data as never)[p]\n ) {\n data = (data as never)[p];\n continue;\n }\n\n throw new Error(\n `Key \"${p}\" ${path.startsWith(p) ? '' : `in \"${path}\" `}does not exist inside data`\n );\n }\n\n return data as R;\n}\n","import type { Commands, KeysOf, TemplateData } from '../types';\n\nexport function replaceArrayIndexes<\n D extends TemplateData,\n P extends KeysOf<Omit<D, 'helpers'>>[]\n>(\n keys: Commands<P[number], D>[],\n argument: string,\n index: number,\n symbol = '@'\n): typeof keys {\n const mappedKeys = Array(keys.length);\n\n for (let i = 0; i < keys.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const key = keys[i]! as string | [string, string];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let path = typeof key === 'string' ? key : key[1]!;\n\n if (\n // Commands like ['/if', '/each'] don't have a path\n !path ||\n // Not a dotted path\n !path.startsWith(`${argument}.${symbol}`)\n ) {\n // Just copies the key\n mappedKeys[i] = key;\n continue;\n }\n\n // Replaces the key with the new path\n path = `${argument}.${index}` + path.slice(argument.length + symbol.length + 1);\n\n mappedKeys[i] =\n typeof key === 'string'\n ? path\n : // Clones the key, so we don't mutate the original\n [key[0] as 'if', path];\n }\n\n return mappedKeys as Commands<P[number], D>[];\n}\n","import { stringify as javascriptStringify } from 'javascript-stringify';\n\nexport function stringify(value: unknown) {\n return typeof value === 'function' || typeof value === 'object'\n ? javascriptStringify(value)\n : String(value);\n}\n","import type { Commands, KeysOf, TemplateData, TemplateHelper } from './types';\nimport { findCommandEnd, findElseClause } from './util/find-command-end';\nimport { indexObject } from './util/index-object';\nimport { replaceArrayIndexes } from './util/replace-array-indexes';\nimport { stringify } from './util/stringify';\n\n/** Parses and evaluates a template string. */\nexport function consume<D extends TemplateData, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n start: number,\n end: number,\n templates: string[],\n data: D,\n keys: Commands<P[number], D>[]\n): string {\n let code = '';\n let index = start;\n\n // Jumps on each nextIndex until it reaches the end of the template\n while (index <= end) {\n const result = consumeStep(templates, data, keys, index);\n\n // Has code to append\n if (result.code !== undefined) {\n code += result.code;\n }\n\n // Reached the end of the sub template\n if (!result.nextIndex) {\n break;\n }\n\n // Jumps to the next index\n index = result.nextIndex;\n }\n\n return code;\n}\n\n/** Parses and evaluates a single template and key of a template string. */\nexport function consumeStep<\n D extends TemplateData,\n P extends KeysOf<Omit<D, 'helpers'>>[]\n>(\n templates: string[],\n data: D,\n keys: Commands<P[number], D>[],\n index: number\n): {\n code?: string;\n nextIndex?: number;\n} {\n let template = templates[index];\n\n // index out of bounds\n if (template === undefined) {\n return {};\n }\n\n const key = keys[index];\n\n // If there's no key, it means it's a simple template\n if (key === undefined) {\n return { code: template, nextIndex: index + 1 };\n }\n\n // If the parameter is a string, it means it's simply a data's key\n if (typeof key === 'string') {\n return {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n code: template + stringify(indexObject(key, data))!,\n nextIndex: index + 1\n };\n }\n\n // The ending of a command template, like /if\n if (key[0][0] === '/' || key[0] === 'else') {\n // The end command template, if needed, should've been appended on the previous iteration\n return {\n code: template,\n nextIndex: index + 1\n };\n }\n\n // It is a helper\n if (key[0][0] === '$') {\n const helperName = key[0].slice(1);\n\n if (!data.helpers) {\n throw new Error(`Helper \"${helperName}\" not found`);\n }\n\n let helper: TemplateHelper[1] | undefined;\n\n for (const h of data.helpers) {\n if (h[0] === helperName) {\n helper = h[1];\n break;\n }\n }\n\n if (!helper) {\n throw new Error(`Helper \"${helperName}\" not found`);\n }\n\n return {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n code: template + stringify(helper(key[1], data))!,\n nextIndex: index + 1\n };\n }\n\n // Handles the 'each' command\n if (key[0] === 'each') {\n const argument = key[1];\n const array: unknown = indexObject(argument, data);\n\n if (!Array.isArray(array)) {\n throw new Error(`Key \"${argument}\" is not an array`);\n }\n\n const eachEndIndex = index + findCommandEnd('each', keys.slice(index));\n\n for (let arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {\n const replacedKeys = replaceArrayIndexes(keys, argument, arrayIndex);\n\n template += consume(index + 1, eachEndIndex, templates, data, replacedKeys);\n }\n\n return {\n code: template,\n nextIndex: eachEndIndex + 1\n };\n }\n\n // Handles the 'if' command\n if (key[0] === 'if') {\n const argument = key[1];\n const condition = !!indexObject(argument, data);\n\n // Reduces the amount of keys to be parsed\n const slicedKeys = keys.slice(index);\n\n const ifEndIndex = index + findCommandEnd('if', slicedKeys);\n const elseRelativeIndex = findElseClause(slicedKeys.slice(0, ifEndIndex));\n\n if (condition || elseRelativeIndex) {\n // Appends the if body, if the condition is truthy or there's an else clause\n template += consume(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n condition ? index + 1 : index + elseRelativeIndex! + 1,\n // Until the else clause, if it exists\n condition && elseRelativeIndex ? index + elseRelativeIndex : ifEndIndex,\n templates,\n data,\n keys\n );\n }\n\n return {\n nextIndex: ifEndIndex + 1,\n code: template\n };\n }\n\n // Just throws an error if the command is invalid\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n throw new Error(`Invalid command: ${stringify(key)!}`);\n}\n","import { consume } from './consume';\nimport type { Commands, KeysOf, TemplateData } from './types';\n\n/**\n * The generic template string template engine function, it does not have any special\n * features, it just fills the provided template with your data.\n *\n * @returns The generated string\n */\nexport function t<D extends TemplateData, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n _template: TemplateStringsArray,\n data: D,\n ...keys: Commands<P[number], D>[]\n): string {\n /** Copies array into mutable */\n const template = _template.slice();\n\n // This removes the first item from the template array,\n // allowing us have matching values for the same index at parameters and template\n {\n const prefix = (template as unknown as string[]).shift();\n\n // If theres text before the data.\n if (prefix?.trim().length) {\n throw new Error(`Cannot have text before data \"${prefix}\"`);\n }\n }\n\n // Trims the start of the code, if there's any\n if (template[0]) {\n template[0] = template[0].trimStart();\n }\n\n // Trims the end of the code, if there's any\n if (template[template.length - 1]) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n template[template.length - 1] = template[template.length - 1]!.trimEnd();\n }\n\n // Runs consume with the whole template range\n return consume(\n // template info\n 0,\n template.length,\n template,\n // data object\n data,\n // keys array\n keys\n );\n}\n","import path from 'node:path';\nimport ts from 'typescript';\n\n/**\n * Attempts to read the compiler options from a tsconfig file. Also resolving its\n * following extends.\n */\nexport function readCompilerOptions(tsconfigPath: string) {\n let res: ReturnType<typeof ts.readConfigFile> | ts.ParsedCommandLine =\n ts.readConfigFile(tsconfigPath, (p) => ts.sys.readFile(p));\n\n if (res.error) {\n throw new Error(`Failed to read tsconfig file.`);\n }\n\n res = ts.parseJsonConfigFileContent(\n res.config,\n ts.sys,\n path.dirname(tsconfigPath),\n undefined,\n tsconfigPath\n );\n\n if (res.errors.length) {\n throw new Error(`Failed to parse tsconfig file.`);\n }\n\n return res.options;\n}\n","import path from 'node:path';\nimport ts from 'typescript';\nimport { t } from './t';\nimport type { Commands, KeysOf, SourceTemplateData, TemplateHelper } from './types';\nimport { readCompilerOptions } from './util/read-compiler-options';\n\nexport class TsWriter<\n H extends readonly TemplateHelper[] | undefined = readonly TemplateHelper[] | undefined\n> {\n /**\n * A simple map of all the sources that have been written.\n *\n * The string array represents the result of each write call, **not each written line**.\n */\n readonly sources: Record<string, string[]> = {};\n private outputs: Record<string, string> = {};\n readonly host: ts.CompilerHost;\n readonly compilerOptions: ts.CompilerOptions;\n\n /**\n * Constructs a new TsWriter instance.\n *\n * @param optionsOrTsconfigPath Either the compiler options or the path to a tsconfig\n * file.\n */\n constructor(optionsOrTsconfigPath: ts.CompilerOptions | string, readonly helpers?: H) {\n this.compilerOptions =\n typeof optionsOrTsconfigPath === 'string'\n ? readCompilerOptions(optionsOrTsconfigPath)\n : optionsOrTsconfigPath;\n\n // Adds outDir to allows multiple files to be written\n this.compilerOptions.outDir ??= '/';\n // Generates following d.ts declaration files.\n this.compilerOptions.declaration ??= true;\n // Sets default compiler options for nodejs bundling\n this.compilerOptions.moduleResolution ??= ts.ModuleResolutionKind.NodeJs;\n this.compilerOptions.module ??= ts.ModuleKind.CommonJS;\n this.compilerOptions.target ??= ts.ScriptTarget.ES2022;\n\n this.host = ts.createCompilerHost(this.compilerOptions, false);\n this.host.readFile = (file) => this.sources[file]?.join('');\n this.host.writeFile = (file, content) =>\n (this.outputs[\n // Normalize paths to avoid inconsistency\n this.compilerOptions.outDir\n ? path.relative(this.compilerOptions.outDir, file)\n : file\n ] = content);\n }\n\n /**\n * Collects all the written files and uses typescript to transpile them.\n *\n * @returns The result of the transpilation from typescript.\n */\n transpile() {\n // Flush the outputs before transpiling (maybe) again\n this.outputs = {};\n\n ts.createProgram(\n // Gets all source filenames\n Object.keys(this.sources),\n this.compilerOptions,\n this.host\n ).emit();\n\n return this.outputs;\n }\n\n /**\n * Generates the code to be written in the provided file. The first argument is an\n * object with the variables to be used in the template, as well the filename. The rest\n * of the arguments are the templates to be written in the file.\n */\n write<D extends SourceTemplateData<H>, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n template: TemplateStringsArray,\n data: D,\n ...keys: Commands<P[number], D & { helpers: H }>[]\n ) {\n data.helpers ??= this.helpers;\n\n (this.sources[data.filename] ??= []).push(\n t(template, data as D & { helpers: H }, ...keys)\n );\n }\n\n /**\n * Generates the code to be written **ON TOP** in the provided file. The first argument\n * is an object with the variables to be used in the template, as well the filename. The\n * rest of the arguments are the templates to be written in the file.\n */\n head<D extends SourceTemplateData<H>, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n template: TemplateStringsArray,\n data: D,\n ...keys: Commands<P[number], D & { helpers: H }>[]\n ) {\n data.helpers ??= this.helpers;\n\n (this.sources[data.filename] ??= []).unshift(\n t(template, data as D & { helpers: H }, ...keys)\n );\n }\n\n /**\n * Generates the code to be written in the provided file **ONLY IF NOT ALREADY\n * WRITTEN**. The first argument is an object with the variables to be used in the\n * template, as well the filename. The rest of the arguments are the templates to be\n * written in the file.\n */\n writeUnique<D extends SourceTemplateData<H>, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n template: TemplateStringsArray,\n data: D,\n ...keys: Commands<P[number], D & { helpers: H }>[]\n ) {\n data.helpers ??= this.helpers;\n\n const str = t(template, data as D & { helpers: H }, ...keys);\n const file = (this.sources[data.filename] ??= []);\n\n if (!file.includes(str)) {\n file.push(str);\n }\n }\n\n /**\n * Generates the code to be written **ON TOP** in the provided file **ONLY IF NOT\n * ALREADY WRITTEN**. The first argument is an object with the variables to be used in\n * the template, as well the filename. The rest of the arguments are the templates to be\n * written in the file.\n */\n headUnique<D extends SourceTemplateData<H>, P extends KeysOf<Omit<D, 'helpers'>>[]>(\n template: TemplateStringsArray,\n data: D,\n ...keys: Commands<P[number], D & { helpers: H }>[]\n ) {\n data.helpers ??= this.helpers;\n\n const str = t(template, data as D & { helpers: H }, ...keys);\n const file = (this.sources[data.filename] ??= []);\n\n if (!file.includes(str)) {\n file.unshift(str);\n }\n }\n}\n"],"names":["findCommandEnd","command","keys","index","deep","length","key","Error","findElseClause","indexObject","path","data","paths","split","p","startsWith","replaceArrayIndexes","argument","symbol","mappedKeys","Array","i","slice","stringify","value","javascriptStringify","String","consume","start","end","templates","code","result","consumeStep","undefined","nextIndex","template","helperName","helpers","helper","h","array","isArray","eachEndIndex","arrayIndex","condition","slicedKeys","ifEndIndex","elseRelativeIndex","t","_template","prefix","shift","trim","trimStart","trimEnd","readCompilerOptions","tsconfigPath","res","ts","readConfigFile","sys","readFile","error","parseJsonConfigFileContent","config","dirname","errors","options","constructor","optionsOrTsconfigPath","_this$compilerOptions","_this$compilerOptions3","_this$compilerOptions5","_this$compilerOptions7","_this$compilerOptions9","this","sources","outputs","host","compilerOptions","outDir","declaration","moduleResolution","ModuleResolutionKind","NodeJs","_this$compilerOptions8","module","ModuleKind","CommonJS","_this$compilerOptions10","target","ScriptTarget","ES2022","createCompilerHost","file","_this$sources$file","join","writeFile","content","relative","transpile","createProgram","Object","emit","write","_this$sources","_data$filename","_this$sources$_data$f","filename","push","head","_this$sources2","_data$filename2","_this$sources2$_data$","unshift","writeUnique","_data$helpers3","_this$sources3","_data$filename3","_this$sources3$_data$","str","includes","headUnique","_data$helpers4","_this$sources4","_data$filename4","_this$sources4$_data$"],"mappings":"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"}
\No newline at end of file