resuml 1.14.0 → 1.14.1
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/package.json +1 -1
- package/scripts/bundle-themes.js +84 -3
package/package.json
CHANGED
package/scripts/bundle-themes.js
CHANGED
|
@@ -137,6 +137,8 @@ const SAMPLE_RESUME = {
|
|
|
137
137
|
function padResume(r) {
|
|
138
138
|
const basics = r.basics ?? {};
|
|
139
139
|
const location = basics.location ?? {};
|
|
140
|
+
const meta = r.meta ?? {};
|
|
141
|
+
const palette = meta.palette ?? {};
|
|
140
142
|
const safe = {
|
|
141
143
|
...r,
|
|
142
144
|
basics: {
|
|
@@ -144,6 +146,9 @@ function padResume(r) {
|
|
|
144
146
|
...basics,
|
|
145
147
|
location: { address: '', postalCode: '', city: '', countryCode: '', region: '', ...location },
|
|
146
148
|
},
|
|
149
|
+
// Guard against themes like material that read meta.palette.primary without
|
|
150
|
+
// defensive checks.
|
|
151
|
+
meta: { ...meta, palette: { primary: '', secondary: '', ...palette } },
|
|
147
152
|
};
|
|
148
153
|
const arraySections = ['work','volunteer','education','awards','certificates','publications','skills','languages','interests','references','projects'];
|
|
149
154
|
for (const key of arraySections) {
|
|
@@ -393,6 +398,29 @@ const LEGACY_PATCHES = [
|
|
|
393
398
|
);
|
|
394
399
|
},
|
|
395
400
|
},
|
|
401
|
+
// jsonresume-theme-react tries to assign `window` and `document` which are
|
|
402
|
+
// read-only in the browser (we're already in a browser — no need to
|
|
403
|
+
// polyfill). Guard the assignments so they don't throw. It also uses a
|
|
404
|
+
// pattern not covered by the generic rewrite:
|
|
405
|
+
// const modulePath = path.join(__dirname, 'dist/index.cjs');
|
|
406
|
+
// require(modulePath);
|
|
407
|
+
// Inline the variable so esbuild can statically bundle dist/index.cjs.
|
|
408
|
+
{
|
|
409
|
+
filter: /node_modules\/jsonresume-theme-react\/index\.cjs$/,
|
|
410
|
+
transform: (src) => src
|
|
411
|
+
.replace(
|
|
412
|
+
/global\.window\s*=\s*global\.window\s*\|\|\s*\{[^}]*\};?/g,
|
|
413
|
+
'try { if (typeof window === "undefined") globalThis.window = {}; } catch (_) {}',
|
|
414
|
+
)
|
|
415
|
+
.replace(
|
|
416
|
+
/global\.document\s*=\s*global\.document\s*\|\|\s*\{[\s\S]*?\};/g,
|
|
417
|
+
'try { if (typeof document === "undefined") globalThis.document = { createElement: () => ({}), addEventListener: () => {} }; } catch (_) {}',
|
|
418
|
+
)
|
|
419
|
+
.replace(
|
|
420
|
+
/const\s+modulePath\s*=\s*path\.join\(\s*__dirname\s*,\s*['"]([^'"]+)['"]\s*\);([\s\S]*?)require\(modulePath\)/,
|
|
421
|
+
(_, rel, middle) => `const modulePath = './${rel}';${middle}require('./${rel}')`,
|
|
422
|
+
),
|
|
423
|
+
},
|
|
396
424
|
];
|
|
397
425
|
|
|
398
426
|
/**
|
|
@@ -406,7 +434,7 @@ function legacyThemeGlobalsPlugin() {
|
|
|
406
434
|
return {
|
|
407
435
|
name: 'legacy-theme-globals',
|
|
408
436
|
setup(build) {
|
|
409
|
-
build.onLoad({ filter: /\.js$/ }, async (args) => {
|
|
437
|
+
build.onLoad({ filter: /\.c?js$/ }, async (args) => {
|
|
410
438
|
const { readFile } = await import('node:fs/promises');
|
|
411
439
|
const isThemePkg = /node_modules\/jsonresume-theme-[^/]+\/[^/]*\.js$/.test(args.path);
|
|
412
440
|
const matchingPatches = LEGACY_PATCHES.filter((p) => p.filter.test(args.path));
|
|
@@ -436,8 +464,28 @@ function legacyThemeGlobalsPlugin() {
|
|
|
436
464
|
]);
|
|
437
465
|
contents = contents.replace(
|
|
438
466
|
/^([ \t]*)([a-zA-Z_$][\w$]*)\s*=(?!=)/gm,
|
|
439
|
-
(match, indent, name) => {
|
|
467
|
+
(match, indent, name, offset, full) => {
|
|
440
468
|
if (RESERVED.has(name)) return match;
|
|
469
|
+
// Skip expression-context assignments (not a new statement):
|
|
470
|
+
// - `var a, b,\n c = ...` (multi-var continuation)
|
|
471
|
+
// - `foo(\n bar = 1\n)` (argument expression)
|
|
472
|
+
// - `[\n x = 1\n]` (array element assignment)
|
|
473
|
+
// - `a ?\n b = 1 :\n c = 2` (ternary branch)
|
|
474
|
+
// - `a ||\n b = 1` (short-circuit)
|
|
475
|
+
// A new statement context, on the other hand, lives after
|
|
476
|
+
// `{` `}` `;` — in those cases the rewrite is correct.
|
|
477
|
+
const before = full.slice(0, offset).replace(/\s+$/, '');
|
|
478
|
+
const prevChar = before.charAt(before.length - 1);
|
|
479
|
+
if (prevChar === ',' || prevChar === '(' || prevChar === '[' ||
|
|
480
|
+
prevChar === '?' || prevChar === ':') return match;
|
|
481
|
+
const prev2 = before.slice(-2);
|
|
482
|
+
if (prev2 === '||' || prev2 === '&&' || prev2 === '=>') return match;
|
|
483
|
+
// Inside `for (` init clause — rare but valid (var isn't allowed
|
|
484
|
+
// there unless at the very start, and esbuild will handle the
|
|
485
|
+
// already-correct `for (var i = 0; ...)` form).
|
|
486
|
+
const lineStart = full.lastIndexOf('\n', offset - 1) + 1;
|
|
487
|
+
const lineBefore = full.slice(lineStart, offset);
|
|
488
|
+
if (/\bfor\s*\(\s*$/.test(lineBefore)) return match;
|
|
441
489
|
return `${indent}var ${name} =`;
|
|
442
490
|
}
|
|
443
491
|
);
|
|
@@ -446,6 +494,39 @@ function legacyThemeGlobalsPlugin() {
|
|
|
446
494
|
// 2. Targeted source patches (layered on top of the generic rewrite)
|
|
447
495
|
for (const patch of matchingPatches) contents = patch.transform(contents);
|
|
448
496
|
|
|
497
|
+
// 3. Resolve dynamic requires statically so esbuild can bundle them.
|
|
498
|
+
// Two common patterns in themes:
|
|
499
|
+
// a) const HELPERS = join(__dirname, 'theme/hbs-helpers');
|
|
500
|
+
// require(join(HELPERS, 'file.js'))
|
|
501
|
+
// b) require(path.join(__dirname, 'dist/index.cjs'))
|
|
502
|
+
// esbuild leaves computed requires as runtime calls, which our
|
|
503
|
+
// browser shim rejects. Rewrite to static relative paths.
|
|
504
|
+
if (isThemePkg) {
|
|
505
|
+
// Pattern (b): inline `require((path.)?join(__dirname, 'literal'))`
|
|
506
|
+
contents = contents.replace(
|
|
507
|
+
/require\(\s*(?:\w+\.)?join\(\s*__dirname\s*,\s*['"]([^'"]+)['"]\s*\)\s*\)/g,
|
|
508
|
+
(_, rel) => `require(${JSON.stringify('./' + rel)})`,
|
|
509
|
+
);
|
|
510
|
+
// Pattern (a): resolve via tracked join-constants.
|
|
511
|
+
const joinConsts = {};
|
|
512
|
+
for (const m of contents.matchAll(
|
|
513
|
+
/\b(?:const|var|let)\s+(\w+)\s*=\s*(?:\w+\.)?join\(\s*__dirname\s*,\s*['"]([^'"]+)['"]\s*\)/g
|
|
514
|
+
)) {
|
|
515
|
+
joinConsts[m[1]] = m[2];
|
|
516
|
+
}
|
|
517
|
+
if (Object.keys(joinConsts).length > 0) {
|
|
518
|
+
contents = contents.replace(
|
|
519
|
+
/require\(\s*(?:\w+\.)?join\(\s*(\w+)\s*,\s*['"]([^'"]+)['"]\s*\)\s*\)/g,
|
|
520
|
+
(match, name, file) => {
|
|
521
|
+
const prefix = joinConsts[name];
|
|
522
|
+
if (prefix === undefined) return match;
|
|
523
|
+
const rel = `./${prefix}/${file}`.replace(/\/+/g, '/');
|
|
524
|
+
return `require(${JSON.stringify(rel)})`;
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
449
530
|
return contents !== original ? { contents, loader: 'js' } : null;
|
|
450
531
|
});
|
|
451
532
|
},
|
|
@@ -498,7 +579,7 @@ async function bundleTheme(shortName, packageName, shimsDir) {
|
|
|
498
579
|
// Runtime process shim: `process.env.X` literal access is handled
|
|
499
580
|
// by esbuild's `define`, but dynamic access like `process.cwd()` or
|
|
500
581
|
// `process.stdout.write` needs an actual object at runtime.
|
|
501
|
-
'if (typeof globalThis.process === "undefined") globalThis.process = { env: { NODE_ENV: "production" }, browser: true, platform: "browser", version: "v20.0.0", versions: {}, stdout: { write: function(){} }, stderr: { write: function(){} }, cwd: function(){ return "/"; }, chdir: function(){}, nextTick: function(fn){ Promise.resolve().then(fn); }, argv: [], pid: 1, title: "browser" };',
|
|
582
|
+
'if (typeof globalThis.process === "undefined") globalThis.process = { env: { NODE_ENV: "production" }, browser: true, platform: "browser", version: "v20.0.0", versions: { node: "20.0.0", v8: "11.3.0" }, stdout: { write: function(){} }, stderr: { write: function(){} }, cwd: function(){ return "/"; }, chdir: function(){}, nextTick: function(fn){ Promise.resolve().then(fn); }, argv: [], pid: 1, title: "browser" };',
|
|
502
583
|
].join(''),
|
|
503
584
|
},
|
|
504
585
|
define: {
|