@runtime-env/vite-plugin 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.js +20 -5
- package/dist/dev.js +29 -5
- package/dist/preview.js +14 -3
- package/dist/utils.d.ts +13 -1
- package/dist/utils.js +70 -1
- package/dist/vitest.js +28 -13
- package/package.json +6 -3
package/dist/build.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import { isTypeScriptProject, runRuntimeEnvCommand } from "./utils.js";
|
|
1
|
+
import { isTypeScriptProject, runRuntimeEnvCommand, logError, hasRuntimeEnvScript, } from "./utils.js";
|
|
2
2
|
export function buildPlugin() {
|
|
3
|
+
let config;
|
|
3
4
|
return {
|
|
4
5
|
name: "runtime-env-build",
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
configResolved(resolvedConfig) {
|
|
7
|
+
config = resolvedConfig;
|
|
8
|
+
if (config.command === "build") {
|
|
9
|
+
if (isTypeScriptProject(config.root)) {
|
|
10
|
+
const result = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
11
|
+
if (!result.success) {
|
|
12
|
+
logError(config.logger, "Failed to generate runtime-env.d.ts", result.stderr || result.stdout);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
transformIndexHtml(html) {
|
|
19
|
+
if (config && config.command === "build") {
|
|
20
|
+
if (!hasRuntimeEnvScript(html, config.base)) {
|
|
21
|
+
logError(config.logger, `index.html is missing <script src="${config.base === "/" ? "" : config.base}/runtime-env.js"></script>. ` +
|
|
22
|
+
"This script tag is mandatory for @runtime-env/vite-plugin to function correctly in production.");
|
|
23
|
+
process.exit(1);
|
|
9
24
|
}
|
|
10
25
|
}
|
|
11
26
|
},
|
package/dist/dev.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
2
|
import { writeFileSync, readFileSync, rmSync, existsSync } from "fs";
|
|
3
|
-
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, } from "./utils.js";
|
|
3
|
+
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, logError, clearLastError, hasRuntimeEnvScript, } from "./utils.js";
|
|
4
4
|
const schemaFile = ".runtimeenvschema.json";
|
|
5
5
|
export function devPlugin() {
|
|
6
6
|
return {
|
|
@@ -10,13 +10,29 @@ export function devPlugin() {
|
|
|
10
10
|
return;
|
|
11
11
|
const envDir = server.config.envDir || server.config.root;
|
|
12
12
|
const envFiles = getViteEnvFiles(server.config.mode, envDir);
|
|
13
|
-
const watchFiles = [schemaFile, ...envFiles];
|
|
13
|
+
const watchFiles = [resolve(server.config.root, schemaFile), ...envFiles];
|
|
14
|
+
let hadError = false;
|
|
14
15
|
function run() {
|
|
15
16
|
const devOutputDir = getTempDir("dev");
|
|
16
17
|
const devOutputPath = resolve(devOutputDir, "runtime-env.js");
|
|
17
|
-
runRuntimeEnvCommand("gen-js", devOutputPath, envFiles);
|
|
18
|
+
const jsResult = runRuntimeEnvCommand("gen-js", devOutputPath, envFiles);
|
|
19
|
+
if (!jsResult.success) {
|
|
20
|
+
logError(server.config.logger, "Failed to generate runtime-env.js", jsResult.stderr || jsResult.stdout, server);
|
|
21
|
+
hadError = true;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
18
24
|
if (isTypeScriptProject(server.config.root)) {
|
|
19
|
-
runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
25
|
+
const tsResult = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
26
|
+
if (!tsResult.success) {
|
|
27
|
+
logError(server.config.logger, "Failed to generate runtime-env.d.ts", tsResult.stderr || tsResult.stdout, server);
|
|
28
|
+
hadError = true;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (hadError) {
|
|
33
|
+
clearLastError();
|
|
34
|
+
server.ws.send({ type: "full-reload" });
|
|
35
|
+
hadError = false;
|
|
20
36
|
}
|
|
21
37
|
}
|
|
22
38
|
run();
|
|
@@ -46,11 +62,19 @@ export function devPlugin() {
|
|
|
46
62
|
if (ctx.server && ctx.server.config.command === "serve") {
|
|
47
63
|
const envDir = ctx.server.config.envDir || ctx.server.config.root;
|
|
48
64
|
const envFiles = getViteEnvFiles(ctx.server.config.mode, envDir);
|
|
65
|
+
if (!hasRuntimeEnvScript(html, ctx.server.config.base)) {
|
|
66
|
+
logError(ctx.server.config.logger, `index.html is missing <script src="${ctx.server.config.base === "/" ? "" : ctx.server.config.base}/runtime-env.js"></script>. ` +
|
|
67
|
+
"Runtime values will not be available. Please add the script tag.", undefined, ctx.server);
|
|
68
|
+
}
|
|
49
69
|
const tmpDir = getTempDir("dev-interpolate");
|
|
50
70
|
try {
|
|
51
71
|
const htmlFile = resolve(tmpDir, "index.html");
|
|
52
72
|
writeFileSync(htmlFile, html, "utf8");
|
|
53
|
-
runRuntimeEnvCommand("interpolate", htmlFile, envFiles, htmlFile);
|
|
73
|
+
const result = runRuntimeEnvCommand("interpolate", htmlFile, envFiles, htmlFile);
|
|
74
|
+
if (!result.success) {
|
|
75
|
+
logError(ctx.server.config.logger, "Failed to interpolate index.html", result.stderr || result.stdout, ctx.server);
|
|
76
|
+
return html;
|
|
77
|
+
}
|
|
54
78
|
html = readFileSync(htmlFile, "utf8");
|
|
55
79
|
return html;
|
|
56
80
|
}
|
package/dist/preview.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
2
|
import { readFileSync, writeFileSync, existsSync, rmSync } from "fs";
|
|
3
|
-
import { runRuntimeEnvCommand, getTempDir, getViteEnvFiles } from "./utils.js";
|
|
3
|
+
import { runRuntimeEnvCommand, getTempDir, getViteEnvFiles, logError, } from "./utils.js";
|
|
4
4
|
export function previewPlugin() {
|
|
5
5
|
return {
|
|
6
6
|
name: "runtime-env-preview",
|
|
@@ -24,7 +24,12 @@ export function previewPlugin() {
|
|
|
24
24
|
const tmpDir = getTempDir("preview-gen-js");
|
|
25
25
|
const tmpPath = resolve(tmpDir, "runtime-env.js");
|
|
26
26
|
try {
|
|
27
|
-
runRuntimeEnvCommand("gen-js", tmpPath, envFiles);
|
|
27
|
+
const result = runRuntimeEnvCommand("gen-js", tmpPath, envFiles);
|
|
28
|
+
if (!result.success) {
|
|
29
|
+
logError(server.config.logger, "Failed to generate runtime-env.js", result.stderr || result.stdout);
|
|
30
|
+
next();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
28
33
|
if (existsSync(tmpPath)) {
|
|
29
34
|
const content = readFileSync(tmpPath, "utf8");
|
|
30
35
|
res.setHeader("Content-Type", "application/javascript");
|
|
@@ -46,7 +51,13 @@ export function previewPlugin() {
|
|
|
46
51
|
const tmpHtmlPath = resolve(tmpDir, "index.html");
|
|
47
52
|
const originalHtml = readFileSync(distIndexHtml, "utf8");
|
|
48
53
|
writeFileSync(tmpHtmlPath, originalHtml, "utf8");
|
|
49
|
-
runRuntimeEnvCommand("interpolate", tmpHtmlPath, envFiles, tmpHtmlPath);
|
|
54
|
+
const result = runRuntimeEnvCommand("interpolate", tmpHtmlPath, envFiles, tmpHtmlPath);
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
logError(server.config.logger, "Failed to interpolate index.html", result.stderr || result.stdout);
|
|
57
|
+
res.setHeader("Content-Type", "text/html");
|
|
58
|
+
res.end(originalHtml);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
50
61
|
const interpolatedHtml = readFileSync(tmpHtmlPath, "utf8");
|
|
51
62
|
res.setHeader("Content-Type", "text/html");
|
|
52
63
|
res.end(interpolatedHtml);
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
import type { Logger, ViteDevServer } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Clears the last error message to allow it to be logged again.
|
|
4
|
+
* This should be called when the plugin recovers from an error state.
|
|
5
|
+
*/
|
|
6
|
+
export declare function clearLastError(): void;
|
|
7
|
+
export declare function logError(logger: Logger | undefined, message: string, error?: any, server?: ViteDevServer): void;
|
|
1
8
|
export declare function isTypeScriptProject(root: string): boolean;
|
|
2
9
|
export declare function getViteEnvFiles(mode: string, envDir: string): string[];
|
|
3
10
|
export declare function getRuntimeEnvCommandLineArgs(command: string, outputFile: string, envFiles?: string[], inputFile?: string): string[];
|
|
4
|
-
export declare function runRuntimeEnvCommand(command: string, outputFile: string, envFiles?: string[], inputFile?: string):
|
|
11
|
+
export declare function runRuntimeEnvCommand(command: string, outputFile: string, envFiles?: string[], inputFile?: string): {
|
|
12
|
+
success: boolean;
|
|
13
|
+
stdout: string;
|
|
14
|
+
stderr: string;
|
|
15
|
+
};
|
|
5
16
|
export declare function getTempDir(subDir: string): string;
|
|
17
|
+
export declare function hasRuntimeEnvScript(html: string, base: string): boolean;
|
package/dist/utils.js
CHANGED
|
@@ -5,6 +5,51 @@ import { createRequire } from "module";
|
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
const schemaFile = ".runtimeenvschema.json";
|
|
7
7
|
const globalVariableName = "runtimeEnv";
|
|
8
|
+
let lastErrorMessage = null;
|
|
9
|
+
/**
|
|
10
|
+
* Clears the last error message to allow it to be logged again.
|
|
11
|
+
* This should be called when the plugin recovers from an error state.
|
|
12
|
+
*/
|
|
13
|
+
export function clearLastError() {
|
|
14
|
+
lastErrorMessage = null;
|
|
15
|
+
}
|
|
16
|
+
export function logError(logger, message, error, server) {
|
|
17
|
+
const prefix = "[@runtime-env/vite-plugin]";
|
|
18
|
+
const fullMessage = `${prefix} ${message}`;
|
|
19
|
+
const errorDetails = error
|
|
20
|
+
? typeof error === "string"
|
|
21
|
+
? error
|
|
22
|
+
: error instanceof Error
|
|
23
|
+
? error.message
|
|
24
|
+
: JSON.stringify(error)
|
|
25
|
+
: "";
|
|
26
|
+
const completeErrorMessage = errorDetails
|
|
27
|
+
? `${fullMessage}\n${errorDetails}`
|
|
28
|
+
: fullMessage;
|
|
29
|
+
if (completeErrorMessage !== lastErrorMessage) {
|
|
30
|
+
if (!logger) {
|
|
31
|
+
console.error(fullMessage);
|
|
32
|
+
if (error)
|
|
33
|
+
console.error(errorDetails);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
logger.error(fullMessage, { timestamp: true });
|
|
37
|
+
if (error) {
|
|
38
|
+
logger.error(errorDetails, { timestamp: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
lastErrorMessage = completeErrorMessage;
|
|
42
|
+
}
|
|
43
|
+
if (server) {
|
|
44
|
+
server.ws.send({
|
|
45
|
+
type: "error",
|
|
46
|
+
err: {
|
|
47
|
+
message: completeErrorMessage,
|
|
48
|
+
stack: "",
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
8
53
|
export function isTypeScriptProject(root) {
|
|
9
54
|
return existsSync(resolve(root, "tsconfig.json"));
|
|
10
55
|
}
|
|
@@ -45,7 +90,12 @@ export function runRuntimeEnvCommand(command, outputFile, envFiles = [], inputFi
|
|
|
45
90
|
// Fallback to local node_modules/.bin if require.resolve fails (e.g. during development or in some monorepo setups)
|
|
46
91
|
cliPath = resolve("node_modules", ".bin", "runtime-env");
|
|
47
92
|
}
|
|
48
|
-
spawnSync("node", [cliPath, ...args]);
|
|
93
|
+
const result = spawnSync("node", [cliPath, ...args], { encoding: "utf8" });
|
|
94
|
+
return {
|
|
95
|
+
success: result.status === 0,
|
|
96
|
+
stdout: result.stdout,
|
|
97
|
+
stderr: result.stderr,
|
|
98
|
+
};
|
|
49
99
|
}
|
|
50
100
|
export function getTempDir(subDir) {
|
|
51
101
|
const root = process.cwd();
|
|
@@ -53,3 +103,22 @@ export function getTempDir(subDir) {
|
|
|
53
103
|
mkdirSync(tempDir, { recursive: true });
|
|
54
104
|
return tempDir;
|
|
55
105
|
}
|
|
106
|
+
export function hasRuntimeEnvScript(html, base) {
|
|
107
|
+
// Normalize base: ensure it starts with / and doesn't end with / (unless it's just /)
|
|
108
|
+
const normalizedBase = base.startsWith("/") ? base : `/${base}`;
|
|
109
|
+
const finalBase = normalizedBase.endsWith("/") && normalizedBase.length > 1
|
|
110
|
+
? normalizedBase.slice(0, -1)
|
|
111
|
+
: normalizedBase;
|
|
112
|
+
const expectedSrc = `${finalBase === "/" ? "" : finalBase}/runtime-env.js`;
|
|
113
|
+
// Regex to find script tag with src matching runtime-env.js
|
|
114
|
+
// It accounts for varying whitespace, attribute order, and quote types.
|
|
115
|
+
const scriptRegex = /<script\b[^>]*?\bsrc\s*=\s*(['"])([^'"]*\/runtime-env\.js)\1[^>]*?>\s*<\/script>/gi;
|
|
116
|
+
let match;
|
|
117
|
+
while ((match = scriptRegex.exec(html)) !== null) {
|
|
118
|
+
const src = match[2];
|
|
119
|
+
if (src === expectedSrc || src === "/runtime-env.js") {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
package/dist/vitest.js
CHANGED
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
2
|
import { rmSync } from "fs";
|
|
3
|
-
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, } from "./utils.js";
|
|
3
|
+
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, logError, } from "./utils.js";
|
|
4
4
|
export function vitestPlugin() {
|
|
5
5
|
return {
|
|
6
6
|
name: "runtime-env-vitest",
|
|
7
7
|
config(config, configEnv) {
|
|
8
|
-
if (config.mode === "test") {
|
|
9
|
-
const root = config.root || process.cwd();
|
|
10
|
-
// Generate runtime-env.d.ts for Vitest type checking
|
|
11
|
-
if (isTypeScriptProject(root)) {
|
|
12
|
-
runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
13
|
-
}
|
|
14
|
-
const envDir = config.envDir || root;
|
|
15
|
-
const envFiles = getViteEnvFiles(config.mode, envDir);
|
|
8
|
+
if (config.mode === "test" || configEnv.mode === "test") {
|
|
16
9
|
// Generate runtime-env.js for Vitest runtime access
|
|
17
10
|
const vitestOutputDir = getTempDir("vitest");
|
|
18
11
|
const vitestOutputPath = resolve(vitestOutputDir, "runtime-env.js");
|
|
19
|
-
// Ensure directory is clean
|
|
20
|
-
rmSync(vitestOutputDir, { recursive: true, force: true });
|
|
21
|
-
getTempDir("vitest"); // Re-create it clean
|
|
22
|
-
runRuntimeEnvCommand("gen-js", vitestOutputPath, envFiles);
|
|
23
12
|
// Automatically inject setupFiles for Vitest
|
|
24
13
|
const vitestConfig = config.test || {};
|
|
25
14
|
const setupFiles = vitestConfig.setupFiles || [];
|
|
@@ -35,5 +24,31 @@ export function vitestPlugin() {
|
|
|
35
24
|
};
|
|
36
25
|
}
|
|
37
26
|
},
|
|
27
|
+
configResolved(config) {
|
|
28
|
+
if (config.mode === "test") {
|
|
29
|
+
const root = config.root || process.cwd();
|
|
30
|
+
// Generate runtime-env.d.ts for Vitest type checking
|
|
31
|
+
if (isTypeScriptProject(root)) {
|
|
32
|
+
const result = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
33
|
+
if (!result.success) {
|
|
34
|
+
logError(config.logger, "Failed to generate runtime-env.d.ts", result.stderr || result.stdout);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const envDir = config.envDir || root;
|
|
39
|
+
const envFiles = getViteEnvFiles(config.mode, envDir);
|
|
40
|
+
// Generate runtime-env.js for Vitest runtime access
|
|
41
|
+
const vitestOutputDir = getTempDir("vitest");
|
|
42
|
+
const vitestOutputPath = resolve(vitestOutputDir, "runtime-env.js");
|
|
43
|
+
// Ensure directory is clean
|
|
44
|
+
rmSync(vitestOutputDir, { recursive: true, force: true });
|
|
45
|
+
getTempDir("vitest"); // Re-create it clean
|
|
46
|
+
const result = runRuntimeEnvCommand("gen-js", vitestOutputPath, envFiles);
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
logError(config.logger, "Failed to generate runtime-env.js", result.stderr || result.stdout);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
38
53
|
};
|
|
39
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtime-env/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Opinionated Vite plugin for runtime-env",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ernest",
|
|
@@ -34,10 +34,13 @@
|
|
|
34
34
|
"url": "https://github.com/runtime-env/runtime-env/issues"
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/runtime-env/runtime-env#readme",
|
|
37
|
-
"dependencies": {
|
|
38
|
-
|
|
37
|
+
"dependencies": {},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@runtime-env/cli": "*",
|
|
40
|
+
"vite": "*"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
43
|
+
"@runtime-env/cli": "^1.0.0",
|
|
41
44
|
"vite": "7.3.0"
|
|
42
45
|
},
|
|
43
46
|
"type": "module"
|