resuml 1.2.6 → 1.3.0

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/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  <h1 align="center">✨ Resuml</h1>
2
- <p align="center"><strong>Resumes in YAML <br>Powered by Typescript & Magic</strong></p>
2
+ <p align="center"><strong>Write your resume in YAML. Render it beautifully.</strong></p>
3
+
4
+ <p align="center">
5
+ <a href="https://www.npmjs.com/package/resuml"><img src="https://img.shields.io/npm/v/resuml.svg" alt="npm version"></a>
6
+ <a href="https://www.npmjs.com/package/resuml"><img src="https://img.shields.io/npm/dm/resuml.svg" alt="npm downloads"></a>
7
+ <a href="https://github.com/phoinixi/resuml/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/resuml.svg" alt="license"></a>
8
+ <a href="https://github.com/phoinixi/resuml"><img src="https://img.shields.io/github/stars/phoinixi/resuml.svg?style=social" alt="GitHub stars"></a>
9
+ </p>
3
10
 
4
11
  <p align="center">
5
12
  <a href="https://www.buymeacoffee.com/leekbeds55j">
@@ -7,8 +14,47 @@
7
14
  </a>
8
15
  </p>
9
16
 
10
- A CLI tool for generating JSON resumes from YAML with theme support. This tool helps you maintain your resume in YAML format and convert it to various formats including JSON and HTML with different themes.
17
+ ---
18
+
19
+ ### YAML in → Beautiful resume out
20
+
21
+ ```yaml
22
+ # resume.yaml
23
+ basics:
24
+ name: Jane Smith
25
+ label: Senior Software Engineer
26
+ email: jane@example.com
27
+ summary: >-
28
+ Passionate engineer with 8+ years
29
+ building scalable distributed systems.
30
+ work:
31
+ - name: Acme Corp
32
+ position: Lead Engineer
33
+ startDate: 2020-01-15
34
+ highlights:
35
+ - Reduced deploy time by 60%
36
+ - Led team of 12 engineers
37
+ ```
38
+
39
+ ```bash
40
+ resuml render --resume resume.yaml --theme stackoverflow --output resume.html
41
+ ```
42
+
43
+ Your YAML becomes a polished, professional resume — ready to share, print, or export to PDF.
44
+
45
+ ---
46
+
47
+ ## Why YAML?
48
+
49
+ | | YAML | JSON |
50
+ |---|---|---|
51
+ | **Comments** | ✅ `# explain your choices` | ❌ Not supported |
52
+ | **Multi-line strings** | ✅ `summary: >-` block syntax | ❌ Escape everything |
53
+ | **Readability** | ✅ Clean, minimal syntax | ⚠️ Brackets & quotes everywhere |
54
+ | **Diffing** | ✅ Clean git diffs | ⚠️ Noisy diffs |
55
+ | **Compatibility** | ✅ Valid JSON Resume schema | ✅ Native |
11
56
 
57
+ YAML is a superset of JSON — your resume stays fully compatible with the [JSON Resume](https://jsonresume.org/) ecosystem while being far more pleasant to write and maintain.
12
58
 
13
59
  ## Prerequisites
14
60
 
@@ -37,44 +83,48 @@ npm install -g resuml
37
83
  resuml render --resume resume.yaml --theme stackoverflow --output resume.html
38
84
  ```
39
85
 
40
- ## Usage
86
+ ## Commands
41
87
 
42
- ### Validate resume data
88
+ | Command | Description |
89
+ |---------|-------------|
90
+ | `validate` | Validate resume data against the JSON Resume schema |
91
+ | `tojson` | Convert YAML resume data to JSON format |
92
+ | `render` | Render the resume using a specified theme |
93
+ | `dev` | Start a development server with hot-reload |
43
94
 
44
- ```bash
45
- resuml validate --resume resume.yaml
46
- ```
95
+ ## Options
47
96
 
48
- ### Convert YAML to JSON
97
+ | Option | Alias | Description |
98
+ |--------|-------|-------------|
99
+ | `--resume` | `-r` | Input YAML file(s) or directory |
100
+ | `--output` | `-o` | Output file path |
101
+ | `--theme` | `-t` | Theme to use for rendering |
102
+ | `--port` | `-p` | Port for dev server (default: 3000) |
103
+ | `--language` | | Language code for localization (default: `en`) |
104
+ | `--debug` | | Enable debug mode for detailed errors |
49
105
 
50
- ```bash
51
- resuml tojson --resume resume.yaml --output resume.json
52
- ```
106
+ ## Compatible Themes
53
107
 
54
- ### Render resume with theme
108
+ Resuml supports themes from the JSON Resume ecosystem. Install a theme, then pass its name to `--theme`:
55
109
 
56
110
  ```bash
57
- resuml render --resume resume.yaml --theme stackoverflow --output resume.html
111
+ npm install jsonresume-theme-stackoverflow
112
+ resuml render --resume resume.yaml --theme stackoverflow
58
113
  ```
59
114
 
60
- ## Examples
61
-
62
- For detailed examples and usage instructions, see the [examples/README.md](examples/README.md) file.
115
+ | Theme | Install | Style |
116
+ |-------|---------|-------|
117
+ | [stackoverflow](https://github.com/francoislaberge/jsonresume-theme-stackoverflow) | `npm i jsonresume-theme-stackoverflow` | Clean, professional |
118
+ | [elegant](https://github.com/mudassir0909/jsonresume-theme-elegant) | `npm i jsonresume-theme-elegant` | Modern, elegant |
119
+ | [kendall](https://github.com/LinuxBozo/jsonresume-theme-kendall) | `npm i jsonresume-theme-kendall` | Minimal, classic |
120
+ | [flat](https://github.com/erming/jsonresume-theme-flat) | `npm i jsonresume-theme-flat` | Flat design |
121
+ | [onepage](https://github.com/aonemd/jsonresume-theme-onepage) | `npm i jsonresume-theme-onepage` | Single page |
63
122
 
64
- ## Commands
123
+ > Browse all themes at [jsonresume.org/themes](https://jsonresume.org/themes/) — any `jsonresume-theme-*` package works with resuml.
65
124
 
66
- - `validate` - Validates resume data against the JSON Resume schema
67
- - `tojson` - Converts YAML resume data to JSON format
68
- - `render` - Renders the resume using a specified theme
69
- - `dev` - Starts a development server with hot-reload
70
-
71
- ## Options
125
+ ## Examples
72
126
 
73
- - `--resume, -r` - Input YAML file(s) or directory
74
- - `--output, -o` - Output file path
75
- - `--theme, -t` - Theme to use for rendering
76
- - `--port, -p` - Port for development server (default: 3000)
77
- - `--debug` - Enable debug mode for detailed error messages
127
+ For detailed examples and usage instructions, see the [examples/README.md](examples/README.md) file.
78
128
 
79
129
  ## Example YAML Structure
80
130
 
@@ -99,24 +149,76 @@ work:
99
149
  summary: Led development of...
100
150
  ```
101
151
 
102
- ## Available Themes
152
+ ## CI/CD: Auto-build on Push
103
153
 
104
- - `stackoverflow` - Clean and professional theme based on Stack Overflow's style
105
- - `react` - Modern React-based theme with interactive features
106
- - More themes coming soon...
154
+ Use GitHub Actions to automatically rebuild your resume when you push changes:
155
+
156
+ ```yaml
157
+ # .github/workflows/resume.yml
158
+ name: Build Resume
159
+
160
+ on:
161
+ push:
162
+ paths: ['resume.yaml', 'resume/*.yaml']
163
+
164
+ jobs:
165
+ build:
166
+ runs-on: ubuntu-latest
167
+ steps:
168
+ - uses: actions/checkout@v4
169
+
170
+ - uses: actions/setup-node@v4
171
+ with:
172
+ node-version: 20
173
+
174
+ - run: npm install -g resuml
175
+ - run: npm install jsonresume-theme-stackoverflow
176
+
177
+ - run: resuml render --resume resume.yaml --theme stackoverflow --output resume.html
178
+ - run: resuml tojson --resume resume.yaml --output resume.json
179
+
180
+ - uses: actions/upload-artifact@v4
181
+ with:
182
+ name: resume
183
+ path: |
184
+ resume.html
185
+ resume.json
186
+ ```
187
+
188
+ ## Node.js API Usage
189
+
190
+ You can use resuml programmatically from Node.js:
191
+
192
+ ```js
193
+ import {
194
+ processResumeData,
195
+ loadResumeFiles,
196
+ loadTheme,
197
+ themeRender
198
+ } from 'resuml';
199
+
200
+ // Load YAML files
201
+ const { yamlContents } = await loadResumeFiles('resume.yaml');
202
+ // Validate and merge
203
+ const resume = await processResumeData(yamlContents);
204
+ // Load a theme
205
+ const theme = await loadTheme('stackoverflow');
206
+ // Render HTML
207
+ const html = await theme.render(resume, { locale: 'en' });
208
+ ```
209
+
210
+ See the CLI and API for more details.
107
211
 
108
212
  ## Troubleshooting
109
213
 
110
214
  ### Common Issues
111
215
 
112
216
  1. **Validation Errors**
113
-
114
217
  - Ensure your YAML follows the JSON Resume schema
115
218
  - Check for proper indentation in your YAML file
116
219
  - Verify all required fields are present
117
220
 
118
221
  2. **Theme Rendering Issues**
119
-
120
222
  - Make sure the theme is properly installed
121
223
  - Check if all required theme dependencies are installed
122
224
  - Try running with `--debug` flag for more information
@@ -133,27 +235,3 @@ Contributions are welcome! Please feel free to submit a Pull Request.
133
235
  ## License
134
236
 
135
237
  ISC
136
-
137
- ## Node.js API Usage
138
-
139
- You can use resuml programmatically from Node.js:
140
-
141
- ```js
142
- import {
143
- processResumeData,
144
- loadResumeFiles,
145
- loadTheme,
146
- themeRender
147
- } from 'resuml';
148
-
149
- // Load YAML files
150
- const { yamlContents } = await loadResumeFiles('resume.yaml');
151
- // Validate and merge
152
- const resume = await processResumeData(yamlContents);
153
- // Load a theme
154
- const theme = await loadTheme('stackoverflow');
155
- // Render HTML
156
- const html = await theme.render(resume, { locale: 'en' });
157
- ```
158
-
159
- See the CLI and API for more details.
package/dist/api.js CHANGED
@@ -38,7 +38,7 @@ var getImportMetaUrl, importMetaUrl;
38
38
  var init_cjs_shims = __esm({
39
39
  "node_modules/tsup/assets/cjs_shims.js"() {
40
40
  "use strict";
41
- getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
41
+ getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
42
42
  importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
43
43
  }
44
44
  });
@@ -180,7 +180,7 @@ var require_brace_expansion = __commonJS({
180
180
  var isSequence = isNumericSequence || isAlphaSequence;
181
181
  var isOptions = m.body.indexOf(",") >= 0;
182
182
  if (!isSequence && !isOptions) {
183
- if (m.post.match(/,.*\}/)) {
183
+ if (m.post.match(/,(?!,).*\}/)) {
184
184
  str = m.pre + "{" + m.body + escClose + m.post;
185
185
  return expand2(str);
186
186
  }
@@ -1066,7 +1066,7 @@ var path = {
1066
1066
  };
1067
1067
  var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
1068
1068
  minimatch.sep = sep;
1069
- var GLOBSTAR = Symbol("globstar **");
1069
+ var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
1070
1070
  minimatch.GLOBSTAR = GLOBSTAR;
1071
1071
  var qmark2 = "[^/]";
1072
1072
  var star2 = qmark2 + "*?";
@@ -1771,7 +1771,6 @@ if (typeof AC === "undefined") {
1771
1771
  };
1772
1772
  }
1773
1773
  var shouldWarn = (code) => !warned.has(code);
1774
- var TYPE = Symbol("type");
1775
1774
  var isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);
1776
1775
  var getUintArray = (max) => !isPosInt(max) ? null : max <= Math.pow(2, 8) ? Uint8Array : max <= Math.pow(2, 16) ? Uint16Array : max <= Math.pow(2, 32) ? Uint32Array : max <= Number.MAX_SAFE_INTEGER ? ZeroArray : null;
1777
1776
  var ZeroArray = class extends Array {
@@ -3116,37 +3115,37 @@ var isStream = (s) => !!s && typeof s === "object" && (s instanceof Minipass ||
3116
3115
  var isReadable = (s) => !!s && typeof s === "object" && s instanceof import_node_events.EventEmitter && typeof s.pipe === "function" && // node core Writable streams have a pipe() method, but it throws
3117
3116
  s.pipe !== import_node_stream.default.Writable.prototype.pipe;
3118
3117
  var isWritable = (s) => !!s && typeof s === "object" && s instanceof import_node_events.EventEmitter && typeof s.write === "function" && typeof s.end === "function";
3119
- var EOF = Symbol("EOF");
3120
- var MAYBE_EMIT_END = Symbol("maybeEmitEnd");
3121
- var EMITTED_END = Symbol("emittedEnd");
3122
- var EMITTING_END = Symbol("emittingEnd");
3123
- var EMITTED_ERROR = Symbol("emittedError");
3124
- var CLOSED = Symbol("closed");
3125
- var READ = Symbol("read");
3126
- var FLUSH = Symbol("flush");
3127
- var FLUSHCHUNK = Symbol("flushChunk");
3128
- var ENCODING = Symbol("encoding");
3129
- var DECODER = Symbol("decoder");
3130
- var FLOWING = Symbol("flowing");
3131
- var PAUSED = Symbol("paused");
3132
- var RESUME = Symbol("resume");
3133
- var BUFFER = Symbol("buffer");
3134
- var PIPES = Symbol("pipes");
3135
- var BUFFERLENGTH = Symbol("bufferLength");
3136
- var BUFFERPUSH = Symbol("bufferPush");
3137
- var BUFFERSHIFT = Symbol("bufferShift");
3138
- var OBJECTMODE = Symbol("objectMode");
3139
- var DESTROYED = Symbol("destroyed");
3140
- var ERROR = Symbol("error");
3141
- var EMITDATA = Symbol("emitData");
3142
- var EMITEND = Symbol("emitEnd");
3143
- var EMITEND2 = Symbol("emitEnd2");
3144
- var ASYNC = Symbol("async");
3145
- var ABORT = Symbol("abort");
3146
- var ABORTED = Symbol("aborted");
3147
- var SIGNAL = Symbol("signal");
3148
- var DATALISTENERS = Symbol("dataListeners");
3149
- var DISCARDED = Symbol("discarded");
3118
+ var EOF = /* @__PURE__ */ Symbol("EOF");
3119
+ var MAYBE_EMIT_END = /* @__PURE__ */ Symbol("maybeEmitEnd");
3120
+ var EMITTED_END = /* @__PURE__ */ Symbol("emittedEnd");
3121
+ var EMITTING_END = /* @__PURE__ */ Symbol("emittingEnd");
3122
+ var EMITTED_ERROR = /* @__PURE__ */ Symbol("emittedError");
3123
+ var CLOSED = /* @__PURE__ */ Symbol("closed");
3124
+ var READ = /* @__PURE__ */ Symbol("read");
3125
+ var FLUSH = /* @__PURE__ */ Symbol("flush");
3126
+ var FLUSHCHUNK = /* @__PURE__ */ Symbol("flushChunk");
3127
+ var ENCODING = /* @__PURE__ */ Symbol("encoding");
3128
+ var DECODER = /* @__PURE__ */ Symbol("decoder");
3129
+ var FLOWING = /* @__PURE__ */ Symbol("flowing");
3130
+ var PAUSED = /* @__PURE__ */ Symbol("paused");
3131
+ var RESUME = /* @__PURE__ */ Symbol("resume");
3132
+ var BUFFER = /* @__PURE__ */ Symbol("buffer");
3133
+ var PIPES = /* @__PURE__ */ Symbol("pipes");
3134
+ var BUFFERLENGTH = /* @__PURE__ */ Symbol("bufferLength");
3135
+ var BUFFERPUSH = /* @__PURE__ */ Symbol("bufferPush");
3136
+ var BUFFERSHIFT = /* @__PURE__ */ Symbol("bufferShift");
3137
+ var OBJECTMODE = /* @__PURE__ */ Symbol("objectMode");
3138
+ var DESTROYED = /* @__PURE__ */ Symbol("destroyed");
3139
+ var ERROR = /* @__PURE__ */ Symbol("error");
3140
+ var EMITDATA = /* @__PURE__ */ Symbol("emitData");
3141
+ var EMITEND = /* @__PURE__ */ Symbol("emitEnd");
3142
+ var EMITEND2 = /* @__PURE__ */ Symbol("emitEnd2");
3143
+ var ASYNC = /* @__PURE__ */ Symbol("async");
3144
+ var ABORT = /* @__PURE__ */ Symbol("abort");
3145
+ var ABORTED = /* @__PURE__ */ Symbol("aborted");
3146
+ var SIGNAL = /* @__PURE__ */ Symbol("signal");
3147
+ var DATALISTENERS = /* @__PURE__ */ Symbol("dataListeners");
3148
+ var DISCARDED = /* @__PURE__ */ Symbol("discarded");
3150
3149
  var defer = (fn) => Promise.resolve().then(fn);
3151
3150
  var nodefer = (fn) => fn();
3152
3151
  var isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish";
@@ -4059,7 +4058,7 @@ var ChildrenCache = class extends LRUCache {
4059
4058
  });
4060
4059
  }
4061
4060
  };
4062
- var setAsCwd = Symbol("PathScurry setAsCwd");
4061
+ var setAsCwd = /* @__PURE__ */ Symbol("PathScurry setAsCwd");
4063
4062
  var PathBase = class {
4064
4063
  /**
4065
4064
  * the basename of this path