@maizzle/framework 6.0.0-rc.14 → 6.0.0-rc.16

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.
Files changed (67) hide show
  1. package/README.md +3 -3
  2. package/dist/components/Body.vue +9 -2
  3. package/dist/components/Button.vue +13 -8
  4. package/dist/components/Column.vue +22 -8
  5. package/dist/components/Container.vue +9 -5
  6. package/dist/components/Head.vue +1 -1
  7. package/dist/components/Html.vue +7 -2
  8. package/dist/components/Layout.vue +45 -15
  9. package/dist/components/Outlook.vue +38 -11
  10. package/dist/components/Overlap.vue +8 -3
  11. package/dist/components/Raw.vue +28 -0
  12. package/dist/components/Row.vue +72 -11
  13. package/dist/components/Section.vue +9 -5
  14. package/dist/components/Spacer.vue +9 -4
  15. package/dist/components/utils.d.mts +11 -1
  16. package/dist/components/utils.d.mts.map +1 -1
  17. package/dist/components/utils.mjs +11 -1
  18. package/dist/components/utils.mjs.map +1 -1
  19. package/dist/components/utils.ts +12 -0
  20. package/dist/composables/useOutlookFallback.d.mts +21 -0
  21. package/dist/composables/useOutlookFallback.d.mts.map +1 -0
  22. package/dist/composables/useOutlookFallback.mjs +30 -0
  23. package/dist/composables/useOutlookFallback.mjs.map +1 -0
  24. package/dist/index.d.mts +3 -1
  25. package/dist/index.mjs +3 -1
  26. package/dist/prepare.d.mts +17 -0
  27. package/dist/prepare.d.mts.map +1 -0
  28. package/dist/prepare.mjs +44 -0
  29. package/dist/prepare.mjs.map +1 -0
  30. package/dist/render/createRenderer.d.mts.map +1 -1
  31. package/dist/render/createRenderer.mjs +9 -75
  32. package/dist/render/createRenderer.mjs.map +1 -1
  33. package/dist/render/plugins/codeBlockExtract.d.mts +14 -0
  34. package/dist/render/plugins/codeBlockExtract.d.mts.map +1 -0
  35. package/dist/render/plugins/codeBlockExtract.mjs +34 -0
  36. package/dist/render/plugins/codeBlockExtract.mjs.map +1 -0
  37. package/dist/render/plugins/markdownExtract.d.mts +12 -0
  38. package/dist/render/plugins/markdownExtract.d.mts.map +1 -0
  39. package/dist/render/plugins/markdownExtract.mjs +50 -0
  40. package/dist/render/plugins/markdownExtract.mjs.map +1 -0
  41. package/dist/render/plugins/rawExtract.d.mts +14 -0
  42. package/dist/render/plugins/rawExtract.d.mts.map +1 -0
  43. package/dist/render/plugins/rawExtract.mjs +34 -0
  44. package/dist/render/plugins/rawExtract.mjs.map +1 -0
  45. package/dist/render/plugins/rowSourceLocation.d.mts +18 -0
  46. package/dist/render/plugins/rowSourceLocation.d.mts.map +1 -0
  47. package/dist/render/plugins/rowSourceLocation.mjs +45 -0
  48. package/dist/render/plugins/rowSourceLocation.mjs.map +1 -0
  49. package/dist/server/ui/App.vue +47 -2
  50. package/dist/server/ui/pages/Preview.vue +32 -3
  51. package/dist/transformers/columnWidth.d.mts +9 -9
  52. package/dist/transformers/columnWidth.d.mts.map +1 -1
  53. package/dist/transformers/columnWidth.mjs +422 -41
  54. package/dist/transformers/columnWidth.mjs.map +1 -1
  55. package/dist/transformers/filters/index.mjs +1 -1
  56. package/dist/transformers/filters/index.mjs.map +1 -1
  57. package/dist/transformers/index.mjs +1 -1
  58. package/dist/transformers/index.mjs.map +1 -1
  59. package/node_modules/maizzle/dist/commands/new.mjs +3 -3
  60. package/node_modules/maizzle/dist/index.d.mts +1 -0
  61. package/node_modules/maizzle/dist/index.mjs +3 -0
  62. package/node_modules/maizzle/package.json +3 -2
  63. package/node_modules/nypm/dist/cli.mjs +28 -5
  64. package/node_modules/nypm/dist/index.d.mts +0 -8
  65. package/node_modules/nypm/dist/index.mjs +27 -4
  66. package/node_modules/nypm/package.json +12 -12
  67. package/package.json +1 -1
@@ -53,6 +53,7 @@ import { minify } from "./minify.mjs";
53
53
  * 16. Minify
54
54
  */
55
55
  async function runTransformers(html, config, filePath, doctype) {
56
+ html = html.replaceAll("<!--[-->", "").replaceAll("<!--]-->", "").replaceAll("<!--teleport start anchor-->", "").replaceAll("<!--teleport anchor-->", "").replaceAll("<!--teleport start-->", "").replaceAll("<!--teleport end-->", "");
56
57
  let dom = parse(html);
57
58
  dom = await inlineLink(dom, filePath);
58
59
  dom = await tailwindcss(dom, config, filePath);
@@ -72,7 +73,6 @@ async function runTransformers(html, config, filePath, doctype) {
72
73
  dom = entities(dom, config.html?.decodeEntities);
73
74
  const isXhtml = doctype ? /xhtml/i.test(doctype) : false;
74
75
  let result = serialize(dom, { selfClosingTags: isXhtml });
75
- result = result.replaceAll("<!--[-->", "").replaceAll("<!--]-->", "").replaceAll("<!--teleport start anchor-->", "").replaceAll("<!--teleport anchor-->", "").replaceAll("<!--teleport start-->", "").replaceAll("<!--teleport end-->", "");
76
76
  result = replaceStrings(result, config);
77
77
  result = await format(result, config);
78
78
  result = minify(result, config);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLink } from './inlineLink.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeClassNames } from './safeClassNames.ts'\nimport { attributeToStyle } from './attributeToStyle.ts'\nimport { inlineCSS } from './inlineCSS.ts'\nimport { msoWidthFromClass } from './msoWidthFromClass.ts'\nimport { columnWidth } from './columnWidth.ts'\nimport { removeAttributes } from './removeAttributes.ts'\nimport { shorthandCSS } from './shorthandCSS.ts'\nimport { sixHex } from './sixHex.ts'\nimport { addAttributes } from './addAttributes.ts'\nimport { filters } from './filters/index.ts'\nimport { base } from './base.ts'\nimport { entities } from './entities.ts'\nimport { urlQuery } from './urlQuery.ts'\nimport { purgeCSS } from './purgeCSS.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Run all Maizzle transformers on the rendered HTML.\n *\n * The HTML is parsed into a DOM once at the start and passed through all\n * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers\n * complete, the DOM is serialized back to a string exactly once.\n *\n * String-only transformers (those that rely on external tools that require a\n * raw HTML string) then run on the serialized output.\n *\n * Transformers run in a specific order:\n * 0. Inline link stylesheets — replace `<link rel=\"stylesheet\">` with `<style>` tags\n * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)\n * 2. Safe class names\n * 3. Attribute to style\n * 4. CSS inliner\n * 5. Remove attributes\n * 6. Shorthand CSS\n * 7. Six-digit HEX\n * 8. Add attributes\n * 9. Filters\n * 10. Base URL\n * 11. URL query\n * 12. Purge CSS (serializes/parses internally around email-comb)\n * 13. Entities\n * + Vue-generated comments stripped here (on serialized string)\n * 14. Replace strings\n * 15. Prettify\n * 16. Minify\n */\nexport async function runTransformers(\n html: string,\n config: MaizzleConfig,\n filePath?: string,\n doctype?: string,\n): Promise<string> {\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLink(dom, filePath)\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, config, filePath)\n\n // 2. Safe class names\n dom = safeClassNames(dom, config.css)\n\n // 3. Attribute to style\n dom = attributeToStyle(dom, config.css)\n\n // 4. CSS inliner (serializes/parses internally around juice)\n dom = inlineCSS(dom, config.css)\n\n // 4.5. Resolve MSO width placeholders from inlined max-width/width\n dom = msoWidthFromClass(dom)\n\n // 4.6. Resolve Column min-width placeholders from nearest sized ancestor\n dom = columnWidth(dom)\n\n // 5. Remove attributes\n dom = removeAttributes(dom, config.html?.attributes)\n\n // 6. Shorthand CSS\n dom = shorthandCSS(dom, config.css)\n\n // 7. Six-digit HEX\n dom = sixHex(dom, config.css)\n\n // 8. Add attributes\n dom = addAttributes(dom, config.html?.attributes)\n\n // 9. Filters\n dom = filters(dom, config.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n dom = base(dom, config.url)\n\n // 11. URL query\n dom = urlQuery(dom, config.url)\n\n // 12. Purge CSS (serializes/parses internally around email-comb)\n dom = purgeCSS(dom, config.css)\n\n // 13. Entities\n dom = entities(dom, config.html?.decodeEntities)\n\n // Serialize once — remaining transformers operate on the HTML string\n const isXhtml = doctype ? /xhtml/i.test(doctype) : false\n let result = serialize(dom, { selfClosingTags: isXhtml })\n\n // Remove Vue-generated comments after serializing\n result = result\n .replaceAll('<!--[-->', '')\n .replaceAll('<!--]-->', '')\n .replaceAll('<!--teleport start anchor-->', '')\n .replaceAll('<!--teleport anchor-->', '')\n .replaceAll('<!--teleport start-->', '')\n .replaceAll('<!--teleport end-->', '')\n\n // 14. Replace strings\n result = replaceStrings(result, config)\n\n // 15. Format\n result = await format(result, config)\n\n // 16. Minify\n result = minify(result, config)\n\n // Strip self-closing slashes for HTML5 doctypes\n if (!isXhtml) {\n result = result.replace(/ \\/>/g, '>')\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,eAAsB,gBACpB,MACA,QACA,UACA,SACiB;CAEjB,IAAI,MAAM,MAAM,KAAK;AAGrB,OAAM,MAAM,WAAW,KAAK,SAAS;AAGrC,OAAM,MAAM,YAAY,KAAK,QAAQ,SAAS;AAG9C,OAAM,eAAe,KAAK,OAAO,IAAI;AAGrC,OAAM,iBAAiB,KAAK,OAAO,IAAI;AAGvC,OAAM,UAAU,KAAK,OAAO,IAAI;AAGhC,OAAM,kBAAkB,IAAI;AAG5B,OAAM,YAAY,IAAI;AAGtB,OAAM,iBAAiB,KAAK,OAAO,MAAM,WAAW;AAGpD,OAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,OAAM,OAAO,KAAK,OAAO,IAAI;AAG7B,OAAM,cAAc,KAAK,OAAO,MAAM,WAAW;AAGjD,OAAM,QAAQ,KAAK,OAAO,QAAQ;AAGlC,OAAM,KAAK,KAAK,OAAO,IAAI;AAG3B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,MAAM,eAAe;CAGhD,MAAM,UAAU,UAAU,SAAS,KAAK,QAAQ,GAAG;CACnD,IAAI,SAAS,UAAU,KAAK,EAAE,iBAAiB,SAAS,CAAC;AAGzD,UAAS,OACN,WAAW,YAAY,GAAG,CAC1B,WAAW,YAAY,GAAG,CAC1B,WAAW,gCAAgC,GAAG,CAC9C,WAAW,0BAA0B,GAAG,CACxC,WAAW,yBAAyB,GAAG,CACvC,WAAW,uBAAuB,GAAG;AAGxC,UAAS,eAAe,QAAQ,OAAO;AAGvC,UAAS,MAAM,OAAO,QAAQ,OAAO;AAGrC,UAAS,OAAO,QAAQ,OAAO;AAG/B,KAAI,CAAC,QACH,UAAS,OAAO,QAAQ,SAAS,IAAI;AAGvC,QAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLink } from './inlineLink.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeClassNames } from './safeClassNames.ts'\nimport { attributeToStyle } from './attributeToStyle.ts'\nimport { inlineCSS } from './inlineCSS.ts'\nimport { msoWidthFromClass } from './msoWidthFromClass.ts'\nimport { columnWidth } from './columnWidth.ts'\nimport { removeAttributes } from './removeAttributes.ts'\nimport { shorthandCSS } from './shorthandCSS.ts'\nimport { sixHex } from './sixHex.ts'\nimport { addAttributes } from './addAttributes.ts'\nimport { filters } from './filters/index.ts'\nimport { base } from './base.ts'\nimport { entities } from './entities.ts'\nimport { urlQuery } from './urlQuery.ts'\nimport { purgeCSS } from './purgeCSS.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Run all Maizzle transformers on the rendered HTML.\n *\n * The HTML is parsed into a DOM once at the start and passed through all\n * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers\n * complete, the DOM is serialized back to a string exactly once.\n *\n * String-only transformers (those that rely on external tools that require a\n * raw HTML string) then run on the serialized output.\n *\n * Transformers run in a specific order:\n * 0. Inline link stylesheets — replace `<link rel=\"stylesheet\">` with `<style>` tags\n * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)\n * 2. Safe class names\n * 3. Attribute to style\n * 4. CSS inliner\n * 5. Remove attributes\n * 6. Shorthand CSS\n * 7. Six-digit HEX\n * 8. Add attributes\n * 9. Filters\n * 10. Base URL\n * 11. URL query\n * 12. Purge CSS (serializes/parses internally around email-comb)\n * 13. Entities\n * + Vue-generated comments stripped here (on serialized string)\n * 14. Replace strings\n * 15. Prettify\n * 16. Minify\n */\nexport async function runTransformers(\n html: string,\n config: MaizzleConfig,\n filePath?: string,\n doctype?: string,\n): Promise<string> {\n // Strip Vue SSR fragment markers before parsing. They contain `-->`, which\n // prematurely terminates conditional comments like `<!--[if mso]>...<![endif]-->`\n // when htmlparser2 reads them, swallowing real markup into comment data.\n html = html\n .replaceAll('<!--[-->', '')\n .replaceAll('<!--]-->', '')\n .replaceAll('<!--teleport start anchor-->', '')\n .replaceAll('<!--teleport anchor-->', '')\n .replaceAll('<!--teleport start-->', '')\n .replaceAll('<!--teleport end-->', '')\n\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLink(dom, filePath)\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, config, filePath)\n\n // 2. Safe class names\n dom = safeClassNames(dom, config.css)\n\n // 3. Attribute to style\n dom = attributeToStyle(dom, config.css)\n\n // 4. CSS inliner (serializes/parses internally around juice)\n dom = inlineCSS(dom, config.css)\n\n // 4.5. Resolve MSO width placeholders from inlined max-width/width\n dom = msoWidthFromClass(dom)\n\n // 4.6. Resolve Column min-width placeholders from nearest sized ancestor\n dom = columnWidth(dom)\n\n // 5. Remove attributes\n dom = removeAttributes(dom, config.html?.attributes)\n\n // 6. Shorthand CSS\n dom = shorthandCSS(dom, config.css)\n\n // 7. Six-digit HEX\n dom = sixHex(dom, config.css)\n\n // 8. Add attributes\n dom = addAttributes(dom, config.html?.attributes)\n\n // 9. Filters\n dom = filters(dom, config.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n dom = base(dom, config.url)\n\n // 11. URL query\n dom = urlQuery(dom, config.url)\n\n // 12. Purge CSS (serializes/parses internally around email-comb)\n dom = purgeCSS(dom, config.css)\n\n // 13. Entities\n dom = entities(dom, config.html?.decodeEntities)\n\n // Serialize once — remaining transformers operate on the HTML string\n const isXhtml = doctype ? /xhtml/i.test(doctype) : false\n let result = serialize(dom, { selfClosingTags: isXhtml })\n\n // 14. Replace strings\n result = replaceStrings(result, config)\n\n // 15. Format\n result = await format(result, config)\n\n // 16. Minify\n result = minify(result, config)\n\n // Strip self-closing slashes for HTML5 doctypes\n if (!isXhtml) {\n result = result.replace(/ \\/>/g, '>')\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,eAAsB,gBACpB,MACA,QACA,UACA,SACiB;AAIjB,QAAO,KACJ,WAAW,YAAY,GAAG,CAC1B,WAAW,YAAY,GAAG,CAC1B,WAAW,gCAAgC,GAAG,CAC9C,WAAW,0BAA0B,GAAG,CACxC,WAAW,yBAAyB,GAAG,CACvC,WAAW,uBAAuB,GAAG;CAGxC,IAAI,MAAM,MAAM,KAAK;AAGrB,OAAM,MAAM,WAAW,KAAK,SAAS;AAGrC,OAAM,MAAM,YAAY,KAAK,QAAQ,SAAS;AAG9C,OAAM,eAAe,KAAK,OAAO,IAAI;AAGrC,OAAM,iBAAiB,KAAK,OAAO,IAAI;AAGvC,OAAM,UAAU,KAAK,OAAO,IAAI;AAGhC,OAAM,kBAAkB,IAAI;AAG5B,OAAM,YAAY,IAAI;AAGtB,OAAM,iBAAiB,KAAK,OAAO,MAAM,WAAW;AAGpD,OAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,OAAM,OAAO,KAAK,OAAO,IAAI;AAG7B,OAAM,cAAc,KAAK,OAAO,MAAM,WAAW;AAGjD,OAAM,QAAQ,KAAK,OAAO,QAAQ;AAGlC,OAAM,KAAK,KAAK,OAAO,IAAI;AAG3B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,MAAM,eAAe;CAGhD,MAAM,UAAU,UAAU,SAAS,KAAK,QAAQ,GAAG;CACnD,IAAI,SAAS,UAAU,KAAK,EAAE,iBAAiB,SAAS,CAAC;AAGzD,UAAS,eAAe,QAAQ,OAAO;AAGvC,UAAS,MAAM,OAAO,QAAQ,OAAO;AAGrC,UAAS,OAAO,QAAQ,OAAO;AAG/B,KAAI,CAAC,QACH,UAAS,OAAO,QAAQ,SAAS,IAAI;AAGvC,QAAO"}
@@ -3,7 +3,7 @@ import color from "picocolors";
3
3
  import * as p from "@clack/prompts";
4
4
  import { rm } from "node:fs/promises";
5
5
  import { existsSync } from "node:fs";
6
- import { execFileSync } from "node:child_process";
6
+ import { execSync } from "node:child_process";
7
7
  import { installDependencies } from "nypm";
8
8
  //#region src/commands/new.ts
9
9
  const starters = [
@@ -210,7 +210,7 @@ async function newProject(starterArg, dirArg, options = {}) {
210
210
  message: "Install dependencies?",
211
211
  initialValue: true
212
212
  }),
213
- pm: async () => "npm"
213
+ pm: async () => options.pm || "npm"
214
214
  }, { onCancel: () => {
215
215
  p.cancel("💀");
216
216
  process.exit(0);
@@ -228,7 +228,7 @@ async function newProject(starterArg, dirArg, options = {}) {
228
228
  spinner.stop(`Created project in ${project.path}`);
229
229
  if (project.install) {
230
230
  try {
231
- execFileSync(project.pm, ["--version"], { stdio: "ignore" });
231
+ execSync(`${project.pm} --version`, { stdio: "ignore" });
232
232
  } catch {
233
233
  p.log.error(`${project.pm} is not installed. Please install it first.`);
234
234
  process.exit(1);
@@ -2,6 +2,7 @@
2
2
  interface Framework {
3
3
  serve: (options?: any) => Promise<any>;
4
4
  build: (options?: any) => Promise<any>;
5
+ prepare: (options?: any) => Promise<any>;
5
6
  }
6
7
  declare function bootstrap(framework?: Framework): Promise<void>;
7
8
  //#endregion
@@ -22,6 +22,9 @@ async function bootstrap(framework) {
22
22
  output: options.output
23
23
  });
24
24
  });
25
+ program.command("prepare").description("Generate IDE type definitions in .maizzle/").option("-c, --config <path>", "Path to maizzle config file").action(async (options) => {
26
+ await framework.prepare({ config: options.config });
27
+ });
25
28
  }
26
29
  program.command("new [starter] [directory]").description("Create a new Maizzle project").option("-i, --install", "Install dependencies").option("--pm <manager>", "Package manager to use").action(async (starter, directory, options) => {
27
30
  await newProject(starter, directory, options);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maizzle",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "CLI tool for the Maizzle Email Framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,7 +19,8 @@
19
19
  ],
20
20
  "scripts": {
21
21
  "build": "tsdown",
22
- "prepublishOnly": "npm run build",
22
+ "typecheck": "tsc --noEmit",
23
+ "prepublishOnly": "npm run typecheck && npm run build",
23
24
  "dev": "vitest",
24
25
  "test": "vitest run --coverage",
25
26
  "release": "npm run build && npx np"
@@ -8,7 +8,7 @@ import { existsSync } from "node:fs";
8
8
  import { readFile } from "node:fs/promises";
9
9
  import { join as join$1 } from "node:path";
10
10
  var name = "nypm";
11
- var version = "0.6.4";
11
+ var version = "0.6.5";
12
12
  var description = "Unified Package Manager for Node.js";
13
13
  const packageManagers = [
14
14
  {
@@ -86,11 +86,32 @@ async function findup(cwd, match, options = {}) {
86
86
  segments.pop();
87
87
  }
88
88
  }
89
- async function readPackageJSON(cwd) {
89
+ async function readPackageJSON(cwd, options = {}) {
90
90
  return findup(cwd, (p) => {
91
91
  const pkgPath = join$1(p, "package.json");
92
92
  if (existsSync(pkgPath)) return readFile(pkgPath, "utf8").then((data) => JSON.parse(data));
93
- });
93
+ }, options);
94
+ }
95
+ async function readInstalledPackageJSON(pkgName, cwd) {
96
+ const pkgJSONPath = await findup(cwd, (p) => {
97
+ const candidate = join$1(p, "node_modules", pkgName, "package.json");
98
+ if (existsSync(candidate)) return candidate;
99
+ }, { includeParentDirs: true });
100
+ if (!pkgJSONPath) return null;
101
+ try {
102
+ return JSON.parse(await readFile(pkgJSONPath, "utf8"));
103
+ } catch {
104
+ return null;
105
+ }
106
+ }
107
+ async function readPackageJSONFromResolver(requireFn, pkgName) {
108
+ let resolved;
109
+ try {
110
+ resolved = requireFn.resolve(pkgName);
111
+ } catch {
112
+ return null;
113
+ }
114
+ return readPackageJSON(resolved, { includeParentDirs: true });
94
115
  }
95
116
  function cached(fn) {
96
117
  let v;
@@ -222,8 +243,10 @@ async function addDependency(name, options = {}) {
222
243
  const _require = createRequire(join$1(resolvedOptions.cwd, "/_.js"));
223
244
  for (const _name of names) {
224
245
  const pkgName = _name.match(/^(.[^@]+)/)?.[0];
225
- const pkg = await readPackageJSON(_require.resolve(pkgName));
226
- if (!pkg?.peerDependencies || pkg?.name !== pkgName) continue;
246
+ if (!pkgName) continue;
247
+ let pkg = await readPackageJSONFromResolver(_require, pkgName);
248
+ if (pkg?.name !== pkgName) pkg = await readInstalledPackageJSON(pkgName, resolvedOptions.cwd);
249
+ if (!pkg?.peerDependencies) continue;
227
250
  for (const [peerDependency, version] of Object.entries(pkg.peerDependencies)) {
228
251
  if (pkg.peerDependenciesMeta?.[peerDependency]?.optional) continue;
229
252
  if (existingPkg?.dependencies?.[peerDependency] || existingPkg?.devDependencies?.[peerDependency]) continue;
@@ -1,4 +1,3 @@
1
- //#region src/types.d.ts
2
1
  type PackageManagerName = "npm" | "yarn" | "pnpm" | "bun" | "deno";
3
2
  type PackageManager = {
4
3
  name: PackageManagerName;
@@ -27,8 +26,6 @@ type OperationResult = {
27
26
  args: string[];
28
27
  };
29
28
  };
30
- //#endregion
31
- //#region src/package-manager.d.ts
32
29
  type DetectPackageManagerOptions = {
33
30
  /**
34
31
  * Whether to ignore the lock file
@@ -64,8 +61,6 @@ declare const packageManagers: PackageManager[];
64
61
  declare function detectPackageManager(cwd: string, options?: DetectPackageManagerOptions): Promise<(PackageManager & {
65
62
  warnings?: string[];
66
63
  }) | undefined>;
67
- //#endregion
68
- //#region src/api.d.ts
69
64
  /**
70
65
  * Installs project dependencies.
71
66
  *
@@ -172,8 +167,6 @@ declare function dlx(name: string, options?: Pick<OperationOptions, "cwd" | "env
172
167
  short?: boolean;
173
168
  packages?: string[];
174
169
  }): Promise<OperationResult>;
175
- //#endregion
176
- //#region src/cmd.d.ts
177
170
  /**
178
171
  * Get the command to install dependencies with the package manager.
179
172
  */
@@ -205,5 +198,4 @@ declare function dlxCommand(packageManager: PackageManagerName, name: string, op
205
198
  short?: boolean;
206
199
  packages?: string[];
207
200
  }): string;
208
- //#endregion
209
201
  export { DetectPackageManagerOptions, OperationOptions, OperationResult, PackageManager, PackageManagerName, addDependency, addDependencyCommand, addDevDependency, dedupeDependencies, detectPackageManager, dlx, dlxCommand, ensureDependencyInstalled, installDependencies, installDependenciesCommand, packageManagers, removeDependency, runScript, runScriptCommand };
@@ -13,11 +13,32 @@ async function findup(cwd, match, options = {}) {
13
13
  segments.pop();
14
14
  }
15
15
  }
16
- async function readPackageJSON(cwd) {
16
+ async function readPackageJSON(cwd, options = {}) {
17
17
  return findup(cwd, (p) => {
18
18
  const pkgPath = join$1(p, "package.json");
19
19
  if (existsSync(pkgPath)) return readFile(pkgPath, "utf8").then((data) => JSON.parse(data));
20
- });
20
+ }, options);
21
+ }
22
+ async function readInstalledPackageJSON(pkgName, cwd) {
23
+ const pkgJSONPath = await findup(cwd, (p) => {
24
+ const candidate = join$1(p, "node_modules", pkgName, "package.json");
25
+ if (existsSync(candidate)) return candidate;
26
+ }, { includeParentDirs: true });
27
+ if (!pkgJSONPath) return null;
28
+ try {
29
+ return JSON.parse(await readFile(pkgJSONPath, "utf8"));
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+ async function readPackageJSONFromResolver(requireFn, pkgName) {
35
+ let resolved;
36
+ try {
37
+ resolved = requireFn.resolve(pkgName);
38
+ } catch {
39
+ return null;
40
+ }
41
+ return readPackageJSON(resolved, { includeParentDirs: true });
21
42
  }
22
43
  function cached(fn) {
23
44
  let v;
@@ -307,8 +328,10 @@ async function addDependency(name, options = {}) {
307
328
  const _require = createRequire(join$1(resolvedOptions.cwd, "/_.js"));
308
329
  for (const _name of names) {
309
330
  const pkgName = _name.match(/^(.[^@]+)/)?.[0];
310
- const pkg = await readPackageJSON(_require.resolve(pkgName));
311
- if (!pkg?.peerDependencies || pkg?.name !== pkgName) continue;
331
+ if (!pkgName) continue;
332
+ let pkg = await readPackageJSONFromResolver(_require, pkgName);
333
+ if (pkg?.name !== pkgName) pkg = await readInstalledPackageJSON(pkgName, resolvedOptions.cwd);
334
+ if (!pkg?.peerDependencies) continue;
312
335
  for (const [peerDependency, version] of Object.entries(pkg.peerDependencies)) {
313
336
  if (pkg.peerDependenciesMeta?.[peerDependency]?.optional) continue;
314
337
  if (existingPkg?.dependencies?.[peerDependency] || existingPkg?.devDependencies?.[peerDependency]) continue;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nypm",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Unified Package Manager for Node.js",
5
5
  "license": "MIT",
6
6
  "repository": "unjs/nypm",
@@ -18,25 +18,25 @@
18
18
  ".": "./dist/index.mjs"
19
19
  },
20
20
  "dependencies": {
21
- "citty": "^0.2.0",
21
+ "citty": "^0.2.2",
22
22
  "pathe": "^2.0.3",
23
- "tinyexec": "^1.0.2"
23
+ "tinyexec": "^1.1.1"
24
24
  },
25
25
  "devDependencies": {
26
- "@types/node": "^25.2.1",
27
- "@typescript/native-preview": "^7.0.0-dev.20260205.1",
28
- "@vitest/coverage-v8": "^4.0.18",
26
+ "@types/node": "^25.6.0",
27
+ "@typescript/native-preview": "^7.0.0-dev.20260424.1",
28
+ "@vitest/coverage-v8": "^4.1.5",
29
29
  "automd": "^0.4.3",
30
30
  "changelogen": "^0.6.2",
31
31
  "eslint-config-unjs": "^0.6.2",
32
- "obuild": "^0.4.22",
33
- "oxfmt": "^0.28.0",
34
- "oxlint": "^1.43.0",
32
+ "obuild": "^0.4.33",
33
+ "oxfmt": "^0.46.0",
34
+ "oxlint": "^1.61.0",
35
35
  "pkg-types": "^2.3.0",
36
- "std-env": "^3.10.0",
37
- "typescript": "^5.9.3",
36
+ "std-env": "^4.1.0",
37
+ "typescript": "^6.0.3",
38
38
  "ufo": "^1.6.3",
39
- "vitest": "^4.0.18"
39
+ "vitest": "^4.1.5"
40
40
  },
41
41
  "engines": {
42
42
  "node": ">=18"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maizzle/framework",
3
- "version": "6.0.0-rc.14",
3
+ "version": "6.0.0-rc.16",
4
4
  "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
5
  "license": "MIT",
6
6
  "type": "module",