nuxt-layerscope 0.1.2 → 0.1.4
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/CHANGELOG.md +23 -0
- package/dist/{analyze-QaYmBXyK.mjs → analyze-BwmKhroS.mjs} +6 -99
- package/dist/analyze-vZUz30sN.mjs +2 -0
- package/dist/api.d.mts +100 -4
- package/dist/api.mjs +5 -4
- package/dist/bin.mjs +23 -14
- package/dist/component-files-B_qvkKwv.mjs +153 -0
- package/dist/{define-DNRGLVG_.d.mts → define-DDg4HQRH.d.mts} +1 -1
- package/dist/define.d.mts +1 -1
- package/dist/{effective-Dqg4EwH_.d.mts → effective-BPMNHe9A.d.mts} +1 -1
- package/dist/eslint.mjs +104 -74
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +203 -23
- package/dist/{file-analysis-Bh7qcWUK.mjs → layer-factory-DVSf2Wj4.mjs} +201 -462
- package/dist/owner-BA00V9VD.mjs +451 -0
- package/dist/report-DG-XzEq4.mjs +2 -0
- package/dist/{report-BNW0GCl9.mjs → report-jEMtNXS8.mjs} +27 -13
- package/dist/{unused-BtsPSfxb.mjs → unused-DbvZ4gRV.mjs} +1 -1
- package/dist/{version-DFWOUgi5.mjs → version-D5JrgoO_.mjs} +1 -1
- package/package.json +1 -1
- package/dist/analyze-DVzyPH7N.mjs +0 -2
- package/dist/component-files-DgOXNE6l.mjs +0 -12
- package/dist/layer-factory-DFh7nkFH.mjs +0 -182
- package/dist/report-DtAi0vPb.mjs +0 -2
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { basename, dirname, join, resolve } from "pathe";
|
|
2
|
-
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
3
|
-
//#region src/errors.ts
|
|
4
|
-
/** A config or input problem; the CLI exits with code 2. */
|
|
5
|
-
var LayerscopeError = class extends Error {
|
|
6
|
-
constructor(..._args) {
|
|
7
|
-
super(..._args);
|
|
8
|
-
this.name = "LayerscopeError";
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/layer-config-error.ts
|
|
13
|
-
/** A layer name in the config that matches no layer. */
|
|
14
|
-
var LayerConfigError = class extends LayerscopeError {
|
|
15
|
-
constructor(..._args) {
|
|
16
|
-
super(..._args);
|
|
17
|
-
this.name = "LayerConfigError";
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/config/rules.ts
|
|
22
|
-
const DEFAULT_SEVERITY = {
|
|
23
|
-
"layer-boundary": "error",
|
|
24
|
-
"unresolved-reference": "warn",
|
|
25
|
-
"shadowed-component": "warn"
|
|
26
|
-
};
|
|
27
|
-
/** Accepted in config for forward compatibility; not implemented yet. */
|
|
28
|
-
const RESERVED_RULES = /* @__PURE__ */ new Set(["unused-symbol"]);
|
|
29
|
-
const SEVERITIES = /* @__PURE__ */ new Set([
|
|
30
|
-
"off",
|
|
31
|
-
"warn",
|
|
32
|
-
"error"
|
|
33
|
-
]);
|
|
34
|
-
function isRuleName(name) {
|
|
35
|
-
return Object.hasOwn(DEFAULT_SEVERITY, name);
|
|
36
|
-
}
|
|
37
|
-
function ruleSeverity(config, rule) {
|
|
38
|
-
return config.rules?.[rule] ?? DEFAULT_SEVERITY[rule];
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/config/validate.ts
|
|
42
|
-
function validateConfig(config, file) {
|
|
43
|
-
for (const [rule, severity] of Object.entries(config.rules ?? {})) {
|
|
44
|
-
if (!isRuleName(rule) && !RESERVED_RULES.has(rule)) throw new LayerscopeError(`${file}: unknown rule "${rule}"`);
|
|
45
|
-
if (!SEVERITIES.has(String(severity))) throw new LayerscopeError(`${file}: rule "${rule}" must be "off", "warn" or "error", got ${JSON.stringify(severity)}`);
|
|
46
|
-
}
|
|
47
|
-
for (const [name, layer] of Object.entries(config.layers ?? {})) {
|
|
48
|
-
if (layer.allow !== void 0 && !Array.isArray(layer.allow)) throw new LayerscopeError(`${file}: layers.${name}.allow must be an array of layer names`);
|
|
49
|
-
if (layer.path !== void 0 && layer.source !== void 0) throw new LayerscopeError(`${file}: layers.${name} sets both "path" and "source"; use one`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/config/effective.ts
|
|
54
|
-
/** Where the module's options live when they come from `nuxt.config`. */
|
|
55
|
-
const NUXT_CONFIG_LABEL = "nuxt.config (layerscope)";
|
|
56
|
-
/** The keys that describe the project; `buildDir` only says where to look. */
|
|
57
|
-
const PROJECT_CONFIG_KEYS = [
|
|
58
|
-
"layers",
|
|
59
|
-
"rules",
|
|
60
|
-
"ignore",
|
|
61
|
-
"globals"
|
|
62
|
-
];
|
|
63
|
-
function hasProjectConfig(config) {
|
|
64
|
-
return PROJECT_CONFIG_KEYS.some((key) => config[key] !== void 0);
|
|
65
|
-
}
|
|
66
|
-
function pickProjectConfig(config) {
|
|
67
|
-
return Object.fromEntries(PROJECT_CONFIG_KEYS.flatMap((key) => config[key] === void 0 ? [] : [[key, config[key]]]));
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* `layerscope.config.*` or the `layerscope` key of `nuxt.config`, which the module records in the
|
|
71
|
-
* registry. Both at once is an error rather than a merge, so it is always clear which one applies.
|
|
72
|
-
*/
|
|
73
|
-
function effectiveConfig(fileConfig, recorded) {
|
|
74
|
-
if (recorded === void 0 || !hasProjectConfig(recorded)) return fileConfig;
|
|
75
|
-
if (hasProjectConfig(fileConfig)) throw new LayerscopeError("Layers or rules are set both in layerscope.config and in the \"layerscope\" key of nuxt.config. Keep one.");
|
|
76
|
-
validateConfig(recorded, NUXT_CONFIG_LABEL);
|
|
77
|
-
return {
|
|
78
|
-
...fileConfig,
|
|
79
|
-
...recorded
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
/** Names the `nuxt.config` key in a layer error, when the settings that caused it came from there. */
|
|
83
|
-
function labelConfigError(error, recorded) {
|
|
84
|
-
if (error instanceof LayerConfigError && recorded !== void 0 && hasProjectConfig(recorded)) return new LayerscopeError(`${NUXT_CONFIG_LABEL}: ${error.message}`);
|
|
85
|
-
return error;
|
|
86
|
-
}
|
|
87
|
-
//#endregion
|
|
88
|
-
//#region src/registry/schema.ts
|
|
89
|
-
/** Bumped on breaking changes to `registry.json`; readers fall back to the `.d.ts` files. */
|
|
90
|
-
const REGISTRY_VERSION = 1;
|
|
91
|
-
/** Relative to the Nuxt build dir. */
|
|
92
|
-
const REGISTRY_FILE = "layerscope/registry.json";
|
|
93
|
-
//#endregion
|
|
94
|
-
//#region src/utils/fs.ts
|
|
95
|
-
function isFile(path) {
|
|
96
|
-
try {
|
|
97
|
-
return statSync(path).isFile();
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function readJson(path) {
|
|
103
|
-
return JSON.parse(readFileSync(path, "utf8").replaceAll(/^\s*\/\/.*$/gmu, ""));
|
|
104
|
-
}
|
|
105
|
-
/** Symlinks resolved (pnpm links packages), or the path itself when it does not exist. */
|
|
106
|
-
function realPath(path) {
|
|
107
|
-
try {
|
|
108
|
-
return realpathSync(path);
|
|
109
|
-
} catch {
|
|
110
|
-
return path;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
//#endregion
|
|
114
|
-
//#region src/nuxt/remote-layer.ts
|
|
115
|
-
/** c12 clones remote layers into `node_modules/.c12`, or into `~/.cache/c12` without one. */
|
|
116
|
-
const CLONE_DIRS = /* @__PURE__ */ new Set([".c12", "c12"]);
|
|
117
|
-
/**
|
|
118
|
-
* c12 names a clone after the first three word segments of its `extends` source plus a hash of
|
|
119
|
-
* the whole source (`github:org/repo#v1` → `github_org_repo_<hash>`). The hash changes with the
|
|
120
|
-
* ref, so names and config matching use the prefix only.
|
|
121
|
-
*/
|
|
122
|
-
function clonePrefix(source) {
|
|
123
|
-
return source.replaceAll(/\W+/gu, "_").split("_").slice(0, 3).join("_");
|
|
124
|
-
}
|
|
125
|
-
/** The clone name without its hash, so it survives ref changes; `null` for other layers. */
|
|
126
|
-
function remoteLayerName(root) {
|
|
127
|
-
if (!CLONE_DIRS.has(basename(dirname(root)))) return null;
|
|
128
|
-
const name = basename(root);
|
|
129
|
-
const hashStart = name.lastIndexOf("_");
|
|
130
|
-
return hashStart === -1 ? name : name.slice(0, hashStart);
|
|
131
|
-
}
|
|
132
|
-
/** Whether the layer at `root` was cloned from this `extends` source. */
|
|
133
|
-
function isClonedFrom(root, source) {
|
|
134
|
-
return remoteLayerName(root) === clonePrefix(source);
|
|
135
|
-
}
|
|
136
|
-
//#endregion
|
|
137
|
-
//#region src/nuxt/layer-factory.ts
|
|
138
|
-
const ROOT_LAYER_NAME = "root";
|
|
139
|
-
/** Fallback for `@nuxt/kit` releases without `getLayerDirectories`. */
|
|
140
|
-
function deriveDirectories(layer, index, options) {
|
|
141
|
-
const root = resolve(layer.config.rootDir ?? layer.cwd);
|
|
142
|
-
return {
|
|
143
|
-
root,
|
|
144
|
-
app: resolve(root, layer.config.srcDir ?? "."),
|
|
145
|
-
server: index === 0 && options.serverDir !== void 0 ? resolve(options.serverDir) : resolve(root, layer.config.serverDir ?? "server"),
|
|
146
|
-
shared: resolve(root, layer.config.dir?.shared ?? options.dir?.shared ?? "shared")
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
/** Real paths, so they match symlinked paths in generated types and imports. */
|
|
150
|
-
function toDirs(dirs) {
|
|
151
|
-
const dir = (path) => realPath(resolve(path));
|
|
152
|
-
return {
|
|
153
|
-
root: dir(dirs.root),
|
|
154
|
-
srcDir: dir(dirs.app),
|
|
155
|
-
serverDir: dir(dirs.server),
|
|
156
|
-
sharedDir: dir(dirs.shared)
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
function layerFromNuxt(layer, index, dirs) {
|
|
160
|
-
const resolved = toDirs(dirs);
|
|
161
|
-
return {
|
|
162
|
-
name: layer.meta?.name ?? layer.config.$meta?.name ?? (index === 0 ? "root" : remoteLayerName(resolved.root) ?? basename(resolved.root)),
|
|
163
|
-
...resolved,
|
|
164
|
-
defaultComponents: layer.config.components === void 0
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/** Without @nuxt/kit, assume Nuxt defaults: `app/` as srcDir when it exists (Nuxt 4). */
|
|
168
|
-
function layerFromPath(name, root) {
|
|
169
|
-
const appDir = join(root, "app");
|
|
170
|
-
return {
|
|
171
|
-
name,
|
|
172
|
-
...toDirs({
|
|
173
|
-
root,
|
|
174
|
-
app: existsSync(appDir) ? appDir : root,
|
|
175
|
-
server: join(root, "server"),
|
|
176
|
-
shared: join(root, "shared")
|
|
177
|
-
}),
|
|
178
|
-
defaultComponents: true
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
//#endregion
|
|
182
|
-
export { LayerConfigError as _, isClonedFrom as a, realPath as c, effectiveConfig as d, labelConfigError as f, ruleSeverity as g, isRuleName as h, layerFromPath as i, REGISTRY_FILE as l, validateConfig as m, deriveDirectories as n, isFile as o, pickProjectConfig as p, layerFromNuxt as r, readJson as s, ROOT_LAYER_NAME as t, REGISTRY_VERSION as u, LayerscopeError as v };
|
package/dist/report-DtAi0vPb.mjs
DELETED