@forgebook/nuxt 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +121 -2
- package/dist/src/app/components.d.ts +119 -0
- package/dist/src/app/components.js +196 -0
- package/dist/src/app/data.d.ts +109 -0
- package/dist/src/app/data.js +155 -0
- package/dist/src/app/define.d.ts +30 -0
- package/dist/src/app/define.js +30 -0
- package/dist/src/app/errors.d.ts +43 -0
- package/dist/src/app/errors.js +41 -0
- package/dist/src/app/fetch.d.ts +63 -0
- package/dist/src/app/fetch.js +73 -0
- package/dist/src/app/head.d.ts +28 -0
- package/dist/src/app/head.js +23 -0
- package/dist/src/app/router.d.ts +69 -0
- package/dist/src/app/router.js +93 -0
- package/dist/src/app/state.d.ts +107 -0
- package/dist/src/app/state.js +137 -0
- package/dist/src/asyncDataRun.d.ts +39 -0
- package/dist/src/asyncDataRun.js +128 -0
- package/dist/src/nuxtError.d.ts +50 -0
- package/dist/src/nuxtError.js +65 -0
- package/dist/src/nuxtRenderer.d.ts +14 -0
- package/dist/src/nuxtRenderer.js +67 -0
- package/dist/src/nuxtStore.d.ts +144 -0
- package/dist/src/nuxtStore.js +196 -0
- package/dist/src/pageProject.d.ts +11 -0
- package/dist/src/pageProject.js +11 -0
- package/dist/src/parameters.d.ts +67 -0
- package/dist/src/parameters.js +89 -0
- package/dist/src/project.d.ts +49 -0
- package/dist/src/project.js +7 -0
- package/dist/src/renderer.d.ts +9 -0
- package/dist/src/renderer.js +10 -0
- package/dist/src/stories.d.ts +54 -0
- package/dist/src/stories.js +11 -0
- package/dist/src/storyCode.d.ts +3 -0
- package/dist/src/storyCode.js +9 -0
- package/dist/src/storyFetch.d.ts +74 -0
- package/dist/src/storyFetch.js +146 -0
- package/dist/src/storyNuxt.d.ts +48 -0
- package/dist/src/storyNuxt.js +26 -0
- package/dist/src/vite/componentNames.d.ts +36 -0
- package/dist/src/vite/componentNames.js +72 -0
- package/dist/src/vite/extractDocs.d.ts +16 -0
- package/dist/src/vite/extractDocs.js +22 -0
- package/dist/src/vite/nuxt.d.ts +13 -0
- package/dist/src/vite/nuxt.js +36 -0
- package/dist/src/vite/nuxtConfig.d.ts +85 -0
- package/dist/src/vite/nuxtConfig.js +261 -0
- package/dist/src/vite/nuxtPlugin.d.ts +51 -0
- package/dist/src/vite/nuxtPlugin.js +466 -0
- package/dist/src/vite/pageRoutes.d.ts +23 -0
- package/dist/src/vite/pageRoutes.js +88 -0
- package/dist/src/vite/placeKeys.d.ts +10 -0
- package/dist/src/vite/placeKeys.js +117 -0
- package/dist/src/vite/standIns.d.ts +26 -0
- package/dist/src/vite/standIns.js +96 -0
- package/package.json +118 -3
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The project's `nuxt.config`, as far as a catalogue reads it: its folders, its aliases, its components' and
|
|
11
|
+
* auto-imports' folders, its style sheets, its public runtime config and its app config.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The file is loaded as Node loads a module (a `nuxt.config.ts` with its types stripped), with `defineNuxtConfig`
|
|
15
|
+
* given as Nuxt gives it, a function that returns its argument; what it returns is read, never trusted: a field of the
|
|
16
|
+
* wrong type is left out. Everything else in it (modules, Nitro, the server's routes, the build) concerns Nuxt's server
|
|
17
|
+
* or its own build, so a story does not need it. A file that cannot be loaded is a warning, not a failure: the
|
|
18
|
+
* catalogue still opens with Nuxt's defaults.
|
|
19
|
+
*
|
|
20
|
+
* The runtime config keeps its `public` part only, since that is all Nuxt sends to the browser; a `NUXT_PUBLIC_`
|
|
21
|
+
* variable of the environment or the `.env` files replaces the value it names, as Nuxt's does.
|
|
22
|
+
*
|
|
23
|
+
* Every path it gives is in Vite's form, with forward slashes on every system: the plugin compares them with the ids
|
|
24
|
+
* Vite hands it and writes them into the modules it makes, which on Windows would not meet a path with backslashes.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import { existsSync, statSync } from "node:fs";
|
|
29
|
+
import nodePath from "node:path";
|
|
30
|
+
import { pathToFileURL } from "node:url";
|
|
31
|
+
import { normalizePath } from "vite";
|
|
32
|
+
/** The names `nuxt.config` may have, in the order Nuxt looks for them. */
|
|
33
|
+
export const NUXT_CONFIG_FILES = [
|
|
34
|
+
"nuxt.config.ts",
|
|
35
|
+
"nuxt.config.mts",
|
|
36
|
+
"nuxt.config.js",
|
|
37
|
+
"nuxt.config.mjs",
|
|
38
|
+
"nuxt.config.cjs"
|
|
39
|
+
];
|
|
40
|
+
/** The names `app.config` may have. */
|
|
41
|
+
const APP_CONFIG_FILES = ["app.config.ts", "app.config.mts", "app.config.js", "app.config.mjs"];
|
|
42
|
+
/** The global function a `nuxt.config` calls without importing it. */
|
|
43
|
+
const DEFINE_CONFIG = "defineNuxtConfig";
|
|
44
|
+
/** Whether a value is a plain object. */
|
|
45
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46
|
+
/**
|
|
47
|
+
* An object field, or an empty object.
|
|
48
|
+
*
|
|
49
|
+
* @param config - the object.
|
|
50
|
+
* @param name - the field.
|
|
51
|
+
*/
|
|
52
|
+
const objectField = (config, name) => {
|
|
53
|
+
const value = config[name];
|
|
54
|
+
return isRecord(value) ? value : {};
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* A text field, or none.
|
|
58
|
+
*
|
|
59
|
+
* @param config - the object.
|
|
60
|
+
* @param name - the field.
|
|
61
|
+
*/
|
|
62
|
+
const textField = (config, name) => {
|
|
63
|
+
const value = config[name];
|
|
64
|
+
return typeof value === "string" ? value : undefined;
|
|
65
|
+
};
|
|
66
|
+
/** `path.join`, in Vite's form. */
|
|
67
|
+
const join = (...segments) => normalizePath(nodePath.join(...segments));
|
|
68
|
+
/** `path.resolve`, in Vite's form. */
|
|
69
|
+
const resolve = (...segments) => normalizePath(nodePath.resolve(...segments));
|
|
70
|
+
/** Whether a path is a folder. */
|
|
71
|
+
const isFolder = (path) => existsSync(path) && statSync(path).isDirectory();
|
|
72
|
+
/**
|
|
73
|
+
* A path as Nuxt resolves one written in its config: `~`, `@`, `~~` and `@@` replaced, a relative path from the
|
|
74
|
+
* project's folder, a package left as it is.
|
|
75
|
+
*
|
|
76
|
+
* @param path - the path.
|
|
77
|
+
* @param rootDir - the project's folder.
|
|
78
|
+
* @param srcDir - its sources' folder.
|
|
79
|
+
*/
|
|
80
|
+
export const resolvedPath = (path, rootDir, srcDir) => {
|
|
81
|
+
const root = /^(~~|@@)(?=\/|$)/.exec(path);
|
|
82
|
+
if (root !== null)
|
|
83
|
+
return join(rootDir, path.slice(root[0].length));
|
|
84
|
+
const src = /^(~|@)(?=\/|$)/.exec(path);
|
|
85
|
+
if (src !== null)
|
|
86
|
+
return join(srcDir, path.slice(src[0].length));
|
|
87
|
+
if (nodePath.isAbsolute(path))
|
|
88
|
+
return normalizePath(path);
|
|
89
|
+
if (path.startsWith("."))
|
|
90
|
+
return resolve(rootDir, path);
|
|
91
|
+
return path;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* A folder of `imports.dirs`: an alias as Nuxt resolves it, anything else from the sources' folder, as Nuxt reads it.
|
|
95
|
+
*
|
|
96
|
+
* @param path - the folder, as written.
|
|
97
|
+
* @param rootDir - the project's folder.
|
|
98
|
+
* @param srcDir - its sources' folder.
|
|
99
|
+
*/
|
|
100
|
+
const importsDir = (path, rootDir, srcDir) => {
|
|
101
|
+
const resolved = resolvedPath(path, rootDir, srcDir);
|
|
102
|
+
return nodePath.isAbsolute(resolved) && resolved !== resolve(rootDir, path)
|
|
103
|
+
? resolved
|
|
104
|
+
: resolve(srcDir, path);
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* The components' folders a config gives: `components/` of the sources by default, none for `false`, else each entry
|
|
108
|
+
* of the list (or of `dirs`), a path or `{ path, prefix, pathPrefix }`.
|
|
109
|
+
*
|
|
110
|
+
* @param value - `components`.
|
|
111
|
+
* @param rootDir - the project's folder.
|
|
112
|
+
* @param srcDir - its sources' folder.
|
|
113
|
+
*/
|
|
114
|
+
const componentsDirsOf = (value, rootDir, srcDir) => {
|
|
115
|
+
if (value === false)
|
|
116
|
+
return [];
|
|
117
|
+
const entries = isRecord(value) ? value["dirs"] : value;
|
|
118
|
+
// Nuxt's own: the islands' and the global folders inside the components' one, each scanned before it
|
|
119
|
+
const list = Array.isArray(entries)
|
|
120
|
+
? entries
|
|
121
|
+
: ["~/components/islands", "~/components/global", "~/components"];
|
|
122
|
+
return list.flatMap((entry) => {
|
|
123
|
+
if (typeof entry === "string")
|
|
124
|
+
return [{ path: resolvedPath(entry, rootDir, srcDir), prefix: "", pathPrefix: true }];
|
|
125
|
+
if (!isRecord(entry))
|
|
126
|
+
return [];
|
|
127
|
+
const path = textField(entry, "path");
|
|
128
|
+
if (path === undefined)
|
|
129
|
+
return [];
|
|
130
|
+
return [
|
|
131
|
+
{
|
|
132
|
+
path: resolvedPath(path, rootDir, srcDir),
|
|
133
|
+
prefix: textField(entry, "prefix") ?? "",
|
|
134
|
+
pathPrefix: entry["pathPrefix"] !== false
|
|
135
|
+
}
|
|
136
|
+
];
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* What a catalogue reads of a configuration Nuxt would read.
|
|
141
|
+
*
|
|
142
|
+
* @param raw - what the file exported.
|
|
143
|
+
* @param file - the file.
|
|
144
|
+
* @param projectDir - the project's folder.
|
|
145
|
+
*/
|
|
146
|
+
export const readNuxtConfig = (raw, file, projectDir) => {
|
|
147
|
+
const rootDir = normalizePath(projectDir);
|
|
148
|
+
const config = isRecord(raw) ? raw : {};
|
|
149
|
+
const srcGiven = textField(config, "srcDir");
|
|
150
|
+
// Nuxt 4 keeps the sources in `app/`; a project laid out as Nuxt 3's has them at its root
|
|
151
|
+
const nuxt4Dir = join(rootDir, "app");
|
|
152
|
+
const defaultDir = isFolder(nuxt4Dir) ? nuxt4Dir : rootDir;
|
|
153
|
+
const srcDir = srcGiven === undefined ? defaultDir : resolve(rootDir, srcGiven);
|
|
154
|
+
const dir = objectField(config, "dir");
|
|
155
|
+
const app = objectField(config, "app");
|
|
156
|
+
const imports = objectField(config, "imports");
|
|
157
|
+
const extraImports = imports["dirs"];
|
|
158
|
+
const css = config["css"];
|
|
159
|
+
const appConfigFile = APP_CONFIG_FILES.map((name) => join(srcDir, name)).find((path) => existsSync(path));
|
|
160
|
+
return {
|
|
161
|
+
file,
|
|
162
|
+
rootDir,
|
|
163
|
+
srcDir,
|
|
164
|
+
pagesDir: join(srcDir, textField(dir, "pages") ?? "pages"),
|
|
165
|
+
alias: {
|
|
166
|
+
...Object.fromEntries(Object.entries(objectField(config, "alias")).flatMap(([name, path]) => typeof path === "string" ? [[name, resolvedPath(path, rootDir, srcDir)]] : []))
|
|
167
|
+
},
|
|
168
|
+
componentsDirs: componentsDirsOf(config["components"], rootDir, srcDir),
|
|
169
|
+
importsDirs: [
|
|
170
|
+
join(srcDir, "composables"),
|
|
171
|
+
join(srcDir, "utils"),
|
|
172
|
+
join(rootDir, "shared", "utils"),
|
|
173
|
+
...(Array.isArray(extraImports)
|
|
174
|
+
? extraImports.flatMap((each) => typeof each === "string" ? [importsDir(each, rootDir, srcDir)] : [])
|
|
175
|
+
: [])
|
|
176
|
+
],
|
|
177
|
+
isAutoImport: imports["autoImport"] !== false,
|
|
178
|
+
css: Array.isArray(css)
|
|
179
|
+
? css.flatMap((each) => typeof each === "string" ? [resolvedPath(each, rootDir, srcDir)] : [])
|
|
180
|
+
: [],
|
|
181
|
+
publicRuntimeConfig: objectField(objectField(config, "runtimeConfig"), "public"),
|
|
182
|
+
baseURL: textField(app, "baseURL") ?? "/",
|
|
183
|
+
buildAssetsDir: textField(app, "buildAssetsDir") ?? "/_nuxt/",
|
|
184
|
+
appConfig: objectField(config, "appConfig"),
|
|
185
|
+
appConfigFile
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* The project's `nuxt.config` file: the first Nuxt would find in its folder.
|
|
190
|
+
*
|
|
191
|
+
* @param rootDir - the project's folder.
|
|
192
|
+
*/
|
|
193
|
+
export const nuxtConfigFile = (rootDir) => NUXT_CONFIG_FILES.map((name) => join(rootDir, name)).find((file) => existsSync(file));
|
|
194
|
+
/**
|
|
195
|
+
* Loads a project's `nuxt.config`.
|
|
196
|
+
*
|
|
197
|
+
* @param rootDir - the project's folder.
|
|
198
|
+
* @returns what the catalogue reads of it, and why it could not be loaded when it could not.
|
|
199
|
+
*/
|
|
200
|
+
export const loadNuxtConfig = async (rootDir) => {
|
|
201
|
+
const file = nuxtConfigFile(rootDir);
|
|
202
|
+
if (file === undefined)
|
|
203
|
+
return { config: readNuxtConfig({}, undefined, rootDir), problem: undefined };
|
|
204
|
+
// Nuxt gives the file this function without an import; one the project already has (Nuxt's own) is left as it is
|
|
205
|
+
const isGiven = !(DEFINE_CONFIG in globalThis);
|
|
206
|
+
if (isGiven)
|
|
207
|
+
Reflect.set(globalThis, DEFINE_CONFIG, (config) => config);
|
|
208
|
+
try {
|
|
209
|
+
const loaded = await import(__rewriteRelativeImportExtension(pathToFileURL(file).href));
|
|
210
|
+
const exported = isRecord(loaded) && "default" in loaded ? loaded["default"] : loaded;
|
|
211
|
+
const raw = typeof exported === "function" ? await Reflect.apply(exported, undefined, []) : exported;
|
|
212
|
+
return { config: readNuxtConfig(raw, file, rootDir), problem: undefined };
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
216
|
+
return { config: readNuxtConfig({}, file, rootDir), problem: `${file} could not be loaded (${reason})` };
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
if (isGiven)
|
|
220
|
+
Reflect.deleteProperty(globalThis, DEFINE_CONFIG);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* A key as Nuxt writes it in a variable's name: `apiBase` as `API_BASE`.
|
|
225
|
+
*
|
|
226
|
+
* @param key - the key.
|
|
227
|
+
*/
|
|
228
|
+
const envName = (key) => key
|
|
229
|
+
.replace(/([a-z\d])([A-Z])/g, "$1_$2")
|
|
230
|
+
.replace(/[-.]/g, "_")
|
|
231
|
+
.toUpperCase();
|
|
232
|
+
/**
|
|
233
|
+
* A variable's value as Nuxt reads it: JSON when it is (a number, a boolean, an object), else the text.
|
|
234
|
+
*
|
|
235
|
+
* @param value - the variable's value.
|
|
236
|
+
*/
|
|
237
|
+
const envValue = (value) => {
|
|
238
|
+
try {
|
|
239
|
+
const parsed = JSON.parse(value);
|
|
240
|
+
return parsed;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return value;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* The public runtime config with the environment's variables over it: `NUXT_PUBLIC_API_BASE` replaces
|
|
248
|
+
* `public.apiBase`, a nested key adding its name (`NUXT_PUBLIC_MAP_KEY` for `public.map.key`). Only a key the config
|
|
249
|
+
* has is replaced, as Nuxt replaces it.
|
|
250
|
+
*
|
|
251
|
+
* @param config - the config's `public` part.
|
|
252
|
+
* @param env - the variables, by name.
|
|
253
|
+
* @param prefix - the variables' prefix for this level; `NUXT_PUBLIC_` at the top.
|
|
254
|
+
*/
|
|
255
|
+
export const withEnvironment = (config, env, prefix = "NUXT_PUBLIC_") => Object.fromEntries(Object.entries(config).map(([key, value]) => {
|
|
256
|
+
const name = `${prefix}${envName(key)}`;
|
|
257
|
+
const given = env[name];
|
|
258
|
+
if (given !== undefined)
|
|
259
|
+
return [key, envValue(given)];
|
|
260
|
+
return [key, isRecord(value) ? withEnvironment(value, env, `${name}_`) : value];
|
|
261
|
+
}));
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
import { type PluginOption } from "vite";
|
|
3
|
+
import { type ProjectComponent } from "./componentNames.ts";
|
|
4
|
+
import type { NuxtOptions } from "./nuxt.ts";
|
|
5
|
+
import { type NuxtProjectConfig } from "./nuxtConfig.ts";
|
|
6
|
+
/** The frame page's module: Forgebook's frame with the Nuxt renderer, after the project's style sheets. */
|
|
7
|
+
export declare const FRAME_MODULE = "virtual:forgebook-nuxt/frame";
|
|
8
|
+
/**
|
|
9
|
+
* The project's components, by name: the first folder that names one wins, as in Nuxt. A file whose name makes no
|
|
10
|
+
* JavaScript name (`a;b.vue`) is left out, since its name is written into code.
|
|
11
|
+
*
|
|
12
|
+
* @param config - the project's config.
|
|
13
|
+
*/
|
|
14
|
+
export declare const componentsOf: (config: NuxtProjectConfig) => {
|
|
15
|
+
readonly components: Map<string, ProjectComponent>;
|
|
16
|
+
readonly skipped: string[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A template's components given their imports, as Nuxt's loader writes them: Nuxt's own, the project's, and a project
|
|
20
|
+
* component's `Lazy` form loaded when it is first drawn.
|
|
21
|
+
*
|
|
22
|
+
* @param code - the compiled component.
|
|
23
|
+
* @param components - the project's components, by name.
|
|
24
|
+
* @returns the code changed, or none when it names no component the plugin knows.
|
|
25
|
+
*/
|
|
26
|
+
export declare const withComponentImports: (code: MagicString, components: ReadonlyMap<string, ProjectComponent>) => MagicString | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Nuxt 3's `process.client`, `process.server`, `process.browser` and `process.dev` written as their values in a
|
|
29
|
+
* project's file. Only there: given to the whole page (Vite's `define`), they would reach the libraries the frame
|
|
30
|
+
* loads, and one that reads `process.browser` would then read `process.env`, which the page does not have.
|
|
31
|
+
*
|
|
32
|
+
* @param code - the file's code, changed in place.
|
|
33
|
+
* @param isDev - whether the catalogue runs in development.
|
|
34
|
+
* @returns whether one was written.
|
|
35
|
+
*/
|
|
36
|
+
export declare const withProcessFlags: (code: MagicString, isDev: boolean) => boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether a file is one of the project's own: inside its folder, not in a folder beside it whose name starts the same
|
|
39
|
+
* (`app-admin` beside `app`).
|
|
40
|
+
*
|
|
41
|
+
* @param file - the file, as Vite names it.
|
|
42
|
+
* @param rootDir - the project's folder.
|
|
43
|
+
*/
|
|
44
|
+
export declare const isProjectFile: (file: string, rootDir: string) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The plugins of a Nuxt catalogue.
|
|
47
|
+
*
|
|
48
|
+
* @param options - the options of `nuxt()`.
|
|
49
|
+
* @returns the plugins.
|
|
50
|
+
*/
|
|
51
|
+
export declare const nuxtPlugins: (options?: NuxtOptions) => PluginOption[];
|