@asheeui/next 0.3.1
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/dist/index.cjs +290 -0
- package/dist/index.d.cts +256 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +256 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +282 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ashee Softworks
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
let _asheeui_utils_node = require("@asheeui/utils/node");
|
|
5
|
+
//#region src/generate.ts
|
|
6
|
+
/**
|
|
7
|
+
* The import specifier used across AsheeUI for the config module.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import config from "virtual:ashee-config";
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
const VIRTUAL_ID = "virtual:ashee-config";
|
|
15
|
+
/**
|
|
16
|
+
* Location of the generated shim, relative to the project root.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately kept outside `node_modules`: package managers and CI
|
|
19
|
+
* treat `node_modules` as fully disposable, and a shim the dev server
|
|
20
|
+
* depends on should not live somewhere that can vanish out from under
|
|
21
|
+
* it.
|
|
22
|
+
*/
|
|
23
|
+
const SHIM_RELATIVE_PATH = ".ashee/generated-config.mjs";
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the absolute path of the generated shim for a project root.
|
|
26
|
+
*
|
|
27
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
28
|
+
* @returns Absolute path of the shim file.
|
|
29
|
+
*/
|
|
30
|
+
function resolveShimPath(root) {
|
|
31
|
+
return (0, node_path.resolve)(root ?? process.cwd(), SHIM_RELATIVE_PATH);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve every candidate config filename to an absolute path under
|
|
35
|
+
* `root`, whether or not the files currently exist.
|
|
36
|
+
*
|
|
37
|
+
* These paths are registered as webpack "missing dependencies" so that
|
|
38
|
+
* creating a config file for the first time triggers a rebuild.
|
|
39
|
+
*
|
|
40
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
41
|
+
* @returns Absolute paths for every known config filename.
|
|
42
|
+
*/
|
|
43
|
+
function resolveCandidatePaths(root) {
|
|
44
|
+
const base = root ?? process.cwd();
|
|
45
|
+
return _asheeui_utils_node.CANDIDATES.map((file) => (0, node_path.resolve)(base, file));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build an import specifier for `toFile` relative to `fromFile`'s directory.
|
|
49
|
+
*
|
|
50
|
+
* Turbopack rejects absolute ("server-relative") import specifiers, so the
|
|
51
|
+
* shim must reference the discovered config with a path relative to itself.
|
|
52
|
+
*
|
|
53
|
+
* @param fromFile - Absolute path of the importing file.
|
|
54
|
+
* @param toFile - Absolute path of the imported file.
|
|
55
|
+
* @returns A `./`-prefixed relative specifier.
|
|
56
|
+
*/
|
|
57
|
+
function toRelativeSpecifier(fromFile, toFile) {
|
|
58
|
+
const rel = (0, node_path.relative)((0, node_path.dirname)(fromFile), toFile).replaceAll("\\", "/");
|
|
59
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Regenerate the config shim, mirroring `@asheeui/vite`'s virtual module:
|
|
63
|
+
* if a config file exists we re-export its default export, otherwise we
|
|
64
|
+
* export `undefined`.
|
|
65
|
+
*
|
|
66
|
+
* The write is skipped when the content is unchanged, so webpack's
|
|
67
|
+
* `beforeCompile` hook does not churn the file (or Turbopack's watcher)
|
|
68
|
+
* on every rebuild.
|
|
69
|
+
*
|
|
70
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
71
|
+
* @returns The absolute path of the regenerated shim file.
|
|
72
|
+
*/
|
|
73
|
+
function generateShim(root) {
|
|
74
|
+
const shimPath = resolveShimPath(root);
|
|
75
|
+
const configPath = (0, _asheeui_utils_node.discoverConfig)(root);
|
|
76
|
+
const content = configPath ? `export { default } from ${JSON.stringify(toRelativeSpecifier(shimPath, configPath))};\n` : "export default undefined;\n";
|
|
77
|
+
if (!(0, node_fs.existsSync)(shimPath) || (0, node_fs.readFileSync)(shimPath, "utf8") !== content) {
|
|
78
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(shimPath), { recursive: true });
|
|
79
|
+
(0, node_fs.writeFileSync)(shimPath, content, "utf8");
|
|
80
|
+
}
|
|
81
|
+
return shimPath;
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/turbopack.ts
|
|
85
|
+
/**
|
|
86
|
+
* Point `virtual:ashee-config` at the generated shim inside a Turbopack
|
|
87
|
+
* config section.
|
|
88
|
+
*
|
|
89
|
+
* The given `target` object is mutated and then returned so the caller
|
|
90
|
+
* can use it in an inline expression.
|
|
91
|
+
*
|
|
92
|
+
* @param target - Turbopack config section (stable or experimental).
|
|
93
|
+
* @param shimPath - Project-root-relative path of the generated shim.
|
|
94
|
+
* @returns The same `target` object, with the alias registered.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const turbopack = addAsheeConfigResolveAlias(
|
|
99
|
+
* { resolveAlias: {} },
|
|
100
|
+
* "./.ashee/generated-config.mjs",
|
|
101
|
+
* );
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
function addAsheeConfigResolveAlias(target, shimPath) {
|
|
105
|
+
target.resolveAlias ??= {};
|
|
106
|
+
target.resolveAlias[VIRTUAL_ID] = shimPath;
|
|
107
|
+
return target;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/webpack.ts
|
|
111
|
+
/**
|
|
112
|
+
* Exact-match alias key (`$`-suffixed) so a hypothetical future
|
|
113
|
+
* `virtual:ashee-config/foo` import does not also resolve through this
|
|
114
|
+
* alias.
|
|
115
|
+
*/
|
|
116
|
+
const EXACT_VIRTUAL_ID = `${VIRTUAL_ID}$`;
|
|
117
|
+
/**
|
|
118
|
+
* Point `virtual:ashee-config` at the generated shim so app code keeps
|
|
119
|
+
* using the same import specifier as Vite.
|
|
120
|
+
*
|
|
121
|
+
* @param config - Webpack config section to patch (mutated in place).
|
|
122
|
+
* @param shimPath - Absolute path of the generated shim.
|
|
123
|
+
* @returns The same `config` object, with the alias registered.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const config = addAsheeConfigAlias(
|
|
128
|
+
* { resolve: { alias: {} } },
|
|
129
|
+
* "/proj/.ashee/generated-config.mjs",
|
|
130
|
+
* );
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function addAsheeConfigAlias(config, shimPath) {
|
|
134
|
+
config.resolve ??= {};
|
|
135
|
+
config.resolve.alias ??= {};
|
|
136
|
+
config.resolve.alias[EXACT_VIRTUAL_ID] = shimPath;
|
|
137
|
+
return config;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Create a dev-only webpack plugin that regenerates the shim before
|
|
141
|
+
* every compile so edits to an existing config file are always picked
|
|
142
|
+
* up.
|
|
143
|
+
*
|
|
144
|
+
* The plugin also registers every candidate filename as a webpack
|
|
145
|
+
* "missing dependency": the shim has no reference to a file that does
|
|
146
|
+
* not exist yet, so without this, *creating* the config file for the
|
|
147
|
+
* first time would never trigger a rebuild on its own. Writes are
|
|
148
|
+
* skipped when content is unchanged, keeping rebuilds cheap.
|
|
149
|
+
*
|
|
150
|
+
* @param regenerate - Callback that rewrites the shim file.
|
|
151
|
+
* @param candidatePaths - Absolute candidate config paths to watch as
|
|
152
|
+
* missing dependencies.
|
|
153
|
+
* @returns A webpack plugin object.
|
|
154
|
+
*/
|
|
155
|
+
function createBeforeCompilePlugin(regenerate, candidatePaths) {
|
|
156
|
+
return { apply(compiler) {
|
|
157
|
+
compiler.hooks.beforeCompile.tap("ashee:virtual-config", () => {
|
|
158
|
+
regenerate();
|
|
159
|
+
});
|
|
160
|
+
compiler.hooks.afterCompile.tap("ashee:virtual-config", (compilation) => {
|
|
161
|
+
for (const path of candidatePaths) compilation.missingDependencies.add(path);
|
|
162
|
+
});
|
|
163
|
+
} };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Create the webpack hook that Next invokes when building.
|
|
167
|
+
*
|
|
168
|
+
* The returned hook always adds the config alias; in dev mode it also
|
|
169
|
+
* installs the `beforeCompile` regeneration plugin and the
|
|
170
|
+
* missing-dependency watcher.
|
|
171
|
+
*
|
|
172
|
+
* @param options - Hook options.
|
|
173
|
+
* @param options.shimPath - Absolute path of the generated shim.
|
|
174
|
+
* @param options.candidatePaths - Absolute candidate config paths.
|
|
175
|
+
* @param options.root - Project root used when regenerating the shim.
|
|
176
|
+
* @param options.regenerate - Function that regenerates the shim for a
|
|
177
|
+
* given root directory.
|
|
178
|
+
* @returns A webpack config hook matching Next's `webpack` signature.
|
|
179
|
+
*/
|
|
180
|
+
function createWebpackHook(options) {
|
|
181
|
+
const { shimPath, candidatePaths, regenerate, root } = options;
|
|
182
|
+
return (config, context) => {
|
|
183
|
+
addAsheeConfigAlias(config, shimPath);
|
|
184
|
+
if (context.dev) {
|
|
185
|
+
config.plugins ??= [];
|
|
186
|
+
config.plugins.push(createBeforeCompilePlugin(() => regenerate(root), candidatePaths));
|
|
187
|
+
}
|
|
188
|
+
return config;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/with-ashee-ui.ts
|
|
193
|
+
/**
|
|
194
|
+
* AsheeUI packages that ship TypeScript source and must be compiled by
|
|
195
|
+
* Next.
|
|
196
|
+
*
|
|
197
|
+
* `transpilePackages` takes npm package names, deduped against any the
|
|
198
|
+
* consumer provides.
|
|
199
|
+
*/
|
|
200
|
+
const ASHEE_TRANSPILE_PACKAGES = ["asheeui"];
|
|
201
|
+
/**
|
|
202
|
+
* Wrap a `next.config.mjs`/`next.config.ts` object with AsheeUI
|
|
203
|
+
* integration.
|
|
204
|
+
*
|
|
205
|
+
* The wrapper:
|
|
206
|
+
* 1. Generates a config shim at `.ashee/generated-config.mjs` (same
|
|
207
|
+
* resolution as `@asheeui/vite`'s `virtual:ashee-config`).
|
|
208
|
+
* 2. Adds a `virtual:ashee-config` alias for Webpack and Turbopack so
|
|
209
|
+
* app code uses the identical import specifier in both bundlers.
|
|
210
|
+
* Webpack gets an absolute path (it resolves against its own
|
|
211
|
+
* context, not the `root` override), Turbopack gets a
|
|
212
|
+
* project-root-relative one (it rejects absolute targets).
|
|
213
|
+
* 3. Merges `transpilePackages` so AsheeUI's source-shipping packages
|
|
214
|
+
* are compiled by Next.
|
|
215
|
+
*
|
|
216
|
+
* @param config - Next config to wrap. AsheeUI override keys (`root`,
|
|
217
|
+
* `transpilePackages`) are consumed and stripped from the returned
|
|
218
|
+
* `NextConfig`. Defaults to `{}`.
|
|
219
|
+
* @returns A plain `NextConfig` with the AsheeUI integration applied.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```ts
|
|
223
|
+
* // next.config.ts
|
|
224
|
+
* import { withAsheeUI } from "@asheeui/next";
|
|
225
|
+
*
|
|
226
|
+
* export default withAsheeUI({
|
|
227
|
+
* transpilePackages: ["@my-org/ui"],
|
|
228
|
+
* });
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
function withAsheeUI(config = {}) {
|
|
232
|
+
const { root, transpilePackages: extraTranspilePackages, ...nextConfig } = config;
|
|
233
|
+
const baseDir = root ?? process.cwd();
|
|
234
|
+
const legacyConfig = nextConfig;
|
|
235
|
+
generateShim(baseDir);
|
|
236
|
+
const absoluteShimPath = resolveShimPath(baseDir);
|
|
237
|
+
const relativeShimPath = `./${SHIM_RELATIVE_PATH}`;
|
|
238
|
+
const candidatePaths = resolveCandidatePaths(baseDir);
|
|
239
|
+
const transpilePackages = [.../* @__PURE__ */ new Set([
|
|
240
|
+
...ASHEE_TRANSPILE_PACKAGES,
|
|
241
|
+
...legacyConfig.transpilePackages ?? [],
|
|
242
|
+
...extraTranspilePackages ?? []
|
|
243
|
+
])];
|
|
244
|
+
const userWebpack = nextConfig.webpack;
|
|
245
|
+
const webpack = ((config, context) => {
|
|
246
|
+
const patchConfig = config;
|
|
247
|
+
const patchContext = context;
|
|
248
|
+
const hook = createWebpackHook({
|
|
249
|
+
shimPath: absoluteShimPath,
|
|
250
|
+
candidatePaths,
|
|
251
|
+
root: baseDir,
|
|
252
|
+
regenerate: generateShim
|
|
253
|
+
});
|
|
254
|
+
if (userWebpack) return hook(userWebpack(patchConfig, patchContext), patchContext);
|
|
255
|
+
return hook(patchConfig, patchContext);
|
|
256
|
+
});
|
|
257
|
+
const turbopackResolveAlias = {
|
|
258
|
+
...nextConfig.turbopack?.resolveAlias ?? {},
|
|
259
|
+
[VIRTUAL_ID]: relativeShimPath
|
|
260
|
+
};
|
|
261
|
+
const turbopack = {
|
|
262
|
+
...nextConfig.turbopack,
|
|
263
|
+
resolveAlias: turbopackResolveAlias
|
|
264
|
+
};
|
|
265
|
+
const patchedConfig = {
|
|
266
|
+
...nextConfig,
|
|
267
|
+
transpilePackages,
|
|
268
|
+
webpack,
|
|
269
|
+
turbopack
|
|
270
|
+
};
|
|
271
|
+
if (legacyConfig.experimental?.turbo) {
|
|
272
|
+
const turboPatch = addAsheeConfigResolveAlias(legacyConfig.experimental.turbo, relativeShimPath);
|
|
273
|
+
patchedConfig.experimental = {
|
|
274
|
+
...nextConfig.experimental,
|
|
275
|
+
turbo: turboPatch
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return patchedConfig;
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
exports.SHIM_RELATIVE_PATH = SHIM_RELATIVE_PATH;
|
|
282
|
+
exports.VIRTUAL_ID = VIRTUAL_ID;
|
|
283
|
+
exports.addAsheeConfigAlias = addAsheeConfigAlias;
|
|
284
|
+
exports.addAsheeConfigResolveAlias = addAsheeConfigResolveAlias;
|
|
285
|
+
exports.createBeforeCompilePlugin = createBeforeCompilePlugin;
|
|
286
|
+
exports.createWebpackHook = createWebpackHook;
|
|
287
|
+
exports.generateShim = generateShim;
|
|
288
|
+
exports.resolveCandidatePaths = resolveCandidatePaths;
|
|
289
|
+
exports.resolveShimPath = resolveShimPath;
|
|
290
|
+
exports.withAsheeUI = withAsheeUI;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { NextConfig } from "next";
|
|
2
|
+
//#region src/generate.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The import specifier used across AsheeUI for the config module.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import config from "virtual:ashee-config";
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
declare const VIRTUAL_ID = "virtual:ashee-config";
|
|
12
|
+
/**
|
|
13
|
+
* Location of the generated shim, relative to the project root.
|
|
14
|
+
*
|
|
15
|
+
* Deliberately kept outside `node_modules`: package managers and CI
|
|
16
|
+
* treat `node_modules` as fully disposable, and a shim the dev server
|
|
17
|
+
* depends on should not live somewhere that can vanish out from under
|
|
18
|
+
* it.
|
|
19
|
+
*/
|
|
20
|
+
declare const SHIM_RELATIVE_PATH = ".ashee/generated-config.mjs";
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the absolute path of the generated shim for a project root.
|
|
23
|
+
*
|
|
24
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
25
|
+
* @returns Absolute path of the shim file.
|
|
26
|
+
*/
|
|
27
|
+
declare function resolveShimPath(root?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve every candidate config filename to an absolute path under
|
|
30
|
+
* `root`, whether or not the files currently exist.
|
|
31
|
+
*
|
|
32
|
+
* These paths are registered as webpack "missing dependencies" so that
|
|
33
|
+
* creating a config file for the first time triggers a rebuild.
|
|
34
|
+
*
|
|
35
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
36
|
+
* @returns Absolute paths for every known config filename.
|
|
37
|
+
*/
|
|
38
|
+
declare function resolveCandidatePaths(root?: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Regenerate the config shim, mirroring `@asheeui/vite`'s virtual module:
|
|
41
|
+
* if a config file exists we re-export its default export, otherwise we
|
|
42
|
+
* export `undefined`.
|
|
43
|
+
*
|
|
44
|
+
* The write is skipped when the content is unchanged, so webpack's
|
|
45
|
+
* `beforeCompile` hook does not churn the file (or Turbopack's watcher)
|
|
46
|
+
* on every rebuild.
|
|
47
|
+
*
|
|
48
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
49
|
+
* @returns The absolute path of the regenerated shim file.
|
|
50
|
+
*/
|
|
51
|
+
declare function generateShim(root?: string): string;
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/turbopack.d.ts
|
|
54
|
+
/**
|
|
55
|
+
* The part of Next's Turbopack config that this package patches.
|
|
56
|
+
*
|
|
57
|
+
* Next exposes the same shape both at the stable `turbopack` key
|
|
58
|
+
* (`>= 15.1`) and at the deprecated `experimental.turbo` key, so one
|
|
59
|
+
* structural type covers both merge targets.
|
|
60
|
+
*/
|
|
61
|
+
interface TurbopackPatch {
|
|
62
|
+
/** Alias map used to redirect module specifiers during resolution. */
|
|
63
|
+
resolveAlias?: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Point `virtual:ashee-config` at the generated shim inside a Turbopack
|
|
67
|
+
* config section.
|
|
68
|
+
*
|
|
69
|
+
* The given `target` object is mutated and then returned so the caller
|
|
70
|
+
* can use it in an inline expression.
|
|
71
|
+
*
|
|
72
|
+
* @param target - Turbopack config section (stable or experimental).
|
|
73
|
+
* @param shimPath - Project-root-relative path of the generated shim.
|
|
74
|
+
* @returns The same `target` object, with the alias registered.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const turbopack = addAsheeConfigResolveAlias(
|
|
79
|
+
* { resolveAlias: {} },
|
|
80
|
+
* "./.ashee/generated-config.mjs",
|
|
81
|
+
* );
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
declare function addAsheeConfigResolveAlias(target: TurbopackPatch, shimPath: string): TurbopackPatch;
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/types.d.ts
|
|
87
|
+
/**
|
|
88
|
+
* AsheeUI-specific overrides that can be spread into a `NextConfig`
|
|
89
|
+
* when calling {@link withAsheeUI}.
|
|
90
|
+
*/
|
|
91
|
+
interface AsheeUIConfigOverrides {
|
|
92
|
+
/**
|
|
93
|
+
* Override the directory to look for `asheeui.config.*` in.
|
|
94
|
+
*
|
|
95
|
+
* Defaults to the project root (the directory containing
|
|
96
|
+
* `next.config.*`).
|
|
97
|
+
*/
|
|
98
|
+
root?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Extra packages appended to `transpilePackages`, deduped against the
|
|
101
|
+
* built-in AsheeUI package list.
|
|
102
|
+
*/
|
|
103
|
+
transpilePackages?: string[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The config object accepted by `withAsheeUI`: a standard `NextConfig`
|
|
107
|
+
* merged with AsheeUI overrides.
|
|
108
|
+
*/
|
|
109
|
+
type WithAsheeUIConfig = NextConfig & AsheeUIConfigOverrides;
|
|
110
|
+
/**
|
|
111
|
+
* Structural view of the webpack config sections that AsheeUI patches.
|
|
112
|
+
*
|
|
113
|
+
* Kept deliberately minimal so this package does not need a webpack
|
|
114
|
+
* type dependency.
|
|
115
|
+
*/
|
|
116
|
+
interface WebpackConfigPatch {
|
|
117
|
+
/** Webpack resolution options. */
|
|
118
|
+
resolve?: {
|
|
119
|
+
/** Module alias map. */
|
|
120
|
+
alias?: Record<string, string>;
|
|
121
|
+
};
|
|
122
|
+
/** Webpack plugins to append to. */
|
|
123
|
+
plugins?: WebpackPluginLike[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Structural view of the compilation object passed to webpack's
|
|
127
|
+
* `afterCompile` hook.
|
|
128
|
+
*/
|
|
129
|
+
interface WebpackCompilationLike {
|
|
130
|
+
/** Collector for files webpack should watch even when missing. */
|
|
131
|
+
missingDependencies: {
|
|
132
|
+
add: (path: string) => void;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Minimal structural view of a webpack plugin used by this package.
|
|
137
|
+
*
|
|
138
|
+
* Only the `apply` method and the `beforeCompile`/`afterCompile` hooks
|
|
139
|
+
* are modelled.
|
|
140
|
+
*/
|
|
141
|
+
interface WebpackPluginLike {
|
|
142
|
+
/** Install the plugin onto the compiler. */
|
|
143
|
+
apply: (compiler: {
|
|
144
|
+
hooks: {
|
|
145
|
+
/** Fired before each compilation begins. */
|
|
146
|
+
beforeCompile: {
|
|
147
|
+
tap: (name: string, callback: () => void) => void;
|
|
148
|
+
};
|
|
149
|
+
/** Fired after each compilation finishes. */
|
|
150
|
+
afterCompile: {
|
|
151
|
+
tap: (name: string, callback: (compilation: WebpackCompilationLike) => void) => void;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
}) => void;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Minimal structural view of the webpack context object passed to the
|
|
158
|
+
* `webpack` config function by Next.
|
|
159
|
+
*/
|
|
160
|
+
interface WebpackContextLike {
|
|
161
|
+
/** `true` when Next is running a development build. */
|
|
162
|
+
dev: boolean;
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/webpack.d.ts
|
|
166
|
+
/**
|
|
167
|
+
* Point `virtual:ashee-config` at the generated shim so app code keeps
|
|
168
|
+
* using the same import specifier as Vite.
|
|
169
|
+
*
|
|
170
|
+
* @param config - Webpack config section to patch (mutated in place).
|
|
171
|
+
* @param shimPath - Absolute path of the generated shim.
|
|
172
|
+
* @returns The same `config` object, with the alias registered.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* const config = addAsheeConfigAlias(
|
|
177
|
+
* { resolve: { alias: {} } },
|
|
178
|
+
* "/proj/.ashee/generated-config.mjs",
|
|
179
|
+
* );
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
declare function addAsheeConfigAlias(config: WebpackConfigPatch, shimPath: string): WebpackConfigPatch;
|
|
183
|
+
/**
|
|
184
|
+
* Create a dev-only webpack plugin that regenerates the shim before
|
|
185
|
+
* every compile so edits to an existing config file are always picked
|
|
186
|
+
* up.
|
|
187
|
+
*
|
|
188
|
+
* The plugin also registers every candidate filename as a webpack
|
|
189
|
+
* "missing dependency": the shim has no reference to a file that does
|
|
190
|
+
* not exist yet, so without this, *creating* the config file for the
|
|
191
|
+
* first time would never trigger a rebuild on its own. Writes are
|
|
192
|
+
* skipped when content is unchanged, keeping rebuilds cheap.
|
|
193
|
+
*
|
|
194
|
+
* @param regenerate - Callback that rewrites the shim file.
|
|
195
|
+
* @param candidatePaths - Absolute candidate config paths to watch as
|
|
196
|
+
* missing dependencies.
|
|
197
|
+
* @returns A webpack plugin object.
|
|
198
|
+
*/
|
|
199
|
+
declare function createBeforeCompilePlugin(regenerate: () => void, candidatePaths: string[]): WebpackPluginLike;
|
|
200
|
+
/**
|
|
201
|
+
* Create the webpack hook that Next invokes when building.
|
|
202
|
+
*
|
|
203
|
+
* The returned hook always adds the config alias; in dev mode it also
|
|
204
|
+
* installs the `beforeCompile` regeneration plugin and the
|
|
205
|
+
* missing-dependency watcher.
|
|
206
|
+
*
|
|
207
|
+
* @param options - Hook options.
|
|
208
|
+
* @param options.shimPath - Absolute path of the generated shim.
|
|
209
|
+
* @param options.candidatePaths - Absolute candidate config paths.
|
|
210
|
+
* @param options.root - Project root used when regenerating the shim.
|
|
211
|
+
* @param options.regenerate - Function that regenerates the shim for a
|
|
212
|
+
* given root directory.
|
|
213
|
+
* @returns A webpack config hook matching Next's `webpack` signature.
|
|
214
|
+
*/
|
|
215
|
+
declare function createWebpackHook(options: {
|
|
216
|
+
shimPath: string;
|
|
217
|
+
candidatePaths: string[];
|
|
218
|
+
root?: string;
|
|
219
|
+
regenerate: (root?: string) => string;
|
|
220
|
+
}): (config: WebpackConfigPatch, context: WebpackContextLike) => WebpackConfigPatch;
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/with-ashee-ui.d.ts
|
|
223
|
+
/**
|
|
224
|
+
* Wrap a `next.config.mjs`/`next.config.ts` object with AsheeUI
|
|
225
|
+
* integration.
|
|
226
|
+
*
|
|
227
|
+
* The wrapper:
|
|
228
|
+
* 1. Generates a config shim at `.ashee/generated-config.mjs` (same
|
|
229
|
+
* resolution as `@asheeui/vite`'s `virtual:ashee-config`).
|
|
230
|
+
* 2. Adds a `virtual:ashee-config` alias for Webpack and Turbopack so
|
|
231
|
+
* app code uses the identical import specifier in both bundlers.
|
|
232
|
+
* Webpack gets an absolute path (it resolves against its own
|
|
233
|
+
* context, not the `root` override), Turbopack gets a
|
|
234
|
+
* project-root-relative one (it rejects absolute targets).
|
|
235
|
+
* 3. Merges `transpilePackages` so AsheeUI's source-shipping packages
|
|
236
|
+
* are compiled by Next.
|
|
237
|
+
*
|
|
238
|
+
* @param config - Next config to wrap. AsheeUI override keys (`root`,
|
|
239
|
+
* `transpilePackages`) are consumed and stripped from the returned
|
|
240
|
+
* `NextConfig`. Defaults to `{}`.
|
|
241
|
+
* @returns A plain `NextConfig` with the AsheeUI integration applied.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* // next.config.ts
|
|
246
|
+
* import { withAsheeUI } from "@asheeui/next";
|
|
247
|
+
*
|
|
248
|
+
* export default withAsheeUI({
|
|
249
|
+
* transpilePackages: ["@my-org/ui"],
|
|
250
|
+
* });
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function withAsheeUI(config?: WithAsheeUIConfig): NextConfig;
|
|
254
|
+
//#endregion
|
|
255
|
+
export { AsheeUIConfigOverrides, SHIM_RELATIVE_PATH, TurbopackPatch, VIRTUAL_ID, WebpackCompilationLike, WebpackConfigPatch, WebpackContextLike, WebpackPluginLike, WithAsheeUIConfig, addAsheeConfigAlias, addAsheeConfigResolveAlias, createBeforeCompilePlugin, createWebpackHook, generateShim, resolveCandidatePaths, resolveShimPath, withAsheeUI };
|
|
256
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/generate.ts","../src/turbopack.ts","../src/types.ts","../src/webpack.ts","../src/with-ashee-ui.ts"],"mappings":";;;;;;;;;;cAYa;;;;;;;;;cAUA;;;;;;;iBAQG,gBAAgB;;;;;;;;;;;iBAchB,sBAAsB;;;;;;;;;;;;;iBAgCtB,aAAa;;;;;;;;;;UCnEZ;;EAEf,eAAe;;;;;;;;;;;;;;;;;;;;;iBAsBD,2BACd,QAAQ,gBACR,mBACC;;;;;;;UC9Bc;;;;;;;EAOf;;;;;EAKA;;;;;;KAOU,oBAAoB,aAAa;;;;;;;UAQ5B;;EAEf;;IAEE,QAAQ;;;EAGV,UAAU;;;;;;UAOK;;EAEf;IAAuB,MAAM;;;;;;;;;UASd;;EAEf,QAAQ;IACN;;MAEE;QACE,MAAM,cAAc;;;MAGtB;QACE,MACE,cACA,WAAW,aAAa;;;;;;;;;UAWjB;;EAEf;;;;;;;;;;;;;;;;;;;;iBCrDc,oBACd,QAAQ,oBACR,mBACC;;;;;;;;;;;;;;;;;iBAuBa,0BACd,wBACA,2BACC;;;;;;;;;;;;;;;;iBA8Ba,kBAAkB;EAChC;EACA;EACA;EACA,aAAa;KAEb,QAAQ,oBACR,SAAS,uBACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCxBW,YAAY,SAAQ,oBAAyB"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { NextConfig } from "next";
|
|
2
|
+
//#region src/generate.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The import specifier used across AsheeUI for the config module.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import config from "virtual:ashee-config";
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
declare const VIRTUAL_ID = "virtual:ashee-config";
|
|
12
|
+
/**
|
|
13
|
+
* Location of the generated shim, relative to the project root.
|
|
14
|
+
*
|
|
15
|
+
* Deliberately kept outside `node_modules`: package managers and CI
|
|
16
|
+
* treat `node_modules` as fully disposable, and a shim the dev server
|
|
17
|
+
* depends on should not live somewhere that can vanish out from under
|
|
18
|
+
* it.
|
|
19
|
+
*/
|
|
20
|
+
declare const SHIM_RELATIVE_PATH = ".ashee/generated-config.mjs";
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the absolute path of the generated shim for a project root.
|
|
23
|
+
*
|
|
24
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
25
|
+
* @returns Absolute path of the shim file.
|
|
26
|
+
*/
|
|
27
|
+
declare function resolveShimPath(root?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve every candidate config filename to an absolute path under
|
|
30
|
+
* `root`, whether or not the files currently exist.
|
|
31
|
+
*
|
|
32
|
+
* These paths are registered as webpack "missing dependencies" so that
|
|
33
|
+
* creating a config file for the first time triggers a rebuild.
|
|
34
|
+
*
|
|
35
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
36
|
+
* @returns Absolute paths for every known config filename.
|
|
37
|
+
*/
|
|
38
|
+
declare function resolveCandidatePaths(root?: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Regenerate the config shim, mirroring `@asheeui/vite`'s virtual module:
|
|
41
|
+
* if a config file exists we re-export its default export, otherwise we
|
|
42
|
+
* export `undefined`.
|
|
43
|
+
*
|
|
44
|
+
* The write is skipped when the content is unchanged, so webpack's
|
|
45
|
+
* `beforeCompile` hook does not churn the file (or Turbopack's watcher)
|
|
46
|
+
* on every rebuild.
|
|
47
|
+
*
|
|
48
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
49
|
+
* @returns The absolute path of the regenerated shim file.
|
|
50
|
+
*/
|
|
51
|
+
declare function generateShim(root?: string): string;
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/turbopack.d.ts
|
|
54
|
+
/**
|
|
55
|
+
* The part of Next's Turbopack config that this package patches.
|
|
56
|
+
*
|
|
57
|
+
* Next exposes the same shape both at the stable `turbopack` key
|
|
58
|
+
* (`>= 15.1`) and at the deprecated `experimental.turbo` key, so one
|
|
59
|
+
* structural type covers both merge targets.
|
|
60
|
+
*/
|
|
61
|
+
interface TurbopackPatch {
|
|
62
|
+
/** Alias map used to redirect module specifiers during resolution. */
|
|
63
|
+
resolveAlias?: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Point `virtual:ashee-config` at the generated shim inside a Turbopack
|
|
67
|
+
* config section.
|
|
68
|
+
*
|
|
69
|
+
* The given `target` object is mutated and then returned so the caller
|
|
70
|
+
* can use it in an inline expression.
|
|
71
|
+
*
|
|
72
|
+
* @param target - Turbopack config section (stable or experimental).
|
|
73
|
+
* @param shimPath - Project-root-relative path of the generated shim.
|
|
74
|
+
* @returns The same `target` object, with the alias registered.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const turbopack = addAsheeConfigResolveAlias(
|
|
79
|
+
* { resolveAlias: {} },
|
|
80
|
+
* "./.ashee/generated-config.mjs",
|
|
81
|
+
* );
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
declare function addAsheeConfigResolveAlias(target: TurbopackPatch, shimPath: string): TurbopackPatch;
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/types.d.ts
|
|
87
|
+
/**
|
|
88
|
+
* AsheeUI-specific overrides that can be spread into a `NextConfig`
|
|
89
|
+
* when calling {@link withAsheeUI}.
|
|
90
|
+
*/
|
|
91
|
+
interface AsheeUIConfigOverrides {
|
|
92
|
+
/**
|
|
93
|
+
* Override the directory to look for `asheeui.config.*` in.
|
|
94
|
+
*
|
|
95
|
+
* Defaults to the project root (the directory containing
|
|
96
|
+
* `next.config.*`).
|
|
97
|
+
*/
|
|
98
|
+
root?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Extra packages appended to `transpilePackages`, deduped against the
|
|
101
|
+
* built-in AsheeUI package list.
|
|
102
|
+
*/
|
|
103
|
+
transpilePackages?: string[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The config object accepted by `withAsheeUI`: a standard `NextConfig`
|
|
107
|
+
* merged with AsheeUI overrides.
|
|
108
|
+
*/
|
|
109
|
+
type WithAsheeUIConfig = NextConfig & AsheeUIConfigOverrides;
|
|
110
|
+
/**
|
|
111
|
+
* Structural view of the webpack config sections that AsheeUI patches.
|
|
112
|
+
*
|
|
113
|
+
* Kept deliberately minimal so this package does not need a webpack
|
|
114
|
+
* type dependency.
|
|
115
|
+
*/
|
|
116
|
+
interface WebpackConfigPatch {
|
|
117
|
+
/** Webpack resolution options. */
|
|
118
|
+
resolve?: {
|
|
119
|
+
/** Module alias map. */
|
|
120
|
+
alias?: Record<string, string>;
|
|
121
|
+
};
|
|
122
|
+
/** Webpack plugins to append to. */
|
|
123
|
+
plugins?: WebpackPluginLike[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Structural view of the compilation object passed to webpack's
|
|
127
|
+
* `afterCompile` hook.
|
|
128
|
+
*/
|
|
129
|
+
interface WebpackCompilationLike {
|
|
130
|
+
/** Collector for files webpack should watch even when missing. */
|
|
131
|
+
missingDependencies: {
|
|
132
|
+
add: (path: string) => void;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Minimal structural view of a webpack plugin used by this package.
|
|
137
|
+
*
|
|
138
|
+
* Only the `apply` method and the `beforeCompile`/`afterCompile` hooks
|
|
139
|
+
* are modelled.
|
|
140
|
+
*/
|
|
141
|
+
interface WebpackPluginLike {
|
|
142
|
+
/** Install the plugin onto the compiler. */
|
|
143
|
+
apply: (compiler: {
|
|
144
|
+
hooks: {
|
|
145
|
+
/** Fired before each compilation begins. */
|
|
146
|
+
beforeCompile: {
|
|
147
|
+
tap: (name: string, callback: () => void) => void;
|
|
148
|
+
};
|
|
149
|
+
/** Fired after each compilation finishes. */
|
|
150
|
+
afterCompile: {
|
|
151
|
+
tap: (name: string, callback: (compilation: WebpackCompilationLike) => void) => void;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
}) => void;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Minimal structural view of the webpack context object passed to the
|
|
158
|
+
* `webpack` config function by Next.
|
|
159
|
+
*/
|
|
160
|
+
interface WebpackContextLike {
|
|
161
|
+
/** `true` when Next is running a development build. */
|
|
162
|
+
dev: boolean;
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/webpack.d.ts
|
|
166
|
+
/**
|
|
167
|
+
* Point `virtual:ashee-config` at the generated shim so app code keeps
|
|
168
|
+
* using the same import specifier as Vite.
|
|
169
|
+
*
|
|
170
|
+
* @param config - Webpack config section to patch (mutated in place).
|
|
171
|
+
* @param shimPath - Absolute path of the generated shim.
|
|
172
|
+
* @returns The same `config` object, with the alias registered.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* const config = addAsheeConfigAlias(
|
|
177
|
+
* { resolve: { alias: {} } },
|
|
178
|
+
* "/proj/.ashee/generated-config.mjs",
|
|
179
|
+
* );
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
declare function addAsheeConfigAlias(config: WebpackConfigPatch, shimPath: string): WebpackConfigPatch;
|
|
183
|
+
/**
|
|
184
|
+
* Create a dev-only webpack plugin that regenerates the shim before
|
|
185
|
+
* every compile so edits to an existing config file are always picked
|
|
186
|
+
* up.
|
|
187
|
+
*
|
|
188
|
+
* The plugin also registers every candidate filename as a webpack
|
|
189
|
+
* "missing dependency": the shim has no reference to a file that does
|
|
190
|
+
* not exist yet, so without this, *creating* the config file for the
|
|
191
|
+
* first time would never trigger a rebuild on its own. Writes are
|
|
192
|
+
* skipped when content is unchanged, keeping rebuilds cheap.
|
|
193
|
+
*
|
|
194
|
+
* @param regenerate - Callback that rewrites the shim file.
|
|
195
|
+
* @param candidatePaths - Absolute candidate config paths to watch as
|
|
196
|
+
* missing dependencies.
|
|
197
|
+
* @returns A webpack plugin object.
|
|
198
|
+
*/
|
|
199
|
+
declare function createBeforeCompilePlugin(regenerate: () => void, candidatePaths: string[]): WebpackPluginLike;
|
|
200
|
+
/**
|
|
201
|
+
* Create the webpack hook that Next invokes when building.
|
|
202
|
+
*
|
|
203
|
+
* The returned hook always adds the config alias; in dev mode it also
|
|
204
|
+
* installs the `beforeCompile` regeneration plugin and the
|
|
205
|
+
* missing-dependency watcher.
|
|
206
|
+
*
|
|
207
|
+
* @param options - Hook options.
|
|
208
|
+
* @param options.shimPath - Absolute path of the generated shim.
|
|
209
|
+
* @param options.candidatePaths - Absolute candidate config paths.
|
|
210
|
+
* @param options.root - Project root used when regenerating the shim.
|
|
211
|
+
* @param options.regenerate - Function that regenerates the shim for a
|
|
212
|
+
* given root directory.
|
|
213
|
+
* @returns A webpack config hook matching Next's `webpack` signature.
|
|
214
|
+
*/
|
|
215
|
+
declare function createWebpackHook(options: {
|
|
216
|
+
shimPath: string;
|
|
217
|
+
candidatePaths: string[];
|
|
218
|
+
root?: string;
|
|
219
|
+
regenerate: (root?: string) => string;
|
|
220
|
+
}): (config: WebpackConfigPatch, context: WebpackContextLike) => WebpackConfigPatch;
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/with-ashee-ui.d.ts
|
|
223
|
+
/**
|
|
224
|
+
* Wrap a `next.config.mjs`/`next.config.ts` object with AsheeUI
|
|
225
|
+
* integration.
|
|
226
|
+
*
|
|
227
|
+
* The wrapper:
|
|
228
|
+
* 1. Generates a config shim at `.ashee/generated-config.mjs` (same
|
|
229
|
+
* resolution as `@asheeui/vite`'s `virtual:ashee-config`).
|
|
230
|
+
* 2. Adds a `virtual:ashee-config` alias for Webpack and Turbopack so
|
|
231
|
+
* app code uses the identical import specifier in both bundlers.
|
|
232
|
+
* Webpack gets an absolute path (it resolves against its own
|
|
233
|
+
* context, not the `root` override), Turbopack gets a
|
|
234
|
+
* project-root-relative one (it rejects absolute targets).
|
|
235
|
+
* 3. Merges `transpilePackages` so AsheeUI's source-shipping packages
|
|
236
|
+
* are compiled by Next.
|
|
237
|
+
*
|
|
238
|
+
* @param config - Next config to wrap. AsheeUI override keys (`root`,
|
|
239
|
+
* `transpilePackages`) are consumed and stripped from the returned
|
|
240
|
+
* `NextConfig`. Defaults to `{}`.
|
|
241
|
+
* @returns A plain `NextConfig` with the AsheeUI integration applied.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* // next.config.ts
|
|
246
|
+
* import { withAsheeUI } from "@asheeui/next";
|
|
247
|
+
*
|
|
248
|
+
* export default withAsheeUI({
|
|
249
|
+
* transpilePackages: ["@my-org/ui"],
|
|
250
|
+
* });
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function withAsheeUI(config?: WithAsheeUIConfig): NextConfig;
|
|
254
|
+
//#endregion
|
|
255
|
+
export { AsheeUIConfigOverrides, SHIM_RELATIVE_PATH, TurbopackPatch, VIRTUAL_ID, WebpackCompilationLike, WebpackConfigPatch, WebpackContextLike, WebpackPluginLike, WithAsheeUIConfig, addAsheeConfigAlias, addAsheeConfigResolveAlias, createBeforeCompilePlugin, createWebpackHook, generateShim, resolveCandidatePaths, resolveShimPath, withAsheeUI };
|
|
256
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/generate.ts","../src/turbopack.ts","../src/types.ts","../src/webpack.ts","../src/with-ashee-ui.ts"],"mappings":";;;;;;;;;;cAYa;;;;;;;;;cAUA;;;;;;;iBAQG,gBAAgB;;;;;;;;;;;iBAchB,sBAAsB;;;;;;;;;;;;;iBAgCtB,aAAa;;;;;;;;;;UCnEZ;;EAEf,eAAe;;;;;;;;;;;;;;;;;;;;;iBAsBD,2BACd,QAAQ,gBACR,mBACC;;;;;;;UC9Bc;;;;;;;EAOf;;;;;EAKA;;;;;;KAOU,oBAAoB,aAAa;;;;;;;UAQ5B;;EAEf;;IAEE,QAAQ;;;EAGV,UAAU;;;;;;UAOK;;EAEf;IAAuB,MAAM;;;;;;;;;UASd;;EAEf,QAAQ;IACN;;MAEE;QACE,MAAM,cAAc;;;MAGtB;QACE,MACE,cACA,WAAW,aAAa;;;;;;;;;UAWjB;;EAEf;;;;;;;;;;;;;;;;;;;;iBCrDc,oBACd,QAAQ,oBACR,mBACC;;;;;;;;;;;;;;;;;iBAuBa,0BACd,wBACA,2BACC;;;;;;;;;;;;;;;;iBA8Ba,kBAAkB;EAChC;EACA;EACA;EACA,aAAa;KAEb,QAAQ,oBACR,SAAS,uBACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCxBW,YAAY,SAAQ,oBAAyB"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, relative, resolve } from "node:path";
|
|
3
|
+
import { CANDIDATES, discoverConfig } from "@asheeui/utils/node";
|
|
4
|
+
//#region src/generate.ts
|
|
5
|
+
/**
|
|
6
|
+
* The import specifier used across AsheeUI for the config module.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import config from "virtual:ashee-config";
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
const VIRTUAL_ID = "virtual:ashee-config";
|
|
14
|
+
/**
|
|
15
|
+
* Location of the generated shim, relative to the project root.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately kept outside `node_modules`: package managers and CI
|
|
18
|
+
* treat `node_modules` as fully disposable, and a shim the dev server
|
|
19
|
+
* depends on should not live somewhere that can vanish out from under
|
|
20
|
+
* it.
|
|
21
|
+
*/
|
|
22
|
+
const SHIM_RELATIVE_PATH = ".ashee/generated-config.mjs";
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the absolute path of the generated shim for a project root.
|
|
25
|
+
*
|
|
26
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
27
|
+
* @returns Absolute path of the shim file.
|
|
28
|
+
*/
|
|
29
|
+
function resolveShimPath(root) {
|
|
30
|
+
return resolve(root ?? process.cwd(), SHIM_RELATIVE_PATH);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolve every candidate config filename to an absolute path under
|
|
34
|
+
* `root`, whether or not the files currently exist.
|
|
35
|
+
*
|
|
36
|
+
* These paths are registered as webpack "missing dependencies" so that
|
|
37
|
+
* creating a config file for the first time triggers a rebuild.
|
|
38
|
+
*
|
|
39
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
40
|
+
* @returns Absolute paths for every known config filename.
|
|
41
|
+
*/
|
|
42
|
+
function resolveCandidatePaths(root) {
|
|
43
|
+
const base = root ?? process.cwd();
|
|
44
|
+
return CANDIDATES.map((file) => resolve(base, file));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build an import specifier for `toFile` relative to `fromFile`'s directory.
|
|
48
|
+
*
|
|
49
|
+
* Turbopack rejects absolute ("server-relative") import specifiers, so the
|
|
50
|
+
* shim must reference the discovered config with a path relative to itself.
|
|
51
|
+
*
|
|
52
|
+
* @param fromFile - Absolute path of the importing file.
|
|
53
|
+
* @param toFile - Absolute path of the imported file.
|
|
54
|
+
* @returns A `./`-prefixed relative specifier.
|
|
55
|
+
*/
|
|
56
|
+
function toRelativeSpecifier(fromFile, toFile) {
|
|
57
|
+
const rel = relative(dirname(fromFile), toFile).replaceAll("\\", "/");
|
|
58
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Regenerate the config shim, mirroring `@asheeui/vite`'s virtual module:
|
|
62
|
+
* if a config file exists we re-export its default export, otherwise we
|
|
63
|
+
* export `undefined`.
|
|
64
|
+
*
|
|
65
|
+
* The write is skipped when the content is unchanged, so webpack's
|
|
66
|
+
* `beforeCompile` hook does not churn the file (or Turbopack's watcher)
|
|
67
|
+
* on every rebuild.
|
|
68
|
+
*
|
|
69
|
+
* @param root - Project root directory. Defaults to `process.cwd()`.
|
|
70
|
+
* @returns The absolute path of the regenerated shim file.
|
|
71
|
+
*/
|
|
72
|
+
function generateShim(root) {
|
|
73
|
+
const shimPath = resolveShimPath(root);
|
|
74
|
+
const configPath = discoverConfig(root);
|
|
75
|
+
const content = configPath ? `export { default } from ${JSON.stringify(toRelativeSpecifier(shimPath, configPath))};\n` : "export default undefined;\n";
|
|
76
|
+
if (!existsSync(shimPath) || readFileSync(shimPath, "utf8") !== content) {
|
|
77
|
+
mkdirSync(dirname(shimPath), { recursive: true });
|
|
78
|
+
writeFileSync(shimPath, content, "utf8");
|
|
79
|
+
}
|
|
80
|
+
return shimPath;
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/turbopack.ts
|
|
84
|
+
/**
|
|
85
|
+
* Point `virtual:ashee-config` at the generated shim inside a Turbopack
|
|
86
|
+
* config section.
|
|
87
|
+
*
|
|
88
|
+
* The given `target` object is mutated and then returned so the caller
|
|
89
|
+
* can use it in an inline expression.
|
|
90
|
+
*
|
|
91
|
+
* @param target - Turbopack config section (stable or experimental).
|
|
92
|
+
* @param shimPath - Project-root-relative path of the generated shim.
|
|
93
|
+
* @returns The same `target` object, with the alias registered.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const turbopack = addAsheeConfigResolveAlias(
|
|
98
|
+
* { resolveAlias: {} },
|
|
99
|
+
* "./.ashee/generated-config.mjs",
|
|
100
|
+
* );
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
function addAsheeConfigResolveAlias(target, shimPath) {
|
|
104
|
+
target.resolveAlias ??= {};
|
|
105
|
+
target.resolveAlias[VIRTUAL_ID] = shimPath;
|
|
106
|
+
return target;
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/webpack.ts
|
|
110
|
+
/**
|
|
111
|
+
* Exact-match alias key (`$`-suffixed) so a hypothetical future
|
|
112
|
+
* `virtual:ashee-config/foo` import does not also resolve through this
|
|
113
|
+
* alias.
|
|
114
|
+
*/
|
|
115
|
+
const EXACT_VIRTUAL_ID = `${VIRTUAL_ID}$`;
|
|
116
|
+
/**
|
|
117
|
+
* Point `virtual:ashee-config` at the generated shim so app code keeps
|
|
118
|
+
* using the same import specifier as Vite.
|
|
119
|
+
*
|
|
120
|
+
* @param config - Webpack config section to patch (mutated in place).
|
|
121
|
+
* @param shimPath - Absolute path of the generated shim.
|
|
122
|
+
* @returns The same `config` object, with the alias registered.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const config = addAsheeConfigAlias(
|
|
127
|
+
* { resolve: { alias: {} } },
|
|
128
|
+
* "/proj/.ashee/generated-config.mjs",
|
|
129
|
+
* );
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
function addAsheeConfigAlias(config, shimPath) {
|
|
133
|
+
config.resolve ??= {};
|
|
134
|
+
config.resolve.alias ??= {};
|
|
135
|
+
config.resolve.alias[EXACT_VIRTUAL_ID] = shimPath;
|
|
136
|
+
return config;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Create a dev-only webpack plugin that regenerates the shim before
|
|
140
|
+
* every compile so edits to an existing config file are always picked
|
|
141
|
+
* up.
|
|
142
|
+
*
|
|
143
|
+
* The plugin also registers every candidate filename as a webpack
|
|
144
|
+
* "missing dependency": the shim has no reference to a file that does
|
|
145
|
+
* not exist yet, so without this, *creating* the config file for the
|
|
146
|
+
* first time would never trigger a rebuild on its own. Writes are
|
|
147
|
+
* skipped when content is unchanged, keeping rebuilds cheap.
|
|
148
|
+
*
|
|
149
|
+
* @param regenerate - Callback that rewrites the shim file.
|
|
150
|
+
* @param candidatePaths - Absolute candidate config paths to watch as
|
|
151
|
+
* missing dependencies.
|
|
152
|
+
* @returns A webpack plugin object.
|
|
153
|
+
*/
|
|
154
|
+
function createBeforeCompilePlugin(regenerate, candidatePaths) {
|
|
155
|
+
return { apply(compiler) {
|
|
156
|
+
compiler.hooks.beforeCompile.tap("ashee:virtual-config", () => {
|
|
157
|
+
regenerate();
|
|
158
|
+
});
|
|
159
|
+
compiler.hooks.afterCompile.tap("ashee:virtual-config", (compilation) => {
|
|
160
|
+
for (const path of candidatePaths) compilation.missingDependencies.add(path);
|
|
161
|
+
});
|
|
162
|
+
} };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Create the webpack hook that Next invokes when building.
|
|
166
|
+
*
|
|
167
|
+
* The returned hook always adds the config alias; in dev mode it also
|
|
168
|
+
* installs the `beforeCompile` regeneration plugin and the
|
|
169
|
+
* missing-dependency watcher.
|
|
170
|
+
*
|
|
171
|
+
* @param options - Hook options.
|
|
172
|
+
* @param options.shimPath - Absolute path of the generated shim.
|
|
173
|
+
* @param options.candidatePaths - Absolute candidate config paths.
|
|
174
|
+
* @param options.root - Project root used when regenerating the shim.
|
|
175
|
+
* @param options.regenerate - Function that regenerates the shim for a
|
|
176
|
+
* given root directory.
|
|
177
|
+
* @returns A webpack config hook matching Next's `webpack` signature.
|
|
178
|
+
*/
|
|
179
|
+
function createWebpackHook(options) {
|
|
180
|
+
const { shimPath, candidatePaths, regenerate, root } = options;
|
|
181
|
+
return (config, context) => {
|
|
182
|
+
addAsheeConfigAlias(config, shimPath);
|
|
183
|
+
if (context.dev) {
|
|
184
|
+
config.plugins ??= [];
|
|
185
|
+
config.plugins.push(createBeforeCompilePlugin(() => regenerate(root), candidatePaths));
|
|
186
|
+
}
|
|
187
|
+
return config;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/with-ashee-ui.ts
|
|
192
|
+
/**
|
|
193
|
+
* AsheeUI packages that ship TypeScript source and must be compiled by
|
|
194
|
+
* Next.
|
|
195
|
+
*
|
|
196
|
+
* `transpilePackages` takes npm package names, deduped against any the
|
|
197
|
+
* consumer provides.
|
|
198
|
+
*/
|
|
199
|
+
const ASHEE_TRANSPILE_PACKAGES = ["asheeui"];
|
|
200
|
+
/**
|
|
201
|
+
* Wrap a `next.config.mjs`/`next.config.ts` object with AsheeUI
|
|
202
|
+
* integration.
|
|
203
|
+
*
|
|
204
|
+
* The wrapper:
|
|
205
|
+
* 1. Generates a config shim at `.ashee/generated-config.mjs` (same
|
|
206
|
+
* resolution as `@asheeui/vite`'s `virtual:ashee-config`).
|
|
207
|
+
* 2. Adds a `virtual:ashee-config` alias for Webpack and Turbopack so
|
|
208
|
+
* app code uses the identical import specifier in both bundlers.
|
|
209
|
+
* Webpack gets an absolute path (it resolves against its own
|
|
210
|
+
* context, not the `root` override), Turbopack gets a
|
|
211
|
+
* project-root-relative one (it rejects absolute targets).
|
|
212
|
+
* 3. Merges `transpilePackages` so AsheeUI's source-shipping packages
|
|
213
|
+
* are compiled by Next.
|
|
214
|
+
*
|
|
215
|
+
* @param config - Next config to wrap. AsheeUI override keys (`root`,
|
|
216
|
+
* `transpilePackages`) are consumed and stripped from the returned
|
|
217
|
+
* `NextConfig`. Defaults to `{}`.
|
|
218
|
+
* @returns A plain `NextConfig` with the AsheeUI integration applied.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* // next.config.ts
|
|
223
|
+
* import { withAsheeUI } from "@asheeui/next";
|
|
224
|
+
*
|
|
225
|
+
* export default withAsheeUI({
|
|
226
|
+
* transpilePackages: ["@my-org/ui"],
|
|
227
|
+
* });
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
function withAsheeUI(config = {}) {
|
|
231
|
+
const { root, transpilePackages: extraTranspilePackages, ...nextConfig } = config;
|
|
232
|
+
const baseDir = root ?? process.cwd();
|
|
233
|
+
const legacyConfig = nextConfig;
|
|
234
|
+
generateShim(baseDir);
|
|
235
|
+
const absoluteShimPath = resolveShimPath(baseDir);
|
|
236
|
+
const relativeShimPath = `./${SHIM_RELATIVE_PATH}`;
|
|
237
|
+
const candidatePaths = resolveCandidatePaths(baseDir);
|
|
238
|
+
const transpilePackages = [.../* @__PURE__ */ new Set([
|
|
239
|
+
...ASHEE_TRANSPILE_PACKAGES,
|
|
240
|
+
...legacyConfig.transpilePackages ?? [],
|
|
241
|
+
...extraTranspilePackages ?? []
|
|
242
|
+
])];
|
|
243
|
+
const userWebpack = nextConfig.webpack;
|
|
244
|
+
const webpack = ((config, context) => {
|
|
245
|
+
const patchConfig = config;
|
|
246
|
+
const patchContext = context;
|
|
247
|
+
const hook = createWebpackHook({
|
|
248
|
+
shimPath: absoluteShimPath,
|
|
249
|
+
candidatePaths,
|
|
250
|
+
root: baseDir,
|
|
251
|
+
regenerate: generateShim
|
|
252
|
+
});
|
|
253
|
+
if (userWebpack) return hook(userWebpack(patchConfig, patchContext), patchContext);
|
|
254
|
+
return hook(patchConfig, patchContext);
|
|
255
|
+
});
|
|
256
|
+
const turbopackResolveAlias = {
|
|
257
|
+
...nextConfig.turbopack?.resolveAlias ?? {},
|
|
258
|
+
[VIRTUAL_ID]: relativeShimPath
|
|
259
|
+
};
|
|
260
|
+
const turbopack = {
|
|
261
|
+
...nextConfig.turbopack,
|
|
262
|
+
resolveAlias: turbopackResolveAlias
|
|
263
|
+
};
|
|
264
|
+
const patchedConfig = {
|
|
265
|
+
...nextConfig,
|
|
266
|
+
transpilePackages,
|
|
267
|
+
webpack,
|
|
268
|
+
turbopack
|
|
269
|
+
};
|
|
270
|
+
if (legacyConfig.experimental?.turbo) {
|
|
271
|
+
const turboPatch = addAsheeConfigResolveAlias(legacyConfig.experimental.turbo, relativeShimPath);
|
|
272
|
+
patchedConfig.experimental = {
|
|
273
|
+
...nextConfig.experimental,
|
|
274
|
+
turbo: turboPatch
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
return patchedConfig;
|
|
278
|
+
}
|
|
279
|
+
//#endregion
|
|
280
|
+
export { SHIM_RELATIVE_PATH, VIRTUAL_ID, addAsheeConfigAlias, addAsheeConfigResolveAlias, createBeforeCompilePlugin, createWebpackHook, generateShim, resolveCandidatePaths, resolveShimPath, withAsheeUI };
|
|
281
|
+
|
|
282
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/generate.ts","../src/turbopack.ts","../src/webpack.ts","../src/with-ashee-ui.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, relative, resolve } from \"node:path\";\nimport { CANDIDATES, discoverConfig } from \"@asheeui/utils/node\";\n\n/**\n * The import specifier used across AsheeUI for the config module.\n *\n * @example\n * ```ts\n * import config from \"virtual:ashee-config\";\n * ```\n */\nexport const VIRTUAL_ID = \"virtual:ashee-config\";\n\n/**\n * Location of the generated shim, relative to the project root.\n *\n * Deliberately kept outside `node_modules`: package managers and CI\n * treat `node_modules` as fully disposable, and a shim the dev server\n * depends on should not live somewhere that can vanish out from under\n * it.\n */\nexport const SHIM_RELATIVE_PATH = \".ashee/generated-config.mjs\";\n\n/**\n * Resolve the absolute path of the generated shim for a project root.\n *\n * @param root - Project root directory. Defaults to `process.cwd()`.\n * @returns Absolute path of the shim file.\n */\nexport function resolveShimPath(root?: string): string {\n return resolve(root ?? process.cwd(), SHIM_RELATIVE_PATH);\n}\n\n/**\n * Resolve every candidate config filename to an absolute path under\n * `root`, whether or not the files currently exist.\n *\n * These paths are registered as webpack \"missing dependencies\" so that\n * creating a config file for the first time triggers a rebuild.\n *\n * @param root - Project root directory. Defaults to `process.cwd()`.\n * @returns Absolute paths for every known config filename.\n */\nexport function resolveCandidatePaths(root?: string): string[] {\n const base = root ?? process.cwd();\n return CANDIDATES.map((file) => resolve(base, file));\n}\n\n/**\n * Build an import specifier for `toFile` relative to `fromFile`'s directory.\n *\n * Turbopack rejects absolute (\"server-relative\") import specifiers, so the\n * shim must reference the discovered config with a path relative to itself.\n *\n * @param fromFile - Absolute path of the importing file.\n * @param toFile - Absolute path of the imported file.\n * @returns A `./`-prefixed relative specifier.\n */\nfunction toRelativeSpecifier(fromFile: string, toFile: string): string {\n const rel = relative(dirname(fromFile), toFile).replaceAll(\"\\\\\", \"/\");\n return rel.startsWith(\".\") ? rel : `./${rel}`;\n}\n\n/**\n * Regenerate the config shim, mirroring `@asheeui/vite`'s virtual module:\n * if a config file exists we re-export its default export, otherwise we\n * export `undefined`.\n *\n * The write is skipped when the content is unchanged, so webpack's\n * `beforeCompile` hook does not churn the file (or Turbopack's watcher)\n * on every rebuild.\n *\n * @param root - Project root directory. Defaults to `process.cwd()`.\n * @returns The absolute path of the regenerated shim file.\n */\nexport function generateShim(root?: string): string {\n const shimPath = resolveShimPath(root);\n const configPath = discoverConfig(root);\n\n const content = configPath\n ? `export { default } from ${JSON.stringify(\n toRelativeSpecifier(shimPath, configPath),\n )};\\n`\n : \"export default undefined;\\n\";\n\n if (!existsSync(shimPath) || readFileSync(shimPath, \"utf8\") !== content) {\n mkdirSync(dirname(shimPath), { recursive: true });\n writeFileSync(shimPath, content, \"utf8\");\n }\n\n return shimPath;\n}\n","import { VIRTUAL_ID } from \"./generate\";\n\n/**\n * The part of Next's Turbopack config that this package patches.\n *\n * Next exposes the same shape both at the stable `turbopack` key\n * (`>= 15.1`) and at the deprecated `experimental.turbo` key, so one\n * structural type covers both merge targets.\n */\nexport interface TurbopackPatch {\n /** Alias map used to redirect module specifiers during resolution. */\n resolveAlias?: Record<string, string>;\n}\n\n/**\n * Point `virtual:ashee-config` at the generated shim inside a Turbopack\n * config section.\n *\n * The given `target` object is mutated and then returned so the caller\n * can use it in an inline expression.\n *\n * @param target - Turbopack config section (stable or experimental).\n * @param shimPath - Project-root-relative path of the generated shim.\n * @returns The same `target` object, with the alias registered.\n *\n * @example\n * ```ts\n * const turbopack = addAsheeConfigResolveAlias(\n * { resolveAlias: {} },\n * \"./.ashee/generated-config.mjs\",\n * );\n * ```\n */\nexport function addAsheeConfigResolveAlias(\n target: TurbopackPatch,\n shimPath: string,\n): TurbopackPatch {\n target.resolveAlias ??= {};\n target.resolveAlias[VIRTUAL_ID] = shimPath;\n return target;\n}\n","import { VIRTUAL_ID } from \"./generate\";\nimport type {\n WebpackConfigPatch,\n WebpackContextLike,\n WebpackPluginLike,\n} from \"./types\";\n\n/**\n * Exact-match alias key (`$`-suffixed) so a hypothetical future\n * `virtual:ashee-config/foo` import does not also resolve through this\n * alias.\n */\nconst EXACT_VIRTUAL_ID = `${VIRTUAL_ID}$`;\n\n/**\n * Point `virtual:ashee-config` at the generated shim so app code keeps\n * using the same import specifier as Vite.\n *\n * @param config - Webpack config section to patch (mutated in place).\n * @param shimPath - Absolute path of the generated shim.\n * @returns The same `config` object, with the alias registered.\n *\n * @example\n * ```ts\n * const config = addAsheeConfigAlias(\n * { resolve: { alias: {} } },\n * \"/proj/.ashee/generated-config.mjs\",\n * );\n * ```\n */\nexport function addAsheeConfigAlias(\n config: WebpackConfigPatch,\n shimPath: string,\n): WebpackConfigPatch {\n config.resolve ??= {};\n config.resolve.alias ??= {};\n config.resolve.alias[EXACT_VIRTUAL_ID] = shimPath;\n return config;\n}\n\n/**\n * Create a dev-only webpack plugin that regenerates the shim before\n * every compile so edits to an existing config file are always picked\n * up.\n *\n * The plugin also registers every candidate filename as a webpack\n * \"missing dependency\": the shim has no reference to a file that does\n * not exist yet, so without this, *creating* the config file for the\n * first time would never trigger a rebuild on its own. Writes are\n * skipped when content is unchanged, keeping rebuilds cheap.\n *\n * @param regenerate - Callback that rewrites the shim file.\n * @param candidatePaths - Absolute candidate config paths to watch as\n * missing dependencies.\n * @returns A webpack plugin object.\n */\nexport function createBeforeCompilePlugin(\n regenerate: () => void,\n candidatePaths: string[],\n): WebpackPluginLike {\n return {\n apply(compiler) {\n compiler.hooks.beforeCompile.tap(\"ashee:virtual-config\", () => {\n regenerate();\n });\n compiler.hooks.afterCompile.tap(\"ashee:virtual-config\", (compilation) => {\n for (const path of candidatePaths) {\n compilation.missingDependencies.add(path);\n }\n });\n },\n };\n}\n\n/**\n * Create the webpack hook that Next invokes when building.\n *\n * The returned hook always adds the config alias; in dev mode it also\n * installs the `beforeCompile` regeneration plugin and the\n * missing-dependency watcher.\n *\n * @param options - Hook options.\n * @param options.shimPath - Absolute path of the generated shim.\n * @param options.candidatePaths - Absolute candidate config paths.\n * @param options.root - Project root used when regenerating the shim.\n * @param options.regenerate - Function that regenerates the shim for a\n * given root directory.\n * @returns A webpack config hook matching Next's `webpack` signature.\n */\nexport function createWebpackHook(options: {\n shimPath: string;\n candidatePaths: string[];\n root?: string;\n regenerate: (root?: string) => string;\n}): (\n config: WebpackConfigPatch,\n context: WebpackContextLike,\n) => WebpackConfigPatch {\n const { shimPath, candidatePaths, regenerate, root } = options;\n\n return (config, context) => {\n addAsheeConfigAlias(config, shimPath);\n\n if (context.dev) {\n config.plugins ??= [];\n config.plugins.push(\n createBeforeCompilePlugin(() => regenerate(root), candidatePaths),\n );\n }\n\n return config;\n };\n}\n","import type { NextConfig } from \"next\";\nimport {\n generateShim,\n resolveCandidatePaths,\n resolveShimPath,\n SHIM_RELATIVE_PATH,\n VIRTUAL_ID,\n} from \"./generate\";\nimport type { TurbopackPatch } from \"./turbopack\";\nimport { addAsheeConfigResolveAlias } from \"./turbopack\";\nimport type {\n WebpackConfigPatch,\n WebpackContextLike,\n WithAsheeUIConfig,\n} from \"./types\";\nimport { createWebpackHook } from \"./webpack\";\n\n/**\n * AsheeUI packages that ship TypeScript source and must be compiled by\n * Next.\n *\n * `transpilePackages` takes npm package names, deduped against any the\n * consumer provides.\n */\nconst ASHEE_TRANSPILE_PACKAGES = [\"asheeui\"];\n\ntype NextWebpack = NonNullable<NextConfig[\"webpack\"]>;\n\n/**\n * Structural superset of `NextConfig` used to reach legacy keys.\n *\n * Next 15 kept `transpilePackages` on `NextConfig` and Turbopack behind\n * `experimental.turbo`; Next 16 removed both (Turbopack is the default).\n * This superset lets one code path type-check against either major\n * version of the peer dependency.\n */\ntype LegacyNextConfig = NextConfig & {\n transpilePackages?: string[];\n experimental?: {\n turbo?: unknown;\n };\n};\n\n/**\n * Wrap a `next.config.mjs`/`next.config.ts` object with AsheeUI\n * integration.\n *\n * The wrapper:\n * 1. Generates a config shim at `.ashee/generated-config.mjs` (same\n * resolution as `@asheeui/vite`'s `virtual:ashee-config`).\n * 2. Adds a `virtual:ashee-config` alias for Webpack and Turbopack so\n * app code uses the identical import specifier in both bundlers.\n * Webpack gets an absolute path (it resolves against its own\n * context, not the `root` override), Turbopack gets a\n * project-root-relative one (it rejects absolute targets).\n * 3. Merges `transpilePackages` so AsheeUI's source-shipping packages\n * are compiled by Next.\n *\n * @param config - Next config to wrap. AsheeUI override keys (`root`,\n * `transpilePackages`) are consumed and stripped from the returned\n * `NextConfig`. Defaults to `{}`.\n * @returns A plain `NextConfig` with the AsheeUI integration applied.\n *\n * @example\n * ```ts\n * // next.config.ts\n * import { withAsheeUI } from \"@asheeui/next\";\n *\n * export default withAsheeUI({\n * transpilePackages: [\"@my-org/ui\"],\n * });\n * ```\n */\nexport function withAsheeUI(config: WithAsheeUIConfig = {}): NextConfig {\n const {\n root,\n transpilePackages: extraTranspilePackages,\n ...nextConfig\n } = config;\n\n const baseDir = root ?? process.cwd();\n\n // Read-only access to config keys that only exist on Next 15.\n const legacyConfig = nextConfig as LegacyNextConfig;\n\n generateShim(baseDir);\n\n const absoluteShimPath = resolveShimPath(baseDir);\n const relativeShimPath = `./${SHIM_RELATIVE_PATH}`;\n const candidatePaths = resolveCandidatePaths(baseDir);\n\n const transpilePackages = [\n ...new Set([\n ...ASHEE_TRANSPILE_PACKAGES,\n ...(legacyConfig.transpilePackages ?? []),\n ...(extraTranspilePackages ?? []),\n ]),\n ];\n\n const userWebpack = nextConfig.webpack;\n\n const webpack: NextWebpack = ((config, context) => {\n const patchConfig = config as unknown as WebpackConfigPatch;\n const patchContext = context as unknown as WebpackContextLike;\n\n const hook = createWebpackHook({\n shimPath: absoluteShimPath,\n candidatePaths,\n root: baseDir,\n regenerate: generateShim,\n });\n\n if (userWebpack) {\n const userResult = userWebpack(\n patchConfig as never,\n patchContext as never,\n );\n return hook(userResult as WebpackConfigPatch, patchContext) as never;\n }\n\n return hook(patchConfig, patchContext) as never;\n }) as NextWebpack;\n\n // Turbopack: patch the stable key, and also the experimental fallback\n // if the consumer configured it on an older Next 15.x.\n const turbopackResolveAlias: Record<string, string> = {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n [VIRTUAL_ID]: relativeShimPath,\n };\n\n const turbopack = {\n ...nextConfig.turbopack,\n resolveAlias: turbopackResolveAlias,\n };\n\n const patchedConfig: NextConfig = {\n ...nextConfig,\n transpilePackages,\n webpack,\n turbopack,\n };\n\n if (legacyConfig.experimental?.turbo) {\n const turboPatch = addAsheeConfigResolveAlias(\n legacyConfig.experimental.turbo as TurbopackPatch,\n relativeShimPath,\n ) as never;\n patchedConfig.experimental = {\n ...nextConfig.experimental,\n turbo: turboPatch,\n } as NextConfig[\"experimental\"];\n }\n\n return patchedConfig;\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,aAAa;;;;;;;;;AAU1B,MAAa,qBAAqB;;;;;;;AAQlC,SAAgB,gBAAgB,MAAuB;CACrD,OAAO,QAAQ,QAAQ,QAAQ,IAAI,GAAG,kBAAkB;AAC1D;;;;;;;;;;;AAYA,SAAgB,sBAAsB,MAAyB;CAC7D,MAAM,OAAO,QAAQ,QAAQ,IAAI;CACjC,OAAO,WAAW,KAAK,SAAS,QAAQ,MAAM,IAAI,CAAC;AACrD;;;;;;;;;;;AAYA,SAAS,oBAAoB,UAAkB,QAAwB;CACrE,MAAM,MAAM,SAAS,QAAQ,QAAQ,GAAG,MAAM,CAAC,CAAC,WAAW,MAAM,GAAG;CACpE,OAAO,IAAI,WAAW,GAAG,IAAI,MAAM,KAAK;AAC1C;;;;;;;;;;;;;AAcA,SAAgB,aAAa,MAAuB;CAClD,MAAM,WAAW,gBAAgB,IAAI;CACrC,MAAM,aAAa,eAAe,IAAI;CAEtC,MAAM,UAAU,aACZ,2BAA2B,KAAK,UAC9B,oBAAoB,UAAU,UAAU,CAC1C,EAAE,OACF;CAEJ,IAAI,CAAC,WAAW,QAAQ,KAAK,aAAa,UAAU,MAAM,MAAM,SAAS;EACvE,UAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;EAChD,cAAc,UAAU,SAAS,MAAM;CACzC;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;AC3DA,SAAgB,2BACd,QACA,UACgB;CAChB,OAAO,iBAAiB,CAAC;CACzB,OAAO,aAAa,cAAc;CAClC,OAAO;AACT;;;;;;;;AC5BA,MAAM,mBAAmB,GAAG,WAAW;;;;;;;;;;;;;;;;;AAkBvC,SAAgB,oBACd,QACA,UACoB;CACpB,OAAO,YAAY,CAAC;CACpB,OAAO,QAAQ,UAAU,CAAC;CAC1B,OAAO,QAAQ,MAAM,oBAAoB;CACzC,OAAO;AACT;;;;;;;;;;;;;;;;;AAkBA,SAAgB,0BACd,YACA,gBACmB;CACnB,OAAO,EACL,MAAM,UAAU;EACd,SAAS,MAAM,cAAc,IAAI,8BAA8B;GAC7D,WAAW;EACb,CAAC;EACD,SAAS,MAAM,aAAa,IAAI,yBAAyB,gBAAgB;GACvE,KAAK,MAAM,QAAQ,gBACjB,YAAY,oBAAoB,IAAI,IAAI;EAE5C,CAAC;CACH,EACF;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,kBAAkB,SAQV;CACtB,MAAM,EAAE,UAAU,gBAAgB,YAAY,SAAS;CAEvD,QAAQ,QAAQ,YAAY;EAC1B,oBAAoB,QAAQ,QAAQ;EAEpC,IAAI,QAAQ,KAAK;GACf,OAAO,YAAY,CAAC;GACpB,OAAO,QAAQ,KACb,gCAAgC,WAAW,IAAI,GAAG,cAAc,CAClE;EACF;EAEA,OAAO;CACT;AACF;;;;;;;;;;ACxFA,MAAM,2BAA2B,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiD3C,SAAgB,YAAY,SAA4B,CAAC,GAAe;CACtE,MAAM,EACJ,MACA,mBAAmB,wBACnB,GAAG,eACD;CAEJ,MAAM,UAAU,QAAQ,QAAQ,IAAI;CAGpC,MAAM,eAAe;CAErB,aAAa,OAAO;CAEpB,MAAM,mBAAmB,gBAAgB,OAAO;CAChD,MAAM,mBAAmB,KAAK;CAC9B,MAAM,iBAAiB,sBAAsB,OAAO;CAEpD,MAAM,oBAAoB,CACxB,mBAAG,IAAI,IAAI;EACT,GAAG;EACH,GAAI,aAAa,qBAAqB,CAAC;EACvC,GAAI,0BAA0B,CAAC;CACjC,CAAC,CACH;CAEA,MAAM,cAAc,WAAW;CAE/B,MAAM,YAAyB,QAAQ,YAAY;EACjD,MAAM,cAAc;EACpB,MAAM,eAAe;EAErB,MAAM,OAAO,kBAAkB;GAC7B,UAAU;GACV;GACA,MAAM;GACN,YAAY;EACd,CAAC;EAED,IAAI,aAKF,OAAO,KAJY,YACjB,aACA,YAEmB,GAAyB,YAAY;EAG5D,OAAO,KAAK,aAAa,YAAY;CACvC;CAIA,MAAM,wBAAgD;EACpD,GAAI,WAAW,WAAW,gBAAgB,CAAC;GAC1C,aAAa;CAChB;CAEA,MAAM,YAAY;EAChB,GAAG,WAAW;EACd,cAAc;CAChB;CAEA,MAAM,gBAA4B;EAChC,GAAG;EACH;EACA;EACA;CACF;CAEA,IAAI,aAAa,cAAc,OAAO;EACpC,MAAM,aAAa,2BACjB,aAAa,aAAa,OAC1B,gBACF;EACA,cAAc,eAAe;GAC3B,GAAG,WAAW;GACd,OAAO;EACT;CACF;CAEA,OAAO;AACT"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@asheeui/next",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"types": "./dist/index.d.mts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"default": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/index.d.cts",
|
|
15
|
+
"default": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@asheeui/utils": "0.3.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"next": "^16.0.0",
|
|
27
|
+
"asheeui": "0.5.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"asheeui": {
|
|
31
|
+
"optional": true
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^26.1.2",
|
|
36
|
+
"next": "16.3.1",
|
|
37
|
+
"tsdown": "^0.22.14",
|
|
38
|
+
"typescript": "^5.0.0"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsdown src/index.ts --format esm,cjs --dts --clean",
|
|
43
|
+
"dev": "tsdown src/index.ts --format esm,cjs --dts --watch"
|
|
44
|
+
},
|
|
45
|
+
"module": "./dist/index.mjs"
|
|
46
|
+
}
|