fuzzyworld-tools / commit
Find package.json above vite's root; v1.0.2
package.json | 2 +- vite/index.d.ts | 2 +- vite/index.js | 22 +++++++++++++++++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 995515c..1449830 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fuzzyworld-tools", - "version": "1.0.1", + "version": "1.0.2", "description": "Tooling for code.fuzzyworld.net and apps.fuzzyworld.net: fw command, deploy, vite plugin.", "type": "module", "bin": { diff --git a/vite/index.d.ts b/vite/index.d.ts index 5e67545..ea683a1 100644 --- a/vite/index.d.ts +++ b/vite/index.d.ts @@ -11,7 +11,7 @@ export interface FuzzyworldAppConfig { out?: string; } -/** Reads the "fuzzyworld" section of package.json in `root` (default: cwd). */ +/** Reads the "fuzzyworld" section of the nearest package.json at or above `root` (default: cwd). */ export function readAppConfig(root?: string): FuzzyworldAppConfig; /** Sets `base` to `/<app>/` for builds, from package.json `fuzzyworld.app`. */ diff --git a/vite/index.js b/vite/index.js index 15e57cc..a286937 100644 --- a/vite/index.js +++ b/vite/index.js @@ -9,12 +9,24 @@ import fs from 'node:fs'; import path from 'node:path'; +// Nearest package.json with a "fuzzyworld" section, from `start` upwards. Vite's `root` +// is often a subfolder (e.g. root: 'src'), while package.json sits at the repo root. +function findPackageJson(start) { + for (let dir = path.resolve(start); ; dir = path.dirname(dir)) { + const p = path.join(dir, 'package.json'); + if (fs.existsSync(p) && JSON.parse(fs.readFileSync(p, 'utf8')).fuzzyworld) return p; + if (path.dirname(dir) === dir) return null; + } +} + export function readAppConfig(root = process.cwd()) { - const pkgPath = path.join(root, 'package.json'); - const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); - const cfg = pkg.fuzzyworld; - if (!cfg || !cfg.app) { - throw new Error(`fuzzyworld: add "fuzzyworld": { "app": "<name>" } to ${pkgPath}`); + const pkgPath = findPackageJson(root); + if (!pkgPath) { + throw new Error(`fuzzyworld: add "fuzzyworld": { "app": "<name>" } to package.json (searched upwards from ${root})`); + } + const cfg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).fuzzyworld; + if (!cfg.app) { + throw new Error(`fuzzyworld: add "app" to the "fuzzyworld" section of ${pkgPath}`); } if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(cfg.app)) { throw new Error(`fuzzyworld: invalid app name "${cfg.app}"`);