Skip to content

Commit 79f38ae

Browse files
committed
feat(powerlines): Major typing changes to support all types of unplugin builder hooks
1 parent b1d6644 commit 79f38ae

File tree

26 files changed

+1842
-1190
lines changed

26 files changed

+1842
-1190
lines changed

packages/plugin-nitro/src/index.ts

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import { LogLevelLabel } from "@storm-software/config-tools/types";
2020
import { appendPath } from "@stryke/path/append";
21+
import defu from "defu";
2122
import { createNitro } from "nitro/builder";
2223
import { NitroConfig } from "nitro/types";
2324
import { getConfigPath } from "powerlines/plugin-utils/get-config-path";
@@ -40,6 +41,12 @@ export const plugin = <
4041
options: NitroPluginOptions = {}
4142
) => {
4243
return [
44+
// nitroInit(options),
45+
// nitroEnv(options),
46+
// nitroMain(options),
47+
// nitroPrepare(options),
48+
// nitroService(options),
49+
// nitroPreviewPlugin(options),
4350
{
4451
name: "nitro:config",
4552
async config() {
@@ -103,8 +110,251 @@ export const plugin = <
103110
this.nitro.nitro = await createNitro(this.config.nitro);
104111
}
105112
}
113+
},
114+
{
115+
name: "nitro:vite",
116+
vite: {
117+
config(_, configEnv) {
118+
this.config.nitro.dev = configEnv.command === "serve";
119+
this.config.nitro.builder = "vite";
120+
this.config.nitro.rootDir = this.config.projectRoot;
121+
this.config.nitro = defu(
122+
this.config.nitro,
123+
this.config
124+
) as NitroConfig;
125+
}
126+
}
106127
}
107128
] as Plugin<TContext>[];
108129
};
109130

110131
export default plugin;
132+
133+
// function nitroInit(
134+
// options: NitroPluginOptions = {}
135+
// ): Plugin<NitroPluginContext> {
136+
// return {
137+
// name: "nitro:init",
138+
// sharedDuringBuild: true,
139+
140+
// async config(config, configEnv) {
141+
// this.isRolldown = !!(this.meta as Record<string, string>).rolldownVersion;
142+
// if (!this.isInitialized) {
143+
// debug("[init] Initializing nitro");
144+
// this.isInitialized = true;
145+
// await setupNitroContext(this, configEnv, config);
146+
// }
147+
// },
148+
149+
// applyToEnvironment(env) {
150+
// if (env.name === "nitro" && ctx.nitro?.options.dev) {
151+
// debug("[init] Adding rollup plugins for dev");
152+
// return [...((ctx.rollupConfig?.config.plugins as VitePlugin[]) || [])];
153+
// }
154+
// },
155+
// vite: {
156+
// apply: (_, configEnv) => !configEnv.isPreview
157+
// }
158+
// };
159+
// }
160+
161+
// function nitroEnv(ctx: NitroPluginContext): VitePlugin {
162+
// return {
163+
// name: "nitro:env",
164+
// sharedDuringBuild: true,
165+
// apply: (_config, configEnv) => !configEnv.isPreview,
166+
167+
// async config(userConfig, _configEnv) {
168+
// debug("[env] Extending config (environments)");
169+
// const environments: Record<string, EnvironmentOptions> = {
170+
// ...createServiceEnvironments(ctx),
171+
// nitro: createNitroEnvironment(ctx)
172+
// };
173+
// environments.client = {
174+
// consumer: userConfig.environments?.client?.consumer ?? "client",
175+
// build: {
176+
// rollupOptions: {
177+
// input:
178+
// userConfig.environments?.client?.build?.rollupOptions?.input ??
179+
// useNitro(ctx).options.renderer?.template
180+
// }
181+
// }
182+
// };
183+
// debug("[env] Environments:", Object.keys(environments).join(", "));
184+
// return {
185+
// environments
186+
// };
187+
// },
188+
189+
// configEnvironment(name, config) {
190+
// if (config.consumer === "client") {
191+
// debug(
192+
// "[env] Configuring client environment",
193+
// name === "client" ? "" : ` (${name})`
194+
// );
195+
// config.build!.emptyOutDir = false;
196+
// config.build!.outDir = useNitro(ctx).options.output.publicDir;
197+
// }
198+
// }
199+
// };
200+
// }
201+
202+
// function nitroMain(ctx: NitroPluginContext): VitePlugin {
203+
// return {
204+
// name: "nitro:main",
205+
// sharedDuringBuild: true,
206+
// apply: (_config, configEnv) => !configEnv.isPreview,
207+
208+
// async config(userConfig, _configEnv) {
209+
// debug("[main] Extending config (appType, resolve, server)");
210+
// if (!ctx.rollupConfig) {
211+
// throw new Error("Nitro rollup config is not initialized yet.");
212+
// }
213+
// return {
214+
// appType: userConfig.appType || "custom",
215+
// resolve: {
216+
// // TODO: environment specific aliases not working
217+
// // https://github.com/vitejs/vite/pull/17583 (seems not effective)
218+
// alias: ctx.rollupConfig.base.aliases
219+
// },
220+
// builder: {
221+
// sharedConfigBuild: true
222+
// },
223+
// server: {
224+
// port:
225+
// Number.parseInt(process.env.PORT || "") ||
226+
// userConfig.server?.port ||
227+
// useNitro(ctx).options.devServer?.port ||
228+
// 3000,
229+
// // #3673, disable Vite's `cors` by default as Nitro handles all requests
230+
// cors: false
231+
// }
232+
// };
233+
// },
234+
235+
// buildApp: {
236+
// order: "post",
237+
// handler(builder) {
238+
// debug("[main] Building environments");
239+
// return buildEnvironments(ctx, builder);
240+
// }
241+
// },
242+
243+
// generateBundle: {
244+
// handler(_options, bundle) {
245+
// const environment = this.environment;
246+
// debug(
247+
// "[main] Generating manifest and entry points for environment:",
248+
// environment.name
249+
// );
250+
// const serviceNames = Object.keys(ctx.services);
251+
// const isRegisteredService = serviceNames.includes(environment.name);
252+
253+
// // Find entry point of this service
254+
// let entryFile: string | undefined;
255+
// for (const [_name, file] of Object.entries(bundle)) {
256+
// if (file.type === "chunk" && isRegisteredService && file.isEntry) {
257+
// if (entryFile === undefined) {
258+
// entryFile = file.fileName;
259+
// } else {
260+
// this.warn(
261+
// `Multiple entry points found for service "${environment.name}"`
262+
// );
263+
// }
264+
// }
265+
// }
266+
// if (isRegisteredService) {
267+
// if (entryFile === undefined) {
268+
// this.error(
269+
// `No entry point found for service "${this.environment.name}".`
270+
// );
271+
// }
272+
// ctx._entryPoints![this.environment.name] = entryFile!;
273+
// }
274+
// }
275+
// },
276+
277+
// configureServer: server => {
278+
// debug("[main] Configuring dev server");
279+
// return configureViteDevServer(ctx, server);
280+
// },
281+
282+
// // Automatically reload the client when a server module is updated
283+
// // see: https://github.com/vitejs/vite/issues/19114
284+
// async hotUpdate({ server, modules, timestamp }) {
285+
// const env = this.environment;
286+
// if (
287+
// ctx.pluginConfig.experimental?.vite.serverReload === false ||
288+
// env.config.consumer === "client"
289+
// ) {
290+
// return;
291+
// }
292+
// const clientEnvs = Object.values(server.environments).filter(
293+
// env => env.config.consumer === "client"
294+
// );
295+
// let hasServerOnlyModule = false;
296+
// const invalidated = new Set<EnvironmentModuleNode>();
297+
// for (const mod of modules) {
298+
// if (
299+
// mod.id &&
300+
// !clientEnvs.some(env => env.moduleGraph.getModuleById(mod.id))
301+
// ) {
302+
// hasServerOnlyModule = true;
303+
// env.moduleGraph.invalidateModule(mod, invalidated, timestamp, false);
304+
// }
305+
// }
306+
// if (hasServerOnlyModule) {
307+
// env.hot.send({ type: "full-reload" });
308+
// server.ws.send({ type: "full-reload" });
309+
// return [];
310+
// }
311+
// }
312+
// };
313+
// }
314+
315+
// function nitroPrepare(ctx: NitroPluginContext): VitePlugin {
316+
// return {
317+
// name: "nitro:prepare",
318+
// sharedDuringBuild: true,
319+
// applyToEnvironment: env => env.name === "nitro",
320+
321+
// buildApp: {
322+
// // Clean the output directory before any environment is built
323+
// order: "pre",
324+
// async handler() {
325+
// debug("[prepare] Preparing output directory");
326+
// const nitro = ctx.nitro;
327+
// await prepare(nitro);
328+
// }
329+
// }
330+
// };
331+
// }
332+
333+
// function nitroService(ctx: NitroPluginContext): VitePlugin {
334+
// return {
335+
// name: "nitro:service",
336+
// enforce: "pre",
337+
// sharedDuringBuild: true,
338+
// applyToEnvironment: env => env.name === "nitro",
339+
340+
// resolveId: {
341+
// filter: { id: /^#nitro-vite-setup$/ },
342+
// async handler(id) {
343+
// // Virtual modules
344+
// if (id === "#nitro-vite-setup") {
345+
// return { id, moduleSideEffects: true };
346+
// }
347+
// }
348+
// },
349+
350+
// load: {
351+
// filter: { id: /^#nitro-vite-setup$/ },
352+
// async handler(id) {
353+
// // Virtual modules
354+
// if (id === "#nitro-vite-setup") {
355+
// return prodSetup(ctx);
356+
// }
357+
// }
358+
// }
359+
// };
360+
// }

packages/plugin-vite/src/types/plugin.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
------------------------------------------------------------------- */
1818

1919
import { ViteBuildConfig } from "powerlines/types/build";
20+
import { ConfigEnv } from "powerlines/types/config";
2021
import { PluginContext } from "powerlines/types/context";
2122
import { ViteResolvedConfig } from "powerlines/types/resolved";
2223

@@ -26,4 +27,7 @@ export type VitePluginResolvedConfig = ViteResolvedConfig;
2627

2728
export type VitePluginContext<
2829
TResolvedConfig extends VitePluginResolvedConfig = VitePluginResolvedConfig
29-
> = PluginContext<TResolvedConfig>;
30+
> = PluginContext<TResolvedConfig> & {
31+
dev: boolean;
32+
configEnv: ConfigEnv;
33+
};

packages/powerlines/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,9 +723,11 @@
723723
"@types/babel__helper-plugin-utils": "catalog:",
724724
"@types/babel__template": "catalog:",
725725
"@types/babel__traverse": "catalog:",
726+
"@types/bun": "catalog:",
726727
"@types/diff-match-patch": "catalog:",
727728
"@types/node": "catalog:",
728729
"@types/semver": "catalog:",
730+
"bun-types-no-globals": "catalog:",
729731
"eslint": "catalog:",
730732
"minimatch": "catalog:",
731733
"tsdown": "catalog:",

packages/powerlines/src/api.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ import type {
8484
EnvironmentContext,
8585
PluginContext
8686
} from "./types/context";
87-
import { HookKeys, InferHookParameters } from "./types/hooks";
87+
import { InferHookParameters } from "./types/hooks";
8888
import { UNSAFE_APIContext } from "./types/internal";
8989
import type { Plugin, TypesResult } from "./types/plugin";
9090
import { EnvironmentResolvedConfig, ResolvedConfig } from "./types/resolved";
@@ -783,14 +783,14 @@ ${formatTypes(types)}
783783
* @param args - The arguments to pass to the hook
784784
* @returns The result of the hook call
785785
*/
786-
public async callHook<TKey extends HookKeys<PluginContext<TResolvedConfig>>>(
786+
public async callHook<TKey extends string>(
787787
hook: TKey,
788788
options: CallHookOptions & {
789789
environment?: string | EnvironmentContext<TResolvedConfig>;
790790
},
791791
...args: InferHookParameters<PluginContext<TResolvedConfig>, TKey>
792792
) {
793-
return callHook<TResolvedConfig, EnvironmentContext<TResolvedConfig>, TKey>(
793+
return callHook<TResolvedConfig, TKey>(
794794
isSetObject(options?.environment)
795795
? options.environment
796796
: await this.#context.getEnvironment(options?.environment),
@@ -992,7 +992,7 @@ ${formatTypes(types)}
992992
>;
993993
}
994994

995-
if (!isPluginConfig(awaited)) {
995+
if (!isPluginConfig<PluginContext<TResolvedConfig>>(awaited)) {
996996
const invalid = findInvalidPluginConfig(awaited);
997997

998998
throw new Error(
@@ -1024,7 +1024,7 @@ ${formatTypes(types)}
10241024
isPlugin<PluginContext<TResolvedConfig>>
10251025
)
10261026
) {
1027-
plugins = awaited;
1027+
plugins = awaited as Plugin<PluginContext<TResolvedConfig>>[];
10281028
} else if (
10291029
Array.isArray(awaited) &&
10301030
(awaited as PluginConfig<PluginContext<TResolvedConfig>>[]).every(
@@ -1040,14 +1040,17 @@ ${formatTypes(types)}
10401040
plugins.push(...initialized);
10411041
}
10421042
}
1043-
} else if (isPluginConfigTuple(awaited) || isPluginConfigObject(awaited)) {
1043+
} else if (
1044+
isPluginConfigTuple<PluginContext<TResolvedConfig>>(awaited) ||
1045+
isPluginConfigObject<PluginContext<TResolvedConfig>>(awaited)
1046+
) {
10441047
let pluginConfig!:
10451048
| string
10461049
| PluginFactory<PluginContext<TResolvedConfig>>
10471050
| Plugin<PluginContext<TResolvedConfig>>;
10481051
let pluginOptions: any;
10491052

1050-
if (isPluginConfigTuple(awaited)) {
1053+
if (isPluginConfigTuple<PluginContext<TResolvedConfig>>(awaited)) {
10511054
pluginConfig = awaited[0] as Plugin<PluginContext<TResolvedConfig>>;
10521055
pluginOptions =
10531056
(awaited as PluginConfigTuple)?.length === 2 ? awaited[1] : undefined;
@@ -1076,7 +1079,7 @@ ${formatTypes(types)}
10761079
pluginConfig.every(isPlugin<PluginContext<TResolvedConfig>>)
10771080
) {
10781081
plugins = pluginConfig;
1079-
} else if (isPlugin(pluginConfig)) {
1082+
} else if (isPlugin<PluginContext<TResolvedConfig>>(pluginConfig)) {
10801083
plugins = toArray(pluginConfig);
10811084
}
10821085
}

0 commit comments

Comments
 (0)