docs(core): update server boundary rules and fix db import paths

- document `.server.js` suffix requirement for node-only imports in DEV.md
- add client-safe subentries table and server-only barrel warnings in MODULES.md
- fix `crud.js` and `database/index.js` to import from `db.server.js`
- replace `createRequire` with `pathToFileURL` in `discover.server.js` for ESM-only modules
- update admin navigation and registry to use safe client-compatible imports
- bump version to 1.4.132
This commit is contained in:
2026-04-25 15:05:26 -04:00
parent 0b32e8aa97
commit cb547f6400
8 changed files with 61 additions and 21 deletions
+19 -8
View File
@@ -1,7 +1,7 @@
import { readFile } from 'node:fs/promises';
import { readFileSync } from 'node:fs';
import { resolve, join, dirname } from 'node:path';
import { createRequire } from 'node:module';
import { pathToFileURL } from 'node:url';
import { info, warn } from '@zen/core/shared/logger';
import { registerModule } from './registry.js';
@@ -132,6 +132,20 @@ export async function findInstalledModuleNames({ cwd = process.cwd() } = {}) {
return out.sort();
}
/**
* Résout l'URL ESM du main entry d'un module à partir de son `package.json`.
* On lit `exports['.'].import` puis `main`, sinon `./index.js` par défaut.
* Pas de `require.resolve` : un module `@zen/module-*` peut déclarer uniquement
* la condition `"import"` (ESM-only) — la résolution CJS échouerait alors avec
* "No exports main defined". Comme on a déjà localisé le `package.json` via
* `resolveModulePackageJson`, on construit l'URL nous-mêmes.
*/
function resolveModuleEntryUrl(found) {
const pkgDir = dirname(found.path);
const main = found.pkg?.exports?.['.']?.import ?? found.pkg?.main ?? './index.js';
return pathToFileURL(resolve(pkgDir, main)).href;
}
/**
* Variante "Node-only" du chargement de modules — utilisée par le CLI
* `zen-db init` qui ne passe jamais par un bundler. Charge dynamiquement
@@ -145,20 +159,17 @@ export async function findInstalledModuleNames({ cwd = process.cwd() } = {}) {
*/
export async function loadModulesForCli({ cwd = process.cwd() } = {}) {
const names = await findInstalledModuleNames({ cwd });
const require = createRequire(join(cwd, 'package.json'));
for (const name of names) {
let entryPath;
try {
entryPath = require.resolve(name);
} catch (err) {
warn(`zen-modules: cannot resolve "${name}" — ${err.message}`);
const found = resolveModulePackageJson(name, cwd);
if (!found) {
warn(`zen-modules: cannot find package "${name}" in node_modules`);
continue;
}
let mod;
try {
mod = await import(entryPath);
mod = await import(resolveModuleEntryUrl(found));
} catch (err) {
warn(`zen-modules: failed to import "${name}" — ${err.message}`);
continue;