yamlresume 0.7.4 → 0.7.5

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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {Command}from'commander';import Q from'child_process';import L from'fs';import O from'path';import g,{consola}from'consola';import re from'which';import {YAMLResumeError,joinNonEmptyString,toCodeBlock,LOCALE_LANGUAGE_OPTIONS,getLocaleLanguageDetail,TEMPLATE_OPTIONS,getTemplateDetail,getResumeRenderer,ResumeSchema}from'@yamlresume/core';import P,{LineCounter,parseDocument,isNode}from'yaml';import a from'chalk';import ie from'chokidar';import {coalesce}from'coalescifn';import {fileURLToPath}from'url';import {markdownTable}from'markdown-table';var I={version:"0.7.4"};function z(e,t,r){let o=r.split(`
2
+ import {Command}from'commander';import Q from'child_process';import L from'fs';import O from'path';import g,{consola}from'consola';import re from'which';import {YAMLResumeError,joinNonEmptyString,toCodeBlock,LOCALE_LANGUAGE_OPTIONS,getLocaleLanguageDetail,TEMPLATE_OPTIONS,getTemplateDetail,getResumeRenderer,ResumeSchema}from'@yamlresume/core';import P,{LineCounter,parseDocument,isNode}from'yaml';import a from'chalk';import ie from'chokidar';import {coalesce}from'coalescifn';import {fileURLToPath}from'url';import {markdownTable}from'markdown-table';var I={version:"0.7.5"};function z(e,t,r){let o=r.split(`
3
3
  `)[e.line-1]||"",s=`${" ".repeat(e.column-1)}^`,m=a.white.bold(`${t}:${e.line}:${e.column}`),i=a.red.bold("warning"),c=a.white(e.message),u=a.white(o),d=a.green.bold(s);return [`${m}: ${i}: ${c}`,`${u}`,`${d}`].join(`
4
4
  `)}function H(e,t,r){let n=e.match(/at line (\d+), column (\d+)/);if(!n)return joinNonEmptyString([a.white.bold(t),a.red.bold("error"),`${a.white(e)}.`],": ");let o=Number.parseInt(n[1],10),s=Number.parseInt(n[2],10),i=r.split(`
5
5
  `)[o-1]||"",c=`${" ".repeat(s-1)}^`,u=a.white.bold(`${t}:${o}:${s}`),d=a.red.bold("error"),_=a.white(e.split(`
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/commands/validate.ts","../src/commands/build.ts","../src/commands/dev.ts","../src/commands/new.ts","../src/commands/languages.ts","../src/commands/templates.ts","../src/utils/consola.ts","../src/program.ts","../src/cli.ts"],"names":["package_default","prettifySchemaValidationError","error","resumePath","resumeStr","lineContent","pointer","filePath","chalk","errorType","message","codeLine","pointerLine","prettifyYamlParseError","errorMessage","lineMatch","joinNonEmptyString","line","column","validateResume","yamlStr","schema","lineCounter","LineCounter","resumeCST","parseDocument","validationResult","issues","issue","path","node","isNode","startOffset","pos","a","b","readResume","resuemPath","validate","fs","YAMLResumeError","resume","yaml","formattedError","errors","ResumeSchema","createValidateCommand","Command","validated","consola","inferOutput","extname","isCommandAvailable","command","which","inferLaTeXEnvironment","inferLaTeXCommand","environment","destination","generateTeX","texFile","tex","getResumeRenderer","buildResume","options","stdout","child_process","toCodeBlock","createBuildCommand","watchResume","pdf","exclusiveBuild","coalesce","watcher","chokidar","createDevCommand","newResume","filename","templatePath","fileURLToPath","templateContent","createNewCommand","listLanguages","markdownTable","LOCALE_LANGUAGE_OPTIONS","value","getLocaleLanguageDetail","createLanguagesCommand","cmd","listTemplates","TEMPLATE_OPTIONS","details","getTemplateDetail","createTemplatesCommand","setVerboseLog","verbose","createProgram","program","thisCommand"],"mappings":"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","file":"cli.js","sourcesContent":["{\n \"name\": \"yamlresume\",\n \"version\": \"0.7.4\",\n \"description\": \"The CLI interface for YAMLResume's engine\",\n \"license\": \"MIT\",\n \"author\": {\n \"name\": \"YAMLResume\",\n \"email\": \"support@yamlresume.com\",\n \"url\": \"https://yamlresume.dev\"\n },\n \"keywords\": [\n \"YAMLResume\",\n \"CV\",\n \"Resume\",\n \"LaTeX\",\n \"Typesetting\",\n \"PDF\",\n \"YAML\",\n \"JSON\"\n ],\n \"type\": \"module\",\n \"bin\": {\n \"yamlresume\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"resources/resume.yml\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"build:clean\": \"rm -rf dist\",\n \"build:prod\": \"tsup --dts --minify --sourcemap\",\n \"prepublishOnly\": \"pnpm test\",\n \"dev\": \"tsx src/cli.ts\",\n \"test\": \"vitest --run\",\n \"test:cov\": \"vitest --coverage --run\",\n \"test:watch\": \"vitest\"\n },\n \"dependencies\": {\n \"@yamlresume/core\": \"workspace:*\",\n \"chalk\": \"^5.4.1\",\n \"chokidar\": \"^4.0.3\",\n \"coalescifn\": \"^0.1.0\",\n \"commander\": \"^14.0.0\",\n \"consola\": \"^3.4.2\",\n \"extensionless\": \"^1.9.9\",\n \"lodash-es\": \"^4.17.21\",\n \"markdown-table\": \"^3.0.4\",\n \"tslib\": \"^2.8.1\",\n \"which\": \"^5.0.0\",\n \"yaml\": \"^2.8.1\"\n },\n \"devDependencies\": {\n \"@types/chalk\": \"^2.2.4\",\n \"@types/commander\": \"^2.12.5\",\n \"@types/lodash-es\": \"^4.17.12\",\n \"@types/which\": \"^3.0.4\",\n \"tsx\": \"^4.19.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/yamlresume/yamlresume.git\",\n \"directory\": \"packages/cli\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/yamlresume/yamlresume/issues\"\n },\n \"homepage\": \"https://yamlresume.dev/docs/cli\",\n \"engines\": {\n \"node\": \">=20.0.0\"\n }\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport fs from 'node:fs'\nimport yaml from 'yaml'\n\nimport {\n type Resume,\n ResumeSchema,\n YAMLResumeError,\n joinNonEmptyString,\n} from '@yamlresume/core'\nimport chalk from 'chalk'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { LineCounter, isNode, parseDocument } from 'yaml'\n\n/**\n * A positional error with line number, column number, and path.\n *\n * @param message The error message.\n * @param line The line number.\n * @param column The column number.\n * @param path The path to the error.\n */\nexport interface PositionalError {\n message: string\n line: number\n column: number\n path: (string | number | symbol)[]\n}\n\n/**\n * Formats an error in clang-style with line number, column pointer, and message\n *\n * @param error The positional error to format\n * @param resumePath The source file path\n * @param resumeStr The content of the source file for line display\n * @returns Formatted error string in clang style\n */\nexport function prettifySchemaValidationError(\n error: PositionalError,\n resumePath: string,\n resumeStr: string\n): string {\n const lines = resumeStr.split('\\n')\n const lineContent = lines[error.line - 1] || ''\n\n // Create the pointer line with spaces and caret\n const pointer = `${' '.repeat(error.column - 1)}^`\n\n // Color scheme similar to clang with enhanced visibility\n const filePath = chalk.white.bold(\n `${resumePath}:${error.line}:${error.column}`\n )\n const errorType = chalk.red.bold('warning')\n const message = chalk.white(error.message)\n const codeLine = chalk.white(lineContent)\n const pointerLine = chalk.green.bold(pointer)\n\n return [\n `${filePath}: ${errorType}: ${message}`,\n `${codeLine}`,\n `${pointerLine}`,\n ].join('\\n')\n}\n\n/**\n * Parses YAML parsing error messages and extracts line/column information\n *\n * @param errorMessage The error message from `yaml.parse`\n * @param resumePath The source file path\n * @param resumeStr The content of the source file for line display\n * @returns Formatted error string in clang style\n */\nexport function prettifyYamlParseError(\n errorMessage: string,\n resumePath: string,\n resumeStr: string\n): string {\n // parse the error message to extract line and column\n // example:\n // \"Nested mappings are not allowed in compact mappings at line 6, column 10\"\n const lineMatch = errorMessage.match(/at line (\\d+), column (\\d+)/)\n\n if (!lineMatch) {\n // if we can't parse the error, return a simple formatted message\n return joinNonEmptyString(\n [\n chalk.white.bold(resumePath),\n chalk.red.bold('error'),\n `${chalk.white(errorMessage)}.`,\n ],\n ': '\n )\n }\n\n const line = Number.parseInt(lineMatch[1], 10)\n const column = Number.parseInt(lineMatch[2], 10)\n const lines = resumeStr.split('\\n')\n const lineContent = lines[line - 1] || ''\n\n // create the pointer line with spaces and caret\n const pointer = `${' '.repeat(column - 1)}^`\n\n // color scheme similar to clang with enhanced visibility\n const filePath = chalk.white.bold(`${resumePath}:${line}:${column}`)\n const errorType = chalk.red.bold('error')\n const message = chalk.white(\n errorMessage\n .split('\\n')[0]\n .replace(/ at line \\d+, column \\d+:?/, '.')\n .trim()\n )\n const codeLine = chalk.white(lineContent)\n const pointerLine = chalk.green.bold(pointer)\n\n return [\n `${filePath}: ${errorType}: ${message}`,\n `${codeLine}`,\n `${pointerLine}`,\n ].join('\\n')\n}\n\n/**\n * Validates a YAML string against a Zod schema and returns errors.\n *\n * @param yamlStr The YAML string to validate.\n * @param schema The Zod schema to validate against.\n * @returns A list of positional errors, or an empty array if validation is\n * successful.\n */\nexport function validateResume(\n yamlStr: string,\n schema: typeof ResumeSchema\n): PositionalError[] {\n const lineCounter = new LineCounter()\n\n // CST: Concrete Syntax Tree\n const resumeCST = parseDocument(yamlStr, {\n lineCounter,\n keepSourceTokens: true,\n })\n\n const validationResult = schema.safeParse(resumeCST.toJS())\n\n if (validationResult.success) {\n return []\n }\n\n const {\n error: { issues },\n } = validationResult\n\n return issues\n .map((issue) => {\n const path = issue.path\n const node = resumeCST.getIn(path, true)\n\n let line = 1\n let column = 1\n\n if (isNode(node) && node.range) {\n const startOffset = node.range[0]\n const pos = lineCounter.linePos(startOffset)\n line = pos.line\n column = pos.col\n }\n\n return {\n message: issue.message,\n line,\n column,\n path,\n }\n })\n .sort((a, b) => a.line - b.line)\n}\n\n/**\n * Read the resume from the source file and validate it on request.\n *\n * Steps:\n *\n * 1. read the resume from the source file\n * 2. validate the resume with `yaml.parse`\n * 3. if `validate` is true, validate the resume with `ResumeSchema`\n *\n * @param resuemPath - The source resume file path (YAML, YML, or JSON).\n * @returns The resume object.\n * @throws {Error} If the source file cannot be read or is invalid.\n */\nexport function readResume(\n resuemPath: string,\n validate = true\n): { resume: Resume; validated: 'success' | 'failed' | 'unknown' } {\n let resumeStr: string\n\n try {\n resumeStr = fs.readFileSync(resuemPath, 'utf8')\n } catch (error) {\n throw new YAMLResumeError('FILE_READ_ERROR', { path: resuemPath })\n }\n\n let resume: Resume\n\n try {\n resume = yaml.parse(resumeStr) as Resume\n } catch (error) {\n // Format YAML parsing errors in clang style\n //\n // Actually you can use `parseDocument` to get a list of errors, here we\n // only use `yaml.parse` to get the first error, which should be enough for\n // users to know that there is something wrong with the yaml file.\n const formattedError = prettifyYamlParseError(\n error.message,\n resuemPath,\n resumeStr\n )\n\n console.log(formattedError)\n throw new YAMLResumeError('INVALID_YAML', {\n error: `Failed to parse ${resuemPath}.`,\n })\n }\n\n if (validate) {\n const errors = validateResume(resumeStr, ResumeSchema)\n\n if (errors.length > 0) {\n for (const error of errors) {\n console.log(prettifySchemaValidationError(error, resuemPath, resumeStr))\n }\n\n return { resume, validated: 'failed' }\n }\n\n return { resume, validated: 'success' }\n }\n\n return { resume, validated: 'unknown' }\n}\n\n/**\n * Create a command instance to validate a YAML resume\n */\nexport function createValidateCommand() {\n return new Command()\n .name('validate')\n .description('validate a resume against the YAMLResume schema')\n .argument('<resume-path>', 'the resume file path')\n .action(async (resumePath: string) => {\n try {\n const { validated } = readResume(resumePath, true)\n\n if (validated === 'success') {\n consola.success('Resume validation passed.')\n }\n if (validated === 'failed') {\n consola.fail('Resume validation failed.')\n }\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n })\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport child_process from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\nimport which from 'which'\n\nimport {\n type Resume,\n YAMLResumeError,\n getResumeRenderer,\n joinNonEmptyString,\n toCodeBlock,\n} from '@yamlresume/core'\n\nimport { readResume } from './validate'\n\n/**\n * Infer the output file name from the source file name\n *\n * For now we support yaml, yml and json file extensions, and the output file\n * will have a `.tex` extension.\n *\n * @param resumePath - The source resume file\n * @returns The output file name\n * @throws {Error} If the source file has an unsupported extension.\n */\nexport function inferOutput(resumePath: string): string {\n const extname = path.extname(resumePath)\n\n if (\n resumePath.endsWith('.yaml') ||\n resumePath.endsWith('.yml') ||\n resumePath.endsWith('.json')\n ) {\n return resumePath.replace(/\\.yaml|\\.yml|\\.json$/, '.tex')\n }\n\n throw new YAMLResumeError('INVALID_EXTNAME', { extname })\n}\n\ntype LaTeXEnvironment = 'xelatex' | 'tectonic'\n\n/**\n * Check if a command is available\n *\n * @param command - The command to check\n * @returns True if the command is available, false otherwise\n */\nexport function isCommandAvailable(command: string): boolean {\n try {\n return !!which.sync(command)\n } catch {\n return false\n }\n}\n\n/**\n * Infer the LaTeX environment to use\n *\n * We support xelatex and tectonic, if both are installed we will prioritize\n * xelatex.\n *\n * @returns The LaTeX environment PATH.\n * @throws {Error} If neither 'xelatex' nor 'tectonic' is found in system PATH.\n */\nexport function inferLaTeXEnvironment(): LaTeXEnvironment {\n if (isCommandAvailable('xelatex')) {\n return 'xelatex'\n }\n\n if (isCommandAvailable('tectonic')) {\n return 'tectonic'\n }\n\n throw new YAMLResumeError('LATEX_NOT_FOUND', {})\n}\n\n/**\n * Infer the LaTeX command to use based on the LaTeX environment\n *\n * @param resumePath - The source resume file\n * @returns The LaTeX command\n * @throws {Error} If the LaTeX environment cannot be inferred or the source\n * file extension is unsupported.\n */\nexport function inferLaTeXCommand(resumePath: string): string {\n const environment = inferLaTeXEnvironment()\n const destination = inferOutput(resumePath)\n\n switch (environment) {\n case 'xelatex':\n return `xelatex -halt-on-error ${destination}`\n case 'tectonic':\n return `tectonic ${destination}`\n }\n}\n\n/**\n * Compiles the resume source file to a LaTeX file.\n *\n * @param resumePath - The source resume file path (YAML, YML, or JSON).\n * @param resume - The parsed resume object.\n * @remarks This function performs file I/O: writes a .tex file.\n * @throws {Error} Can throw if rendering or writing fails.\n */\nexport function generateTeX(resumePath: string, resume: Resume) {\n // make sure the file has an valid extension, i.e, '.json', '.yml' or '.yaml'\n const texFile = inferOutput(resumePath)\n\n const renderer = getResumeRenderer(resume)\n const tex = renderer.render()\n\n try {\n fs.writeFileSync(texFile, tex)\n } catch (error) {\n throw new YAMLResumeError('FILE_WRITE_ERROR', { path: texFile })\n }\n}\n\n/**\n * Build a YAML resume to LaTeX & PDF\n *\n * It first validates the resume against the schema (unless `--no-validate` flag\n * is used), then generates the .tex file (using `generateTeX`) and then runs\n * the inferred LaTeX command (e.g., xelatex or tectonic) to produce the PDF.\n *\n * Steps:\n * 1. read the resume from the source file\n * 2. validate the resume against YAMLResume schema (unless `--no-validate`)\n * 3. infer the LaTeX command to use\n * 3.1. infer the LaTeX environment to use\n * 3.2. infer the output destination\n * 4. build the resume to LaTeX and PDF at the same time\n *\n * @param resumePath - The source resume file path (YAML, YML, or JSON).\n * @param options - Build options including validation and PDF generation flags.\n * @remarks This function performs file I/O (via `generateTeX`) and executes an\n * external process (LaTeX compiler).\n * @throws {Error} Can throw if .tex generation, LaTeX command inference, or the\n * LaTeX compilation process fails.\n */\nexport function buildResume(\n resumePath: string,\n options: { pdf?: boolean; validate?: boolean } = { pdf: true, validate: true }\n) {\n const { resume } = readResume(resumePath, options.validate)\n\n generateTeX(resumePath, resume)\n\n if (!options.pdf) {\n consola.success('Generated resume TeX file successfully.')\n return\n }\n\n const command = inferLaTeXCommand(resumePath)\n consola.start(`Generating resume PDF file with command: \\`${command}\\`...`)\n\n try {\n const stdout = child_process.execSync(command, { encoding: 'utf8' })\n consola.success('Generated resume PDF file successfully.')\n consola.debug(joinNonEmptyString(['stdout: ', toCodeBlock(stdout)]))\n } catch (error) {\n consola.debug(joinNonEmptyString(['stdout: ', toCodeBlock(error.stdout)]))\n consola.debug(joinNonEmptyString(['stderr: ', toCodeBlock(error.stderr)]))\n throw new YAMLResumeError('LATEX_COMPILE_ERROR', { error: error.message })\n }\n}\n\n/**\n * Create a command instance to build a YAML resume to LaTeX and PDF\n */\nexport function createBuildCommand() {\n return new Command()\n .name('build')\n .description('build a resume to LaTeX and PDF')\n .argument('<resume-path>', 'the resume file path')\n .option('--no-pdf', 'only generate TeX file without PDF')\n .option('--no-validate', 'skip resume schema validation')\n .action(\n async (\n resumePath: string,\n options: { pdf: boolean; validate: boolean }\n ) => {\n try {\n buildResume(resumePath, options)\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n }\n )\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport chokidar from 'chokidar'\n\nimport { coalesce } from 'coalescifn'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\n\nimport { buildResume } from './build'\n\n/**\n * Options for the watchResume function\n *\n * @param pdf - Whether to generate PDF\n * @param validate - Whether to validate the resume\n */\ntype WatchOptions = {\n pdf?: boolean\n validate?: boolean\n}\n\n/**\n * Watch a resume source file and rebuild on changes.\n *\n * - Only one build runs at a time.\n * - If multiple events arrive during a build, run exactly one more build after\n * it finishes (coalesce bursts).\n * - Uses chokidar for robust file watching that handles editor operations.\n *\n * @param resumePath - The resume file to watch\n * @param options - Build and watch options\n * @returns Chokidar watcher instance\n */\nexport function watchResume(\n resumePath: string,\n options: WatchOptions = { pdf: true, validate: true }\n) {\n const { pdf, validate } = options\n\n // there should be only one build running at a time\n const exclusiveBuild = coalesce(() =>\n buildResume(resumePath, { pdf, validate })\n )\n\n // initial build\n exclusiveBuild()\n\n consola.start(`Watching file changes: ${resumePath}...`)\n\n // use chokidar for robust file watching that handles vim and other editors\n // properly.\n //\n // vim will save the file in a single atomic operation, that being said, it\n // will first create a temporary file (the '.swp' file), then rename it to the\n // final file.\n //\n // Node.js `fs.watch` has trouble with this, so we use chokidar instead.\n const watcher = chokidar.watch(resumePath, {\n awaitWriteFinish: {\n stabilityThreshold: 200, // wait 200ms after file stops changing\n pollInterval: 200, // check every 200ms\n },\n ignoreInitial: true, // don't trigger on initial file discovery\n })\n\n // handle file changes - chokidar's awaitWriteFinish already handles\n // debouncing\n watcher.on('change', () => exclusiveBuild())\n\n // handle file additions (in case file gets recreated)\n watcher.on('add', () => exclusiveBuild())\n\n return watcher\n}\n\n/**\n * Create a command instance to run in watch mode\n */\nexport function createDevCommand() {\n return new Command()\n .name('dev')\n .description('build a resume on file changes (watch mode)')\n .argument('<resume-path>', 'the resume file path')\n .option('--no-pdf', 'only generate TeX file without PDF')\n .option('--no-validate', 'skip resume schema validation')\n .action(\n (resumePath: string, options: { pdf: boolean; validate: boolean }) => {\n watchResume(resumePath, options)\n }\n )\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { Command } from 'commander'\nimport consola from 'consola'\n\nimport {\n YAMLResumeError,\n joinNonEmptyString,\n toCodeBlock,\n} from '@yamlresume/core'\n\n/**\n * Creates a new resume file with the given filename\n *\n * @param filename - The name of the resume file to create\n * @throws {YAMLResumeError} When there are file-related errors:\n * - FILE_CONFLICT: When the file already exists\n * - FILE_READ_ERROR: When there's an error reading the template\n * - FILE_WRITE_ERROR: When there's an error writing the file\n */\nexport function newResume(filename: string) {\n if (fs.existsSync(filename)) {\n throw new YAMLResumeError('FILE_CONFLICT', { path: filename })\n }\n\n const templatePath = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n /* v8 ignore start */\n // I din't find a way to mock `import.meta.url` in tests so we have to\n // ignore the following lines for coverage calculation\n import.meta.url.includes('dist')\n ? '../resources/resume.yml'\n : '../../resources/resume.yml'\n /* v8 ignore stop */\n )\n\n let templateContent: string\n\n try {\n templateContent = fs.readFileSync(templatePath, 'utf8')\n } catch (error) {\n consola.debug(\n joinNonEmptyString(['Error reading template: ', toCodeBlock(error.stack)])\n )\n throw new YAMLResumeError('FILE_READ_ERROR', { path: templatePath })\n }\n\n try {\n fs.writeFileSync(filename, templateContent)\n consola.success(`Created ${filename} successfully.`)\n } catch (error) {\n consola.debug(\n joinNonEmptyString(['Error creating resume: ', toCodeBlock(error.stack)])\n )\n throw new YAMLResumeError('FILE_WRITE_ERROR', { path: filename })\n }\n}\n\n/**\n * Create a command instance to create a new YAML resume\n */\nexport function createNewCommand() {\n return new Command()\n .name('new')\n .description('create a new resume')\n .argument('[filename]', 'output filename', 'resume.yml')\n .action((filename) => {\n try {\n newResume(filename)\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n })\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n LOCALE_LANGUAGE_OPTIONS,\n getLocaleLanguageDetail,\n} from '@yamlresume/core'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { markdownTable } from 'markdown-table'\n\n/**\n * Generates a markdown table listing all supported locale languages.\n *\n * The table includes columns for the language code and the language name.\n *\n * @returns A string containing the formatted markdown table.\n */\nexport function listLanguages() {\n return markdownTable([\n ['layout.locale.language', 'Language Name'],\n ...LOCALE_LANGUAGE_OPTIONS.map((value) => [\n value,\n getLocaleLanguageDetail(value).name,\n ]),\n ])\n}\n\n/**\n * Create a command instance to list supported languages\n */\n\nexport function createLanguagesCommand() {\n const cmd = new Command()\n .name('languages')\n .description('i18n and l10n support')\n\n cmd\n .command('list')\n .description('list all supported languages')\n .action(() => {\n consola.log(listLanguages())\n })\n\n return cmd\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { TEMPLATE_OPTIONS, getTemplateDetail } from '@yamlresume/core'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { markdownTable } from 'markdown-table'\n\n/**\n * Generates a markdown table listing all supported templates.\n *\n * The table includes columns for the template id, name and description.\n *\n * @returns A string containing the formatted markdown table.\n */\nexport function listTemplates() {\n return markdownTable([\n ['layout.template', 'Template Name', 'Description'],\n ...TEMPLATE_OPTIONS.map((value) => {\n const details = getTemplateDetail(value)\n return [value, details.name, details.description]\n }),\n ])\n}\n\n/**\n * Create a command instance to list supported templates\n */\nexport function createTemplatesCommand() {\n const cmd = new Command()\n .name('templates')\n .description('manage resume templates')\n\n cmd\n .command('list')\n .description('list all supported templates')\n .action(() => {\n consola.log(listTemplates())\n })\n\n return cmd\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport consola from 'consola'\n\n/**\n * Set the verbose mode for consola\n *\n * @param verbose - Whether to enable verbose mode\n * @see https://github.com/unjs/consola?tab=readme-ov-file#log-level\n */\nexport function setVerboseLog(verbose: boolean) {\n consola.level = verbose ? 4 : 3\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Command } from 'commander'\n\nimport packageJson from '../package.json' with { type: 'json' }\nimport {\n createBuildCommand,\n createDevCommand,\n createLanguagesCommand,\n createNewCommand,\n createTemplatesCommand,\n createValidateCommand,\n} from './commands'\nimport { setVerboseLog } from './utils'\n\n/**\n * Create the CLI program.\n *\n * @returns The CLI program.\n */\nexport function createProgram(): Command {\n const program = new Command()\n\n const banner = `\n __ __ _ __ __ _ ____\n \\\\ \\\\ / // \\\\ | \\\\/ | | | _ \\\\ ___ ___ _ _ ___ ___ ___\n \\\\ V // _ \\\\ | |\\\\/| | | | |_) / _ \\\\/ __| | | / _ \\\\/ _ \\\\ / _ \\\\\n | |/ ___ \\\\| | | | |___| _ < __/\\\\__ \\\\ |_| | | | | | | __/\n |_/_/ \\\\_\\\\_| |_|_____|_| \\\\_\\\\___||___/\\\\____|_| |_| |_|\\\\___|\n`\n\n program\n .name('yamlresume')\n .description(['YAMLResume — Resume as Code in YAML', banner].join('\\n'))\n .version(packageJson.version)\n .option('-v, --verbose', 'verbose output')\n .hook('preAction', (thisCommand) => {\n setVerboseLog(thisCommand.opts().verbose)\n })\n\n program.addCommand(createNewCommand())\n program.addCommand(createBuildCommand())\n program.addCommand(createDevCommand())\n program.addCommand(createLanguagesCommand())\n program.addCommand(createTemplatesCommand())\n program.addCommand(createValidateCommand())\n\n return program\n}\n","#!/usr/bin/env node\n/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { createProgram } from './program'\n\ncreateProgram().parse()\n"]}
1
+ {"version":3,"sources":["../package.json","../src/commands/validate.ts","../src/commands/build.ts","../src/commands/dev.ts","../src/commands/new.ts","../src/commands/languages.ts","../src/commands/templates.ts","../src/utils/consola.ts","../src/program.ts","../src/cli.ts"],"names":["package_default","prettifySchemaValidationError","error","resumePath","resumeStr","lineContent","pointer","filePath","chalk","errorType","message","codeLine","pointerLine","prettifyYamlParseError","errorMessage","lineMatch","joinNonEmptyString","line","column","validateResume","yamlStr","schema","lineCounter","LineCounter","resumeCST","parseDocument","validationResult","issues","issue","path","node","isNode","startOffset","pos","a","b","readResume","resuemPath","validate","fs","YAMLResumeError","resume","yaml","formattedError","errors","ResumeSchema","createValidateCommand","Command","validated","consola","inferOutput","extname","isCommandAvailable","command","which","inferLaTeXEnvironment","inferLaTeXCommand","environment","destination","generateTeX","texFile","tex","getResumeRenderer","buildResume","options","stdout","child_process","toCodeBlock","createBuildCommand","watchResume","pdf","exclusiveBuild","coalesce","watcher","chokidar","createDevCommand","newResume","filename","templatePath","fileURLToPath","templateContent","createNewCommand","listLanguages","markdownTable","LOCALE_LANGUAGE_OPTIONS","value","getLocaleLanguageDetail","createLanguagesCommand","cmd","listTemplates","TEMPLATE_OPTIONS","details","getTemplateDetail","createTemplatesCommand","setVerboseLog","verbose","createProgram","program","thisCommand"],"mappings":"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","file":"cli.js","sourcesContent":["{\n \"name\": \"yamlresume\",\n \"version\": \"0.7.5\",\n \"description\": \"The CLI interface for YAMLResume's engine\",\n \"license\": \"MIT\",\n \"author\": {\n \"name\": \"YAMLResume\",\n \"email\": \"support@yamlresume.com\",\n \"url\": \"https://yamlresume.dev\"\n },\n \"keywords\": [\n \"YAMLResume\",\n \"CV\",\n \"Resume\",\n \"LaTeX\",\n \"Typesetting\",\n \"PDF\",\n \"YAML\",\n \"JSON\"\n ],\n \"type\": \"module\",\n \"bin\": {\n \"yamlresume\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"resources/resume.yml\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"build:clean\": \"rm -rf dist\",\n \"build:prod\": \"tsup --dts --minify --sourcemap\",\n \"prepublishOnly\": \"pnpm test\",\n \"dev\": \"tsx src/cli.ts\",\n \"test\": \"vitest --run\",\n \"test:cov\": \"vitest --coverage --run\",\n \"test:watch\": \"vitest\"\n },\n \"dependencies\": {\n \"@yamlresume/core\": \"workspace:*\",\n \"chalk\": \"^5.4.1\",\n \"chokidar\": \"^4.0.3\",\n \"coalescifn\": \"^0.1.0\",\n \"commander\": \"^14.0.0\",\n \"consola\": \"^3.4.2\",\n \"extensionless\": \"^1.9.9\",\n \"lodash-es\": \"^4.17.21\",\n \"markdown-table\": \"^3.0.4\",\n \"tslib\": \"^2.8.1\",\n \"which\": \"^5.0.0\",\n \"yaml\": \"^2.8.1\"\n },\n \"devDependencies\": {\n \"@types/chalk\": \"^2.2.4\",\n \"@types/commander\": \"^2.12.5\",\n \"@types/lodash-es\": \"^4.17.12\",\n \"@types/which\": \"^3.0.4\",\n \"tsx\": \"^4.19.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/yamlresume/yamlresume.git\",\n \"directory\": \"packages/cli\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/yamlresume/yamlresume/issues\"\n },\n \"homepage\": \"https://yamlresume.dev/docs/cli\",\n \"engines\": {\n \"node\": \">=20.0.0\"\n }\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport fs from 'node:fs'\nimport yaml from 'yaml'\n\nimport {\n type Resume,\n ResumeSchema,\n YAMLResumeError,\n joinNonEmptyString,\n} from '@yamlresume/core'\nimport chalk from 'chalk'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { LineCounter, isNode, parseDocument } from 'yaml'\n\n/**\n * A positional error with line number, column number, and path.\n *\n * @param message The error message.\n * @param line The line number.\n * @param column The column number.\n * @param path The path to the error.\n */\nexport interface PositionalError {\n message: string\n line: number\n column: number\n path: (string | number | symbol)[]\n}\n\n/**\n * Formats an error in clang-style with line number, column pointer, and message\n *\n * @param error The positional error to format\n * @param resumePath The source file path\n * @param resumeStr The content of the source file for line display\n * @returns Formatted error string in clang style\n */\nexport function prettifySchemaValidationError(\n error: PositionalError,\n resumePath: string,\n resumeStr: string\n): string {\n const lines = resumeStr.split('\\n')\n const lineContent = lines[error.line - 1] || ''\n\n // Create the pointer line with spaces and caret\n const pointer = `${' '.repeat(error.column - 1)}^`\n\n // Color scheme similar to clang with enhanced visibility\n const filePath = chalk.white.bold(\n `${resumePath}:${error.line}:${error.column}`\n )\n const errorType = chalk.red.bold('warning')\n const message = chalk.white(error.message)\n const codeLine = chalk.white(lineContent)\n const pointerLine = chalk.green.bold(pointer)\n\n return [\n `${filePath}: ${errorType}: ${message}`,\n `${codeLine}`,\n `${pointerLine}`,\n ].join('\\n')\n}\n\n/**\n * Parses YAML parsing error messages and extracts line/column information\n *\n * @param errorMessage The error message from `yaml.parse`\n * @param resumePath The source file path\n * @param resumeStr The content of the source file for line display\n * @returns Formatted error string in clang style\n */\nexport function prettifyYamlParseError(\n errorMessage: string,\n resumePath: string,\n resumeStr: string\n): string {\n // parse the error message to extract line and column\n // example:\n // \"Nested mappings are not allowed in compact mappings at line 6, column 10\"\n const lineMatch = errorMessage.match(/at line (\\d+), column (\\d+)/)\n\n if (!lineMatch) {\n // if we can't parse the error, return a simple formatted message\n return joinNonEmptyString(\n [\n chalk.white.bold(resumePath),\n chalk.red.bold('error'),\n `${chalk.white(errorMessage)}.`,\n ],\n ': '\n )\n }\n\n const line = Number.parseInt(lineMatch[1], 10)\n const column = Number.parseInt(lineMatch[2], 10)\n const lines = resumeStr.split('\\n')\n const lineContent = lines[line - 1] || ''\n\n // create the pointer line with spaces and caret\n const pointer = `${' '.repeat(column - 1)}^`\n\n // color scheme similar to clang with enhanced visibility\n const filePath = chalk.white.bold(`${resumePath}:${line}:${column}`)\n const errorType = chalk.red.bold('error')\n const message = chalk.white(\n errorMessage\n .split('\\n')[0]\n .replace(/ at line \\d+, column \\d+:?/, '.')\n .trim()\n )\n const codeLine = chalk.white(lineContent)\n const pointerLine = chalk.green.bold(pointer)\n\n return [\n `${filePath}: ${errorType}: ${message}`,\n `${codeLine}`,\n `${pointerLine}`,\n ].join('\\n')\n}\n\n/**\n * Validates a YAML string against a Zod schema and returns errors.\n *\n * @param yamlStr The YAML string to validate.\n * @param schema The Zod schema to validate against.\n * @returns A list of positional errors, or an empty array if validation is\n * successful.\n */\nexport function validateResume(\n yamlStr: string,\n schema: typeof ResumeSchema\n): PositionalError[] {\n const lineCounter = new LineCounter()\n\n // CST: Concrete Syntax Tree\n const resumeCST = parseDocument(yamlStr, {\n lineCounter,\n keepSourceTokens: true,\n })\n\n const validationResult = schema.safeParse(resumeCST.toJS())\n\n if (validationResult.success) {\n return []\n }\n\n const {\n error: { issues },\n } = validationResult\n\n return issues\n .map((issue) => {\n const path = issue.path\n const node = resumeCST.getIn(path, true)\n\n let line = 1\n let column = 1\n\n if (isNode(node) && node.range) {\n const startOffset = node.range[0]\n const pos = lineCounter.linePos(startOffset)\n line = pos.line\n column = pos.col\n }\n\n return {\n message: issue.message,\n line,\n column,\n path,\n }\n })\n .sort((a, b) => a.line - b.line)\n}\n\n/**\n * Read the resume from the source file and validate it on request.\n *\n * Steps:\n *\n * 1. read the resume from the source file\n * 2. validate the resume with `yaml.parse`\n * 3. if `validate` is true, validate the resume with `ResumeSchema`\n *\n * @param resuemPath - The source resume file path (YAML, YML, or JSON).\n * @returns The resume object.\n * @throws {Error} If the source file cannot be read or is invalid.\n */\nexport function readResume(\n resuemPath: string,\n validate = true\n): { resume: Resume; validated: 'success' | 'failed' | 'unknown' } {\n let resumeStr: string\n\n try {\n resumeStr = fs.readFileSync(resuemPath, 'utf8')\n } catch (error) {\n throw new YAMLResumeError('FILE_READ_ERROR', { path: resuemPath })\n }\n\n let resume: Resume\n\n try {\n resume = yaml.parse(resumeStr) as Resume\n } catch (error) {\n // Format YAML parsing errors in clang style\n //\n // Actually you can use `parseDocument` to get a list of errors, here we\n // only use `yaml.parse` to get the first error, which should be enough for\n // users to know that there is something wrong with the yaml file.\n const formattedError = prettifyYamlParseError(\n error.message,\n resuemPath,\n resumeStr\n )\n\n console.log(formattedError)\n throw new YAMLResumeError('INVALID_YAML', {\n error: `Failed to parse ${resuemPath}.`,\n })\n }\n\n if (validate) {\n const errors = validateResume(resumeStr, ResumeSchema)\n\n if (errors.length > 0) {\n for (const error of errors) {\n console.log(prettifySchemaValidationError(error, resuemPath, resumeStr))\n }\n\n return { resume, validated: 'failed' }\n }\n\n return { resume, validated: 'success' }\n }\n\n return { resume, validated: 'unknown' }\n}\n\n/**\n * Create a command instance to validate a YAML resume\n */\nexport function createValidateCommand() {\n return new Command()\n .name('validate')\n .description('validate a resume against the YAMLResume schema')\n .argument('<resume-path>', 'the resume file path')\n .action(async (resumePath: string) => {\n try {\n const { validated } = readResume(resumePath, true)\n\n if (validated === 'success') {\n consola.success('Resume validation passed.')\n }\n if (validated === 'failed') {\n consola.fail('Resume validation failed.')\n }\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n })\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport child_process from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\nimport which from 'which'\n\nimport {\n type Resume,\n YAMLResumeError,\n getResumeRenderer,\n joinNonEmptyString,\n toCodeBlock,\n} from '@yamlresume/core'\n\nimport { readResume } from './validate'\n\n/**\n * Infer the output file name from the source file name\n *\n * For now we support yaml, yml and json file extensions, and the output file\n * will have a `.tex` extension.\n *\n * @param resumePath - The source resume file\n * @returns The output file name\n * @throws {Error} If the source file has an unsupported extension.\n */\nexport function inferOutput(resumePath: string): string {\n const extname = path.extname(resumePath)\n\n if (\n resumePath.endsWith('.yaml') ||\n resumePath.endsWith('.yml') ||\n resumePath.endsWith('.json')\n ) {\n return resumePath.replace(/\\.yaml|\\.yml|\\.json$/, '.tex')\n }\n\n throw new YAMLResumeError('INVALID_EXTNAME', { extname })\n}\n\ntype LaTeXEnvironment = 'xelatex' | 'tectonic'\n\n/**\n * Check if a command is available\n *\n * @param command - The command to check\n * @returns True if the command is available, false otherwise\n */\nexport function isCommandAvailable(command: string): boolean {\n try {\n return !!which.sync(command)\n } catch {\n return false\n }\n}\n\n/**\n * Infer the LaTeX environment to use\n *\n * We support xelatex and tectonic, if both are installed we will prioritize\n * xelatex.\n *\n * @returns The LaTeX environment PATH.\n * @throws {Error} If neither 'xelatex' nor 'tectonic' is found in system PATH.\n */\nexport function inferLaTeXEnvironment(): LaTeXEnvironment {\n if (isCommandAvailable('xelatex')) {\n return 'xelatex'\n }\n\n if (isCommandAvailable('tectonic')) {\n return 'tectonic'\n }\n\n throw new YAMLResumeError('LATEX_NOT_FOUND', {})\n}\n\n/**\n * Infer the LaTeX command to use based on the LaTeX environment\n *\n * @param resumePath - The source resume file\n * @returns The LaTeX command\n * @throws {Error} If the LaTeX environment cannot be inferred or the source\n * file extension is unsupported.\n */\nexport function inferLaTeXCommand(resumePath: string): string {\n const environment = inferLaTeXEnvironment()\n const destination = inferOutput(resumePath)\n\n switch (environment) {\n case 'xelatex':\n return `xelatex -halt-on-error ${destination}`\n case 'tectonic':\n return `tectonic ${destination}`\n }\n}\n\n/**\n * Compiles the resume source file to a LaTeX file.\n *\n * @param resumePath - The source resume file path (YAML, YML, or JSON).\n * @param resume - The parsed resume object.\n * @remarks This function performs file I/O: writes a .tex file.\n * @throws {Error} Can throw if rendering or writing fails.\n */\nexport function generateTeX(resumePath: string, resume: Resume) {\n // make sure the file has an valid extension, i.e, '.json', '.yml' or '.yaml'\n const texFile = inferOutput(resumePath)\n\n const renderer = getResumeRenderer(resume)\n const tex = renderer.render()\n\n try {\n fs.writeFileSync(texFile, tex)\n } catch (error) {\n throw new YAMLResumeError('FILE_WRITE_ERROR', { path: texFile })\n }\n}\n\n/**\n * Build a YAML resume to LaTeX & PDF\n *\n * It first validates the resume against the schema (unless `--no-validate` flag\n * is used), then generates the .tex file (using `generateTeX`) and then runs\n * the inferred LaTeX command (e.g., xelatex or tectonic) to produce the PDF.\n *\n * Steps:\n * 1. read the resume from the source file\n * 2. validate the resume against YAMLResume schema (unless `--no-validate`)\n * 3. infer the LaTeX command to use\n * 3.1. infer the LaTeX environment to use\n * 3.2. infer the output destination\n * 4. build the resume to LaTeX and PDF at the same time\n *\n * @param resumePath - The source resume file path (YAML, YML, or JSON).\n * @param options - Build options including validation and PDF generation flags.\n * @remarks This function performs file I/O (via `generateTeX`) and executes an\n * external process (LaTeX compiler).\n * @throws {Error} Can throw if .tex generation, LaTeX command inference, or the\n * LaTeX compilation process fails.\n */\nexport function buildResume(\n resumePath: string,\n options: { pdf?: boolean; validate?: boolean } = { pdf: true, validate: true }\n) {\n const { resume } = readResume(resumePath, options.validate)\n\n generateTeX(resumePath, resume)\n\n if (!options.pdf) {\n consola.success('Generated resume TeX file successfully.')\n return\n }\n\n const command = inferLaTeXCommand(resumePath)\n consola.start(`Generating resume PDF file with command: \\`${command}\\`...`)\n\n try {\n const stdout = child_process.execSync(command, { encoding: 'utf8' })\n consola.success('Generated resume PDF file successfully.')\n consola.debug(joinNonEmptyString(['stdout: ', toCodeBlock(stdout)]))\n } catch (error) {\n consola.debug(joinNonEmptyString(['stdout: ', toCodeBlock(error.stdout)]))\n consola.debug(joinNonEmptyString(['stderr: ', toCodeBlock(error.stderr)]))\n throw new YAMLResumeError('LATEX_COMPILE_ERROR', { error: error.message })\n }\n}\n\n/**\n * Create a command instance to build a YAML resume to LaTeX and PDF\n */\nexport function createBuildCommand() {\n return new Command()\n .name('build')\n .description('build a resume to LaTeX and PDF')\n .argument('<resume-path>', 'the resume file path')\n .option('--no-pdf', 'only generate TeX file without PDF')\n .option('--no-validate', 'skip resume schema validation')\n .action(\n async (\n resumePath: string,\n options: { pdf: boolean; validate: boolean }\n ) => {\n try {\n buildResume(resumePath, options)\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n }\n )\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport chokidar from 'chokidar'\n\nimport { coalesce } from 'coalescifn'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\n\nimport { buildResume } from './build'\n\n/**\n * Options for the watchResume function\n *\n * @param pdf - Whether to generate PDF\n * @param validate - Whether to validate the resume\n */\ntype WatchOptions = {\n pdf?: boolean\n validate?: boolean\n}\n\n/**\n * Watch a resume source file and rebuild on changes.\n *\n * - Only one build runs at a time.\n * - If multiple events arrive during a build, run exactly one more build after\n * it finishes (coalesce bursts).\n * - Uses chokidar for robust file watching that handles editor operations.\n *\n * @param resumePath - The resume file to watch\n * @param options - Build and watch options\n * @returns Chokidar watcher instance\n */\nexport function watchResume(\n resumePath: string,\n options: WatchOptions = { pdf: true, validate: true }\n) {\n const { pdf, validate } = options\n\n // there should be only one build running at a time\n const exclusiveBuild = coalesce(() =>\n buildResume(resumePath, { pdf, validate })\n )\n\n // initial build\n exclusiveBuild()\n\n consola.start(`Watching file changes: ${resumePath}...`)\n\n // use chokidar for robust file watching that handles vim and other editors\n // properly.\n //\n // vim will save the file in a single atomic operation, that being said, it\n // will first create a temporary file (the '.swp' file), then rename it to the\n // final file.\n //\n // Node.js `fs.watch` has trouble with this, so we use chokidar instead.\n const watcher = chokidar.watch(resumePath, {\n awaitWriteFinish: {\n stabilityThreshold: 200, // wait 200ms after file stops changing\n pollInterval: 200, // check every 200ms\n },\n ignoreInitial: true, // don't trigger on initial file discovery\n })\n\n // handle file changes - chokidar's awaitWriteFinish already handles\n // debouncing\n watcher.on('change', () => exclusiveBuild())\n\n // handle file additions (in case file gets recreated)\n watcher.on('add', () => exclusiveBuild())\n\n return watcher\n}\n\n/**\n * Create a command instance to run in watch mode\n */\nexport function createDevCommand() {\n return new Command()\n .name('dev')\n .description('build a resume on file changes (watch mode)')\n .argument('<resume-path>', 'the resume file path')\n .option('--no-pdf', 'only generate TeX file without PDF')\n .option('--no-validate', 'skip resume schema validation')\n .action(\n (resumePath: string, options: { pdf: boolean; validate: boolean }) => {\n watchResume(resumePath, options)\n }\n )\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { Command } from 'commander'\nimport consola from 'consola'\n\nimport {\n YAMLResumeError,\n joinNonEmptyString,\n toCodeBlock,\n} from '@yamlresume/core'\n\n/**\n * Creates a new resume file with the given filename\n *\n * @param filename - The name of the resume file to create\n * @throws {YAMLResumeError} When there are file-related errors:\n * - FILE_CONFLICT: When the file already exists\n * - FILE_READ_ERROR: When there's an error reading the template\n * - FILE_WRITE_ERROR: When there's an error writing the file\n */\nexport function newResume(filename: string) {\n if (fs.existsSync(filename)) {\n throw new YAMLResumeError('FILE_CONFLICT', { path: filename })\n }\n\n const templatePath = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n /* v8 ignore start */\n // I din't find a way to mock `import.meta.url` in tests so we have to\n // ignore the following lines for coverage calculation\n import.meta.url.includes('dist')\n ? '../resources/resume.yml'\n : '../../resources/resume.yml'\n /* v8 ignore stop */\n )\n\n let templateContent: string\n\n try {\n templateContent = fs.readFileSync(templatePath, 'utf8')\n } catch (error) {\n consola.debug(\n joinNonEmptyString(['Error reading template: ', toCodeBlock(error.stack)])\n )\n throw new YAMLResumeError('FILE_READ_ERROR', { path: templatePath })\n }\n\n try {\n fs.writeFileSync(filename, templateContent)\n consola.success(`Created ${filename} successfully.`)\n } catch (error) {\n consola.debug(\n joinNonEmptyString(['Error creating resume: ', toCodeBlock(error.stack)])\n )\n throw new YAMLResumeError('FILE_WRITE_ERROR', { path: filename })\n }\n}\n\n/**\n * Create a command instance to create a new YAML resume\n */\nexport function createNewCommand() {\n return new Command()\n .name('new')\n .description('create a new resume')\n .argument('[filename]', 'output filename', 'resume.yml')\n .action((filename) => {\n try {\n newResume(filename)\n } catch (error) {\n consola.error(error.message)\n process.exit(error.errno)\n }\n })\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n LOCALE_LANGUAGE_OPTIONS,\n getLocaleLanguageDetail,\n} from '@yamlresume/core'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { markdownTable } from 'markdown-table'\n\n/**\n * Generates a markdown table listing all supported locale languages.\n *\n * The table includes columns for the language code and the language name.\n *\n * @returns A string containing the formatted markdown table.\n */\nexport function listLanguages() {\n return markdownTable([\n ['layout.locale.language', 'Language Name'],\n ...LOCALE_LANGUAGE_OPTIONS.map((value) => [\n value,\n getLocaleLanguageDetail(value).name,\n ]),\n ])\n}\n\n/**\n * Create a command instance to list supported languages\n */\n\nexport function createLanguagesCommand() {\n const cmd = new Command()\n .name('languages')\n .description('i18n and l10n support')\n\n cmd\n .command('list')\n .description('list all supported languages')\n .action(() => {\n consola.log(listLanguages())\n })\n\n return cmd\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { TEMPLATE_OPTIONS, getTemplateDetail } from '@yamlresume/core'\nimport { Command } from 'commander'\nimport consola from 'consola'\nimport { markdownTable } from 'markdown-table'\n\n/**\n * Generates a markdown table listing all supported templates.\n *\n * The table includes columns for the template id, name and description.\n *\n * @returns A string containing the formatted markdown table.\n */\nexport function listTemplates() {\n return markdownTable([\n ['layout.template', 'Template Name', 'Description'],\n ...TEMPLATE_OPTIONS.map((value) => {\n const details = getTemplateDetail(value)\n return [value, details.name, details.description]\n }),\n ])\n}\n\n/**\n * Create a command instance to list supported templates\n */\nexport function createTemplatesCommand() {\n const cmd = new Command()\n .name('templates')\n .description('manage resume templates')\n\n cmd\n .command('list')\n .description('list all supported templates')\n .action(() => {\n consola.log(listTemplates())\n })\n\n return cmd\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport consola from 'consola'\n\n/**\n * Set the verbose mode for consola\n *\n * @param verbose - Whether to enable verbose mode\n * @see https://github.com/unjs/consola?tab=readme-ov-file#log-level\n */\nexport function setVerboseLog(verbose: boolean) {\n consola.level = verbose ? 4 : 3\n}\n","/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Command } from 'commander'\n\nimport packageJson from '../package.json' with { type: 'json' }\nimport {\n createBuildCommand,\n createDevCommand,\n createLanguagesCommand,\n createNewCommand,\n createTemplatesCommand,\n createValidateCommand,\n} from './commands'\nimport { setVerboseLog } from './utils'\n\n/**\n * Create the CLI program.\n *\n * @returns The CLI program.\n */\nexport function createProgram(): Command {\n const program = new Command()\n\n const banner = `\n __ __ _ __ __ _ ____\n \\\\ \\\\ / // \\\\ | \\\\/ | | | _ \\\\ ___ ___ _ _ ___ ___ ___\n \\\\ V // _ \\\\ | |\\\\/| | | | |_) / _ \\\\/ __| | | / _ \\\\/ _ \\\\ / _ \\\\\n | |/ ___ \\\\| | | | |___| _ < __/\\\\__ \\\\ |_| | | | | | | __/\n |_/_/ \\\\_\\\\_| |_|_____|_| \\\\_\\\\___||___/\\\\____|_| |_| |_|\\\\___|\n`\n\n program\n .name('yamlresume')\n .description(['YAMLResume — Resume as Code in YAML', banner].join('\\n'))\n .version(packageJson.version)\n .option('-v, --verbose', 'verbose output')\n .hook('preAction', (thisCommand) => {\n setVerboseLog(thisCommand.opts().verbose)\n })\n\n program.addCommand(createNewCommand())\n program.addCommand(createBuildCommand())\n program.addCommand(createDevCommand())\n program.addCommand(createLanguagesCommand())\n program.addCommand(createTemplatesCommand())\n program.addCommand(createValidateCommand())\n\n return program\n}\n","#!/usr/bin/env node\n/**\n * MIT License\n *\n * Copyright (c) 2023–Present PPResume (https://ppresume.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { createProgram } from './program'\n\ncreateProgram().parse()\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yamlresume",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "The CLI interface for YAMLResume's engine",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -40,7 +40,7 @@
40
40
  "tslib": "^2.8.1",
41
41
  "which": "^5.0.0",
42
42
  "yaml": "^2.8.1",
43
- "@yamlresume/core": "0.7.4"
43
+ "@yamlresume/core": "0.7.5"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/chalk": "^2.2.4",