revojs 0.1.57 → 0.1.58
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/dist/assets/index.d.ts +11 -0
- package/dist/assets/index.js +51 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +150 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/module/index.d.ts +108 -0
- package/dist/module/index.js +306 -0
- package/dist/package.js +62 -0
- package/dist/router/index.d.ts +43 -0
- package/dist/router/index.js +183 -0
- package/dist/scope/index.d.ts +43 -0
- package/dist/scope/index.js +73 -0
- package/dist/shared/index.d.ts +14 -0
- package/dist/shared/index.js +39 -0
- package/dist/types/index.d.ts +21 -0
- package/package.json +28 -25
- package/src/types/index.d.ts +14 -11
- package/dist/commands/index.d.mts +0 -1
- package/dist/commands/index.mjs +0 -50
- package/dist/index-DOmfkUsW.d.mts +0 -229
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -55
- package/dist/kit/index.d.mts +0 -13
- package/dist/kit/index.mjs +0 -49
- package/dist/package-DllXqorv.mjs +0 -5
- package/dist/server-BplNURRd.mjs +0 -655
- package/dist/vite/index.d.mts +0 -12
- package/dist/vite/index.mjs +0 -329
- package/src/types/assets.d.ts +0 -7
- package/src/types/routes.d.ts +0 -7
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type MimeType = (typeof mimeTypes)[keyof typeof mimeTypes];
|
|
2
|
+
export interface Asset {
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
relative: string;
|
|
6
|
+
entityTag: string;
|
|
7
|
+
lastModified: string;
|
|
8
|
+
size: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function mimeType(file: string): MimeType;
|
|
11
|
+
export declare const mimeTypes: Record<string, string>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/assets/index.ts
|
|
2
|
+
function mimeType(file) {
|
|
3
|
+
return mimeTypes[/\.([a-zA-Z0-9]+?)$/.exec(file)?.at(1) ?? ""] ?? "text/plain";
|
|
4
|
+
}
|
|
5
|
+
var mimeTypes = {
|
|
6
|
+
"txt": "text/plain",
|
|
7
|
+
"css": "text/css",
|
|
8
|
+
"html": "text/html",
|
|
9
|
+
"htm": "text/html",
|
|
10
|
+
"js": "text/javascript",
|
|
11
|
+
"json": "application/json",
|
|
12
|
+
"xml": "application/xml",
|
|
13
|
+
"csv": "text/csv",
|
|
14
|
+
"jpg": "image/jpeg",
|
|
15
|
+
"jpeg": "image/jpeg",
|
|
16
|
+
"png": "image/png",
|
|
17
|
+
"gif": "image/gif",
|
|
18
|
+
"webp": "image/webp",
|
|
19
|
+
"svg": "image/svg+xml",
|
|
20
|
+
"bmp": "image/bmp",
|
|
21
|
+
"ico": "image/x-icon",
|
|
22
|
+
"ttf": "font/ttf",
|
|
23
|
+
"otf": "font/otf",
|
|
24
|
+
"woff": "font/woff",
|
|
25
|
+
"woff2": "font/woff2",
|
|
26
|
+
"mp3": "audio/mpeg",
|
|
27
|
+
"wav": "audio/wav",
|
|
28
|
+
"ogg": "audio/ogg",
|
|
29
|
+
"m4a": "audio/mp4",
|
|
30
|
+
"mp4": "video/mp4",
|
|
31
|
+
"webm": "video/webm",
|
|
32
|
+
"ogv": "video/ogg",
|
|
33
|
+
"mov": "video/quicktime",
|
|
34
|
+
"avi": "video/x-msvideo",
|
|
35
|
+
"zip": "application/zip",
|
|
36
|
+
"rar": "application/vnd.rar",
|
|
37
|
+
"tar": "application/x-tar",
|
|
38
|
+
"gz": "application/gzip",
|
|
39
|
+
"7z": "application/x-7z-compressed",
|
|
40
|
+
"pdf": "application/pdf",
|
|
41
|
+
"doc": "application/msword",
|
|
42
|
+
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
43
|
+
"xls": "application/vnd.ms-excel",
|
|
44
|
+
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
45
|
+
"ppt": "application/vnd.ms-powerpoint",
|
|
46
|
+
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
47
|
+
"exe": "application/vnd.microsoft.portable-executable",
|
|
48
|
+
"apk": "application/vnd.android.package-archive"
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { mimeType, mimeTypes };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRunnableDevEnvironment, createServer, isRunnableDevEnvironment } from "vite";
|
|
3
|
+
import { parseArgs } from "util";
|
|
4
|
+
//#region src/cli/index.ts
|
|
5
|
+
function help() {
|
|
6
|
+
const environmentMeta = new Array();
|
|
7
|
+
for (const [name, environment] of Object.entries(server.environments)) if (isRunnableDevEnvironment(environment)) environmentMeta.push({
|
|
8
|
+
name,
|
|
9
|
+
description: [environment.config.consumer, name === "ssr" ? "default" : void 0].filter(Boolean).join(", ")
|
|
10
|
+
});
|
|
11
|
+
const flagMeta = new Array();
|
|
12
|
+
for (const [name, descriptor] of Object.entries(command?.arguments ?? {})) flagMeta.push({
|
|
13
|
+
name,
|
|
14
|
+
description: descriptor.description,
|
|
15
|
+
multiple: descriptor.multiple,
|
|
16
|
+
short: descriptor.short,
|
|
17
|
+
type: descriptor.type
|
|
18
|
+
});
|
|
19
|
+
flagMeta.push({
|
|
20
|
+
name: "help",
|
|
21
|
+
description: "Show help",
|
|
22
|
+
short: "h",
|
|
23
|
+
type: "boolean"
|
|
24
|
+
}, {
|
|
25
|
+
name: "environment",
|
|
26
|
+
description: "Vite dev environment used for command execution",
|
|
27
|
+
short: "e",
|
|
28
|
+
type: "string"
|
|
29
|
+
});
|
|
30
|
+
const commandMeta = new Array();
|
|
31
|
+
for (const [name, child] of Object.entries(node.children)) {
|
|
32
|
+
let target = child;
|
|
33
|
+
while (target && !target.value) target = Object.values(target.children)[0];
|
|
34
|
+
commandMeta.push({
|
|
35
|
+
name,
|
|
36
|
+
description: target?.value?.description
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
environmentMeta.sort((a, b) => a.name.localeCompare(b.name));
|
|
40
|
+
commandMeta.sort((a, b) => a.name.localeCompare(b.name));
|
|
41
|
+
const lines = new Array();
|
|
42
|
+
lines.push(`Usage: ${["revojs", ...path].join(" ")} [flags]${commandMeta.length > 0 ? " [command]" : ""}`);
|
|
43
|
+
const description = command?.description ?? (path.length === 0 ? "Commands are discovered from ./commands (via the revojs \"commands\" source) and run inside the project's Vite dev server, sharing the same module graph and virtuals." : void 0);
|
|
44
|
+
if (description) lines.push("", description);
|
|
45
|
+
lines.push(...section("Environments", environmentMeta), ...section("Flags", flagMeta.map((flag) => ({
|
|
46
|
+
name: [flag.short ? `-${flag.short}` : void 0, flag.type === "string" ? `--${flag.name}=<value>${flag.multiple ? "..." : ""}` : `--${flag.name}`].filter(Boolean).join(", "),
|
|
47
|
+
description: flag.description
|
|
48
|
+
}))), ...section("Commands", commandMeta));
|
|
49
|
+
console.log(lines.join("\n"));
|
|
50
|
+
}
|
|
51
|
+
function section(title, entries) {
|
|
52
|
+
if (entries.length === 0) return [];
|
|
53
|
+
const width = Math.max(...entries.map((entry) => entry.name.length));
|
|
54
|
+
return [
|
|
55
|
+
"",
|
|
56
|
+
`${title}:`,
|
|
57
|
+
...entries.map((entry) => ` ${entry.name.padEnd(width)} ${entry.description ?? ""}`.trimEnd())
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
var args = process.argv.slice(2);
|
|
61
|
+
var parsed = parseArgs({
|
|
62
|
+
args,
|
|
63
|
+
strict: false,
|
|
64
|
+
allowPositionals: true,
|
|
65
|
+
options: {
|
|
66
|
+
help: {
|
|
67
|
+
type: "boolean",
|
|
68
|
+
short: "h",
|
|
69
|
+
default: false
|
|
70
|
+
},
|
|
71
|
+
environment: {
|
|
72
|
+
type: "string",
|
|
73
|
+
short: "e"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
var server = await createServer({
|
|
78
|
+
appType: "custom",
|
|
79
|
+
environments: { command: {
|
|
80
|
+
consumer: "server",
|
|
81
|
+
dev: { createEnvironment(name, config) {
|
|
82
|
+
return createRunnableDevEnvironment(name, config);
|
|
83
|
+
} }
|
|
84
|
+
} },
|
|
85
|
+
server: {
|
|
86
|
+
middlewareMode: true,
|
|
87
|
+
hmr: false
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
var environment = typeof parsed.values.environment === "string" ? server.environments[parsed.values.environment] : server.environments.command ?? Object.values(server.environments).find((environment) => isRunnableDevEnvironment(environment) && environment.config.consumer === "server") ?? Object.values(server.environments).find(isRunnableDevEnvironment);
|
|
91
|
+
if (!environment || !isRunnableDevEnvironment(environment)) {
|
|
92
|
+
await server.close();
|
|
93
|
+
throw new Error(typeof parsed.values.environment === "string" ? `No runnable environment named "${parsed.values.environment}" found.` : "No runnable Vite environment found.");
|
|
94
|
+
}
|
|
95
|
+
var commands = await environment.runner.import("#commands").then((module) => module.default);
|
|
96
|
+
var radix = { children: {} };
|
|
97
|
+
for (const source of Object.values(commands)) for (const [path, value] of Object.entries(source)) {
|
|
98
|
+
let node = radix;
|
|
99
|
+
for (const segment of path.replace(/\\/g, "/").split("/")) node = node.children[segment] ??= { children: {} };
|
|
100
|
+
node.value = await value();
|
|
101
|
+
}
|
|
102
|
+
var helpRequested = parsed.values.help === true || parsed.positionals[0] === "help";
|
|
103
|
+
var path = new Array();
|
|
104
|
+
var node = radix;
|
|
105
|
+
if (parsed.positionals[0] !== "help") for (const positional of parsed.positionals) {
|
|
106
|
+
const child = node.children[positional];
|
|
107
|
+
if (!child) break;
|
|
108
|
+
node = child;
|
|
109
|
+
path.push(positional);
|
|
110
|
+
}
|
|
111
|
+
var command = node.value;
|
|
112
|
+
try {
|
|
113
|
+
if (command && !helpRequested) {
|
|
114
|
+
const consumable = [...path];
|
|
115
|
+
const context = parseArgs({
|
|
116
|
+
args: args.filter((argument) => {
|
|
117
|
+
const index = consumable.indexOf(argument);
|
|
118
|
+
if (index === -1) return true;
|
|
119
|
+
consumable.splice(index, 1);
|
|
120
|
+
return false;
|
|
121
|
+
}),
|
|
122
|
+
strict: false,
|
|
123
|
+
allowPositionals: true,
|
|
124
|
+
options: {
|
|
125
|
+
...command.arguments,
|
|
126
|
+
help: {
|
|
127
|
+
type: "boolean",
|
|
128
|
+
short: "h",
|
|
129
|
+
description: "Show this help"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
if (context.values.help) help();
|
|
134
|
+
else await command.run({
|
|
135
|
+
args: context.positionals,
|
|
136
|
+
arguments: context.values,
|
|
137
|
+
environment
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
help();
|
|
141
|
+
process.exitCode = helpRequested || command ? 0 : 1;
|
|
142
|
+
}
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(error);
|
|
145
|
+
process.exitCode = 1;
|
|
146
|
+
} finally {
|
|
147
|
+
await server.close();
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export {};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { mimeType, mimeTypes } from "./assets/index.js";
|
|
2
|
+
import { VARIABLE_CONTEXT, createRegisterHooks, createScope, defineContext, defineHook, definePlugin, dispatchHook, dispatchHookSingle, getContext, registerHook, setContext, useVariables } from "./scope/index.js";
|
|
3
|
+
import { GROUP_MATCH, HOOK_MATCH, OPTIONAL_PARAMETER_MATCH, OPTIONAL_WILDCARD_MATCH, PARAMETER_MATCH, ROUTE_CONTEXT, ROUTE_RESOLVER_CONTEXT, Router, WILDCARD_MATCH, fillSegments, toSegments, useRoute } from "./router/index.js";
|
|
4
|
+
export { GROUP_MATCH, HOOK_MATCH, OPTIONAL_PARAMETER_MATCH, OPTIONAL_WILDCARD_MATCH, PARAMETER_MATCH, ROUTE_CONTEXT, ROUTE_RESOLVER_CONTEXT, Router, VARIABLE_CONTEXT, WILDCARD_MATCH, createRegisterHooks, createScope, defineContext, defineHook, definePlugin, dispatchHook, dispatchHookSingle, fillSegments, getContext, mimeType, mimeTypes, registerHook, setContext, toSegments, useRoute, useVariables };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { parseArgs } from "node:util";
|
|
2
|
+
import { type ParseArgsOptionDescriptor, type ParseArgsOptionsConfig } from "node:util";
|
|
3
|
+
import type { RunnableDevEnvironment } from "vite";
|
|
4
|
+
import { type PluginOption, type UserConfig } from "vite";
|
|
5
|
+
import { type Awaitable, type Mergeable } from "../shared/index.ts";
|
|
6
|
+
export type CommandValues<T extends ParseArgsOptionsConfig> = ReturnType<typeof parseArgs<{
|
|
7
|
+
options: T;
|
|
8
|
+
allowPositionals: true;
|
|
9
|
+
strict: true;
|
|
10
|
+
}>>["values"];
|
|
11
|
+
export type Consumer = "client" | "server";
|
|
12
|
+
export type Template = (consumer: Consumer) => Awaitable<undefined | string>;
|
|
13
|
+
export type Variable = StringVariable | NumberVariable | BooleanVariable | EnumVariable;
|
|
14
|
+
export type InferVariableValue<T extends Variable> = T extends {
|
|
15
|
+
type: "enum";
|
|
16
|
+
options: infer Options;
|
|
17
|
+
} ? Extract<Options, ReadonlyArray<unknown>>[number] : T["type"] extends "string" ? string : T["type"] extends "number" ? number : boolean;
|
|
18
|
+
export type OptionalVariable<T extends Variable> = T extends {
|
|
19
|
+
optional: true;
|
|
20
|
+
} ? T extends {
|
|
21
|
+
default: infer Default;
|
|
22
|
+
} ? [Default] extends [undefined] ? undefined : never : undefined : never;
|
|
23
|
+
export type InferVariables<T extends Record<string, Variable>> = {
|
|
24
|
+
[Key in keyof T]: T[Key] extends Record<string, Variable> ? InferVariables<T[Key]> : InferVariableValue<T[Key]> | OptionalVariable<T[Key]>;
|
|
25
|
+
};
|
|
26
|
+
export type UnionToIntersection<TUnion> = (TUnion extends unknown ? (arg: TUnion) => void : never) extends (arg: infer TIntersection) => void ? TIntersection : never;
|
|
27
|
+
export type InferModuleConfig<TModule> = TModule extends Module<infer TName extends string, infer TConfig, infer TDependencies extends ReadonlyArray<Module>> ? Record<TName, TConfig> & InferModuleConfigs<TDependencies> : never;
|
|
28
|
+
export type InferModuleConfigs<TModules extends ReadonlyArray<Module>> = Partial<UnionToIntersection<InferModuleConfig<TModules[number]>>>;
|
|
29
|
+
export type ModuleInput<TModules extends ReadonlyArray<Module>> = Mergeable<Config> & InferModuleConfigs<TModules> & {
|
|
30
|
+
modules?: TModules;
|
|
31
|
+
};
|
|
32
|
+
export type ModuleSetupResult<TName extends string, TConfig, TDependencies extends ReadonlyArray<Module> = []> = void | (Mergeable<Config> & Mergeable<Record<TName, TConfig>> & Mergeable<InferModuleConfigs<TDependencies>>);
|
|
33
|
+
export interface CommandArgument extends ParseArgsOptionDescriptor {
|
|
34
|
+
description?: string;
|
|
35
|
+
}
|
|
36
|
+
export type CommandArguments = ParseArgsOptionsConfig & Record<string, CommandArgument>;
|
|
37
|
+
export interface CommandContext<T extends ParseArgsOptionsConfig = ParseArgsOptionsConfig> {
|
|
38
|
+
args: Array<string>;
|
|
39
|
+
arguments: CommandValues<T>;
|
|
40
|
+
environment: RunnableDevEnvironment;
|
|
41
|
+
}
|
|
42
|
+
export interface Command<T extends ParseArgsOptionsConfig = ParseArgsOptionsConfig> {
|
|
43
|
+
description?: string;
|
|
44
|
+
arguments?: T;
|
|
45
|
+
run: (context: CommandContext<T>) => Awaitable<void>;
|
|
46
|
+
}
|
|
47
|
+
export interface Source {
|
|
48
|
+
match: Array<string>;
|
|
49
|
+
from: Array<string>;
|
|
50
|
+
}
|
|
51
|
+
export interface StringVariable {
|
|
52
|
+
type: "string";
|
|
53
|
+
default?: string;
|
|
54
|
+
optional?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface NumberVariable {
|
|
57
|
+
type: "number";
|
|
58
|
+
default?: number;
|
|
59
|
+
optional?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export interface BooleanVariable {
|
|
62
|
+
type: "boolean";
|
|
63
|
+
default?: boolean;
|
|
64
|
+
optional?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface EnumVariable {
|
|
67
|
+
type: "enum";
|
|
68
|
+
options: Array<string>;
|
|
69
|
+
default?: string;
|
|
70
|
+
optional?: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface Config {
|
|
73
|
+
copy: Array<string>;
|
|
74
|
+
modules: Array<Module>;
|
|
75
|
+
variables: Record<Consumer, Record<string, Variable>>;
|
|
76
|
+
sources: Record<string, Source>;
|
|
77
|
+
virtuals: Record<string, Template>;
|
|
78
|
+
templates: Record<string, Template>;
|
|
79
|
+
vite: UserConfig;
|
|
80
|
+
}
|
|
81
|
+
export interface Module<TName extends string = string, TConfig = unknown, TDependencies extends ReadonlyArray<unknown> = ReadonlyArray<unknown>> {
|
|
82
|
+
name: TName;
|
|
83
|
+
config?: () => TConfig;
|
|
84
|
+
modules?: TDependencies & ReadonlyArray<Module>;
|
|
85
|
+
setup: (config: Config) => Awaitable<void | Mergeable<Config>>;
|
|
86
|
+
}
|
|
87
|
+
export interface ModuleDefinition<TName extends string, TConfig = Record<string, never>, TDependencies extends ReadonlyArray<Module> = []> {
|
|
88
|
+
name: TName;
|
|
89
|
+
config?: () => TConfig;
|
|
90
|
+
modules?: TDependencies;
|
|
91
|
+
setup: (config: Config & Record<TName, TConfig> & InferModuleConfigs<TDependencies>) => Awaitable<ModuleSetupResult<TName, TConfig, TDependencies>>;
|
|
92
|
+
}
|
|
93
|
+
export declare function defineCommand<const T extends ParseArgsOptionsConfig>(command: Command<T>): Command<T>;
|
|
94
|
+
export declare function defineModule<const TName extends string, TConfig = Record<string, never>, const TDependencies extends ReadonlyArray<Module> = []>(definition: ModuleDefinition<TName, TConfig, TDependencies>): Module<TName, TConfig, TDependencies>;
|
|
95
|
+
export declare function addVirtual(config: Config, name: string, virtual: Template): void;
|
|
96
|
+
export declare function addTemplate(config: Config, name: string, template: Template): void;
|
|
97
|
+
export declare function addTypes(config: Config, name: string, types: Template): void;
|
|
98
|
+
export declare function posixPath(path: string): string;
|
|
99
|
+
export declare function resolvePattern(pattern: string, cwd?: string): string[];
|
|
100
|
+
export declare function resolvePaths(patterns: string | ArrayLike<string>, cwd?: string): string[];
|
|
101
|
+
export declare function resolveSource(source: Source): Map<string, Map<string, string>>;
|
|
102
|
+
export declare function useModule(source: string | URL): {
|
|
103
|
+
fromModule: (...paths: Array<string>) => string;
|
|
104
|
+
};
|
|
105
|
+
export declare function createConfig<const TModules extends ReadonlyArray<Module>>(inputConfig?: ModuleInput<TModules>): Promise<Config>;
|
|
106
|
+
export declare function core(config: Config): Promise<Array<PluginOption>>;
|
|
107
|
+
export declare function module<const TModules extends ReadonlyArray<Module>>(inputConfig?: ModuleInput<TModules>): Promise<Array<PluginOption>>;
|
|
108
|
+
export declare function revojs<const TModules extends ReadonlyArray<Module>>(inputConfig?: ModuleInput<TModules>): Promise<Array<PluginOption>>;
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { mimeType } from "../assets/index.js";
|
|
2
|
+
import { mergeObjects } from "../shared/index.js";
|
|
3
|
+
import package_default from "../package.js";
|
|
4
|
+
import { findPackageJSON } from "node:module";
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
import { copyFileSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "fs";
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
import { globSync } from "node:fs";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
import { dirname, extname, isAbsolute, join, posix, relative, resolve, win32 } from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
import "vite";
|
|
13
|
+
//#region src/module/index.ts
|
|
14
|
+
function defineCommand(command) {
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
17
|
+
function defineModule(definition) {
|
|
18
|
+
return definition;
|
|
19
|
+
}
|
|
20
|
+
function addVirtual(config, name, virtual) {
|
|
21
|
+
config.virtuals[name] = virtual;
|
|
22
|
+
}
|
|
23
|
+
function addTemplate(config, name, template) {
|
|
24
|
+
config.templates[name] = template;
|
|
25
|
+
}
|
|
26
|
+
function addTypes(config, name, types) {
|
|
27
|
+
addTemplate(config, `types/${name}.d.ts`, types);
|
|
28
|
+
}
|
|
29
|
+
function posixPath(path) {
|
|
30
|
+
return path.split(win32.sep).join(posix.sep);
|
|
31
|
+
}
|
|
32
|
+
function resolvePattern(pattern, cwd) {
|
|
33
|
+
const from = resolve(cwd ?? ".");
|
|
34
|
+
const files = new Array();
|
|
35
|
+
for (const match of globSync(pattern, { cwd: from })) {
|
|
36
|
+
const file = join(from, match);
|
|
37
|
+
if (statSync(file).isFile()) files.push(posixPath(file));
|
|
38
|
+
}
|
|
39
|
+
return files;
|
|
40
|
+
}
|
|
41
|
+
function resolvePaths(patterns, cwd) {
|
|
42
|
+
const from = resolve(cwd ?? ".");
|
|
43
|
+
const input = Array.isArray(patterns) ? patterns : [patterns];
|
|
44
|
+
const entries = /* @__PURE__ */ new Set();
|
|
45
|
+
const includes = new Array();
|
|
46
|
+
const excludes = new Array();
|
|
47
|
+
for (const pattern of input) if (pattern.startsWith("!")) excludes.push(pattern.slice(1));
|
|
48
|
+
else includes.push(pattern);
|
|
49
|
+
try {
|
|
50
|
+
for (const include of includes) for (const file of resolvePattern(include, from)) entries.add(file);
|
|
51
|
+
for (const exclude of excludes) for (const file of resolvePattern(exclude, from)) entries.delete(file);
|
|
52
|
+
} catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
return [...entries];
|
|
56
|
+
}
|
|
57
|
+
function resolveSource(source) {
|
|
58
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
59
|
+
for (const directory of source.from) {
|
|
60
|
+
const from = resolve(directory);
|
|
61
|
+
const paths = resolvePaths(source.match, from);
|
|
62
|
+
if (paths.length === 0) continue;
|
|
63
|
+
let scope = PACKAGE_CACHE.get(from);
|
|
64
|
+
if (scope === void 0) {
|
|
65
|
+
const path = findPackageJSON(pathToFileURL(from).href);
|
|
66
|
+
if (path === void 0) throw new Error(`Unable to resolve package.json for ${from}`);
|
|
67
|
+
const manifest = JSON.parse(readFileSync(path, "utf8"));
|
|
68
|
+
if (typeof manifest.name !== "string" || manifest.name.length === 0) throw new Error(`Missing "name" field in ${path}`);
|
|
69
|
+
scope = manifest.name;
|
|
70
|
+
PACKAGE_CACHE.set(from, scope);
|
|
71
|
+
}
|
|
72
|
+
let files = scopes.get(scope);
|
|
73
|
+
if (files === void 0) {
|
|
74
|
+
files = /* @__PURE__ */ new Map();
|
|
75
|
+
scopes.set(scope, files);
|
|
76
|
+
}
|
|
77
|
+
for (const file of paths) files.set(posixPath(relative(from, file)).replace(/\.[^/]+$/, ""), file);
|
|
78
|
+
}
|
|
79
|
+
return scopes;
|
|
80
|
+
}
|
|
81
|
+
function useModule(source) {
|
|
82
|
+
source = source.toString();
|
|
83
|
+
if (source.startsWith("file://")) source = dirname(fileURLToPath(source));
|
|
84
|
+
return { fromModule: (...paths) => {
|
|
85
|
+
return posixPath(join(source, ...paths));
|
|
86
|
+
} };
|
|
87
|
+
}
|
|
88
|
+
async function createConfig(inputConfig) {
|
|
89
|
+
const { fromModule } = useModule(import.meta.url);
|
|
90
|
+
const defaultConfig = {
|
|
91
|
+
copy: [],
|
|
92
|
+
modules: [],
|
|
93
|
+
variables: {
|
|
94
|
+
client: {
|
|
95
|
+
isServer: {
|
|
96
|
+
type: "boolean",
|
|
97
|
+
default: false
|
|
98
|
+
},
|
|
99
|
+
isClient: {
|
|
100
|
+
type: "boolean",
|
|
101
|
+
default: true
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
server: {
|
|
105
|
+
isServer: {
|
|
106
|
+
type: "boolean",
|
|
107
|
+
default: true
|
|
108
|
+
},
|
|
109
|
+
isClient: {
|
|
110
|
+
type: "boolean",
|
|
111
|
+
default: false
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
sources: {
|
|
116
|
+
plugins: {
|
|
117
|
+
match: ["**/*.{js,ts}", "!**/*.d.ts"],
|
|
118
|
+
from: ["./plugins"]
|
|
119
|
+
},
|
|
120
|
+
commands: {
|
|
121
|
+
match: ["**/*.{js,ts}", "!**/*.d.ts"],
|
|
122
|
+
from: ["./commands", fromModule("../../cli/commands")]
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
templates: {},
|
|
126
|
+
virtuals: {},
|
|
127
|
+
vite: {}
|
|
128
|
+
};
|
|
129
|
+
let config = mergeObjects(inputConfig, defaultConfig);
|
|
130
|
+
let index = 0;
|
|
131
|
+
while (index < config.modules.length) {
|
|
132
|
+
const module = config.modules[index];
|
|
133
|
+
config = mergeObjects(config, { [module.name]: module.config?.() ?? {} });
|
|
134
|
+
const result = await module.setup(config);
|
|
135
|
+
if (result) config = mergeObjects(config, result);
|
|
136
|
+
if (module.modules) config.modules.push(...module.modules);
|
|
137
|
+
index++;
|
|
138
|
+
}
|
|
139
|
+
for (const module of config.modules) {
|
|
140
|
+
const value = JSON.stringify(config[module.name] ?? {});
|
|
141
|
+
addVirtual(config, `config/${module.name}`, () => `export default ${value}`);
|
|
142
|
+
addTypes(config, `config/${module.name}`, () => `declare module "#config/${module.name}" { const config: ${value}; export default config; }`);
|
|
143
|
+
}
|
|
144
|
+
addTypes(config, "vite", () => "import 'vite/client'");
|
|
145
|
+
addTypes(config, "revojs", () => `import '${fromModule("../types/index.d.ts")}'`);
|
|
146
|
+
return config;
|
|
147
|
+
}
|
|
148
|
+
async function core(config) {
|
|
149
|
+
return [{
|
|
150
|
+
name: package_default.name + "-core",
|
|
151
|
+
async config() {
|
|
152
|
+
for (const [name, source] of Object.entries(config.sources)) {
|
|
153
|
+
const resolved = resolveSource(source);
|
|
154
|
+
addVirtual(config, name, () => {
|
|
155
|
+
const cwd = posixPath(resolve("."));
|
|
156
|
+
return `export default { ${[...resolved].map(([scope, files]) => {
|
|
157
|
+
return `"${scope}": { ${[...files].map(([key, path]) => {
|
|
158
|
+
const entry = posixPath(relative(cwd, path));
|
|
159
|
+
return `"${key}": () => import("${entry.startsWith(".") ? entry : "./" + entry}").then((module) => module.default)`;
|
|
160
|
+
}).join(",")} }`;
|
|
161
|
+
}).join(",")} }`;
|
|
162
|
+
});
|
|
163
|
+
addTypes(config, name, () => {
|
|
164
|
+
const scopes = [...resolved].map(([scope, files]) => {
|
|
165
|
+
return `"${scope}":{ ${[...files].map(([key, path]) => `"${key}": () => Promise<typeof import("${posixPath(path)}").default>`).join(";")} }`;
|
|
166
|
+
});
|
|
167
|
+
return `declare module "#${name}" { type Entries = { ${scopes.join(";")} }; const entries: Entries; export default entries; }`;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
addVirtual(config, "variables", (consumer) => {
|
|
171
|
+
const variables = config.variables[consumer];
|
|
172
|
+
return `${Object.entries(variables).map(([name, variable]) => `export const ${name} = ${variable.default};`).join(" ")} export default ${JSON.stringify(variables)}`;
|
|
173
|
+
});
|
|
174
|
+
addTypes(config, "variables", () => {
|
|
175
|
+
const exports = /* @__PURE__ */ new Map();
|
|
176
|
+
for (const variables of Object.values(config.variables)) for (const [name, variable] of Object.entries(variables)) exports.set(name, `export const ${name}: InferVariableValue<${JSON.stringify(variable)}> | OptionalVariable<${JSON.stringify(variable)}>;`);
|
|
177
|
+
return `declare module "#variables" { import type { InferVariableValue, OptionalVariable } from "revojs/module"; ${[...exports.values()].join(" ")}; const entries: Record<string, Variable>; export default entries; }`;
|
|
178
|
+
});
|
|
179
|
+
addTemplate(config, "index.d.ts", () => {
|
|
180
|
+
return Object.keys(config.templates).reduce((content, name) => {
|
|
181
|
+
if (name.startsWith("types/")) content += `import "./${name}" \n`;
|
|
182
|
+
return content;
|
|
183
|
+
}, "");
|
|
184
|
+
});
|
|
185
|
+
return mergeObjects({ server: { watch: { ignored: [`**/.${package_default.name}/**`] } } }, config.vite);
|
|
186
|
+
},
|
|
187
|
+
async buildStart() {
|
|
188
|
+
const meta = resolve("." + package_default.name);
|
|
189
|
+
rmSync(meta, {
|
|
190
|
+
recursive: true,
|
|
191
|
+
force: true
|
|
192
|
+
});
|
|
193
|
+
for (const template in config.templates) {
|
|
194
|
+
const content = await config.templates[template](this.environment.config.consumer);
|
|
195
|
+
if (content) {
|
|
196
|
+
const path = join(meta, template);
|
|
197
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
198
|
+
writeFileSync(path, content);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
resolveId(key) {
|
|
203
|
+
if (key.startsWith("#") && key.slice(1) in config.virtuals) return `\0${key.slice(1)}`;
|
|
204
|
+
},
|
|
205
|
+
async load(key) {
|
|
206
|
+
if (key.startsWith("\0")) {
|
|
207
|
+
const virtual = config.virtuals[key.slice(1)];
|
|
208
|
+
return await virtual?.(this.environment.config.consumer);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}, config.vite.plugins];
|
|
212
|
+
}
|
|
213
|
+
async function module(inputConfig) {
|
|
214
|
+
const config = await createConfig(inputConfig);
|
|
215
|
+
const copiedFiles = new Set(resolvePaths(config.copy, "./src"));
|
|
216
|
+
const copiedExtensions = new Set([...copiedFiles].map((file) => extname(file)));
|
|
217
|
+
return [await core(config), {
|
|
218
|
+
name: package_default.name + "-module",
|
|
219
|
+
config() {
|
|
220
|
+
return {
|
|
221
|
+
builder: {
|
|
222
|
+
sharedConfigBuild: true,
|
|
223
|
+
async buildApp(builder) {
|
|
224
|
+
await builder.build(builder.environments.module);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
environments: { module: { build: { rolldownOptions: {
|
|
228
|
+
input: resolvePaths(["./src/**/*.*", "!./src/**/*.d.ts"]).filter((file) => !copiedFiles.has(file)),
|
|
229
|
+
external: (key) => !key.startsWith(".") && !isAbsolute(key) || key.startsWith("#") || copiedExtensions.has(extname(key)),
|
|
230
|
+
output: {
|
|
231
|
+
preserveModules: true,
|
|
232
|
+
preserveModulesRoot: resolve("src"),
|
|
233
|
+
sanitizeFileName: (name) => name.replace(/\0/g, "").replace(/\?.*$/, "")
|
|
234
|
+
}
|
|
235
|
+
} } } }
|
|
236
|
+
};
|
|
237
|
+
},
|
|
238
|
+
closeBundle() {
|
|
239
|
+
let path;
|
|
240
|
+
try {
|
|
241
|
+
path = join(dirname(createRequire(import.meta.url).resolve("typescript/package.json")), "lib", "tsc.js");
|
|
242
|
+
} catch {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
spawnSync(process.execPath, [
|
|
246
|
+
path,
|
|
247
|
+
"--noEmit",
|
|
248
|
+
"false",
|
|
249
|
+
"--declaration",
|
|
250
|
+
"--emitDeclarationOnly"
|
|
251
|
+
], { stdio: "inherit" });
|
|
252
|
+
for (const file of resolvePaths(config.copy, "./src")) {
|
|
253
|
+
const output = join(resolve("dist"), relative(resolve("src"), file));
|
|
254
|
+
mkdirSync(dirname(output), { recursive: true });
|
|
255
|
+
copyFileSync(file, output);
|
|
256
|
+
}
|
|
257
|
+
for (const file of resolvePaths("./src/**/*.d.ts")) {
|
|
258
|
+
const output = join(resolve("dist"), relative(resolve("src"), file));
|
|
259
|
+
mkdirSync(dirname(output), { recursive: true });
|
|
260
|
+
copyFileSync(file, output);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}];
|
|
264
|
+
}
|
|
265
|
+
async function revojs(inputConfig) {
|
|
266
|
+
const config = await createConfig(inputConfig);
|
|
267
|
+
return [await core(config), {
|
|
268
|
+
name: package_default.name,
|
|
269
|
+
config() {
|
|
270
|
+
return mergeObjects({
|
|
271
|
+
appType: config.modules.length === 0 ? "spa" : "custom",
|
|
272
|
+
builder: {
|
|
273
|
+
sharedConfigBuild: true,
|
|
274
|
+
async buildApp(builder) {
|
|
275
|
+
for (const environment of Object.values(builder.environments)) if (environment.config.consumer === "client") await builder.build(environment);
|
|
276
|
+
for (const environment of Object.values(builder.environments)) if (environment.config.consumer === "server") await builder.build(environment);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}, config.vite);
|
|
280
|
+
},
|
|
281
|
+
configResolved(viteConfig) {
|
|
282
|
+
addVirtual(config, "assets", () => {
|
|
283
|
+
const assets = new Array();
|
|
284
|
+
for (const key in viteConfig.environments) {
|
|
285
|
+
const environment = viteConfig.environments[key];
|
|
286
|
+
if (environment.consumer === "client") for (const path of resolvePaths("**/*", environment.build.outDir)) {
|
|
287
|
+
const meta = statSync(path);
|
|
288
|
+
const name = posixPath(relative(environment.build.outDir, path));
|
|
289
|
+
assets.push({
|
|
290
|
+
name,
|
|
291
|
+
type: mimeType(path),
|
|
292
|
+
relative: `./client/${name}`,
|
|
293
|
+
entityTag: `W/"${meta.size.toString(16)}-${Math.floor(meta.mtimeMs).toString(16)}"`,
|
|
294
|
+
lastModified: meta.mtime.toJSON(),
|
|
295
|
+
size: meta.size
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return `export default { ${assets.map((asset) => `"/${asset.name}": ${JSON.stringify(asset)}`).join(",")} }`;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}];
|
|
303
|
+
}
|
|
304
|
+
var PACKAGE_CACHE = /* @__PURE__ */ new Map();
|
|
305
|
+
//#endregion
|
|
306
|
+
export { addTemplate, addTypes, addVirtual, core, createConfig, defineCommand, defineModule, module, posixPath, resolvePaths, resolvePattern, resolveSource, revojs, useModule };
|