@runtime-env/vite-plugin 0.0.1 → 0.1.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/README.md +5 -5
- package/dist/build.js +22 -5
- package/dist/dev.js +40 -9
- package/dist/preview.js +30 -3
- package/dist/utils.d.ts +17 -1
- package/dist/utils.js +100 -2
- package/dist/vitest.d.ts +1 -0
- package/dist/vitest.js +49 -27
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -18,15 +18,15 @@ Before using the plugin, ensure you have the following prerequisites in your pro
|
|
|
18
18
|
{
|
|
19
19
|
"type": "object",
|
|
20
20
|
"properties": {
|
|
21
|
-
"
|
|
21
|
+
"VITE_API_URL": { "type": "string" }
|
|
22
22
|
},
|
|
23
|
-
"required": ["
|
|
23
|
+
"required": ["VITE_API_URL"]
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
2. **Provide local environment variables**
|
|
27
27
|
Create a `.env` (or `.env.local`, `.env.development`, etc.) file to provide values for development:
|
|
28
28
|
```env
|
|
29
|
-
|
|
29
|
+
VITE_API_URL=http://localhost:3000
|
|
30
30
|
```
|
|
31
31
|
3. **Load the runtime environment**
|
|
32
32
|
Add a `<script>` tag to your `index.html` **before** your main entry point to load the generated environment variables:
|
|
@@ -55,14 +55,14 @@ export default defineConfig({
|
|
|
55
55
|
|
|
56
56
|
```ts
|
|
57
57
|
// Variables are available globally
|
|
58
|
-
const apiUrl = runtimeEnv.
|
|
58
|
+
const apiUrl = runtimeEnv.VITE_API_URL;
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
**In `index.html` (Template Interpolation):**
|
|
62
62
|
|
|
63
63
|
```html
|
|
64
64
|
<!-- Use lodash-style templates -->
|
|
65
|
-
<script src="https://maps.googleapis.com/maps/api/js?key=<%= runtimeEnv.
|
|
65
|
+
<script src="https://maps.googleapis.com/maps/api/js?key=<%= runtimeEnv.VITE_GOOGLE_MAPS_API_KEY %>"></script>
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
That's it! The plugin automatically handles the following:
|
package/dist/build.js
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { isTypeScriptProject, runRuntimeEnvCommand } from "./utils.js";
|
|
1
|
+
import { isTypeScriptProject, runRuntimeEnvCommand, validateSchema, 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
|
+
apply: "build",
|
|
7
|
+
configResolved(resolvedConfig) {
|
|
8
|
+
config = resolvedConfig;
|
|
9
|
+
const validation = validateSchema(config.root, config.envPrefix);
|
|
10
|
+
if (!validation.success) {
|
|
11
|
+
logError(config.logger, "Schema validation failed", validation.message);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
if (isTypeScriptProject(config.root)) {
|
|
15
|
+
const result = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
16
|
+
if (!result.success) {
|
|
17
|
+
logError(config.logger, "Failed to generate runtime-env.d.ts", result.stderr || result.stdout);
|
|
18
|
+
process.exit(1);
|
|
9
19
|
}
|
|
10
20
|
}
|
|
11
21
|
},
|
|
22
|
+
transformIndexHtml(html) {
|
|
23
|
+
if (!hasRuntimeEnvScript(html, config.base)) {
|
|
24
|
+
logError(config.logger, `index.html is missing <script src="${config.base === "/" ? "" : config.base}/runtime-env.js"></script>. ` +
|
|
25
|
+
"This script tag is mandatory for @runtime-env/vite-plugin to function correctly in production.");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
12
29
|
};
|
|
13
30
|
}
|
package/dist/dev.js
CHANGED
|
@@ -1,22 +1,45 @@
|
|
|
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, validateSchema, logError, clearLastError, hasRuntimeEnvScript, } from "./utils.js";
|
|
4
4
|
const schemaFile = ".runtimeenvschema.json";
|
|
5
5
|
export function devPlugin() {
|
|
6
6
|
return {
|
|
7
7
|
name: "runtime-env-dev",
|
|
8
|
+
apply(config, { command, mode }) {
|
|
9
|
+
return command === "serve" && mode !== "test";
|
|
10
|
+
},
|
|
8
11
|
configureServer(server) {
|
|
9
|
-
if (server.config.mode === "test")
|
|
10
|
-
return;
|
|
11
12
|
const envDir = server.config.envDir || server.config.root;
|
|
12
13
|
const envFiles = getViteEnvFiles(server.config.mode, envDir);
|
|
13
|
-
const watchFiles = [schemaFile, ...envFiles];
|
|
14
|
+
const watchFiles = [resolve(server.config.root, schemaFile), ...envFiles];
|
|
15
|
+
let hadError = false;
|
|
14
16
|
function run() {
|
|
17
|
+
const validation = validateSchema(server.config.root, server.config.envPrefix);
|
|
18
|
+
if (!validation.success) {
|
|
19
|
+
logError(server.config.logger, "Schema validation failed", validation.message, server);
|
|
20
|
+
hadError = true;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (isTypeScriptProject(server.config.root)) {
|
|
24
|
+
const tsResult = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
25
|
+
if (!tsResult.success) {
|
|
26
|
+
logError(server.config.logger, "Failed to generate runtime-env.d.ts", tsResult.stderr || tsResult.stdout, server);
|
|
27
|
+
hadError = true;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
15
31
|
const devOutputDir = getTempDir("dev");
|
|
16
32
|
const devOutputPath = resolve(devOutputDir, "runtime-env.js");
|
|
17
|
-
runRuntimeEnvCommand("gen-js", devOutputPath, envFiles);
|
|
18
|
-
if (
|
|
19
|
-
|
|
33
|
+
const jsResult = runRuntimeEnvCommand("gen-js", devOutputPath, envFiles);
|
|
34
|
+
if (!jsResult.success) {
|
|
35
|
+
logError(server.config.logger, "Failed to generate runtime-env.js", jsResult.stderr || jsResult.stdout, server);
|
|
36
|
+
hadError = true;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (hadError) {
|
|
40
|
+
clearLastError();
|
|
41
|
+
server.ws.send({ type: "full-reload" });
|
|
42
|
+
hadError = false;
|
|
20
43
|
}
|
|
21
44
|
}
|
|
22
45
|
run();
|
|
@@ -43,14 +66,22 @@ export function devPlugin() {
|
|
|
43
66
|
});
|
|
44
67
|
},
|
|
45
68
|
transformIndexHtml(html, ctx) {
|
|
46
|
-
if (ctx.server
|
|
69
|
+
if (ctx.server) {
|
|
47
70
|
const envDir = ctx.server.config.envDir || ctx.server.config.root;
|
|
48
71
|
const envFiles = getViteEnvFiles(ctx.server.config.mode, envDir);
|
|
72
|
+
if (!hasRuntimeEnvScript(html, ctx.server.config.base)) {
|
|
73
|
+
logError(ctx.server.config.logger, `index.html is missing <script src="${ctx.server.config.base === "/" ? "" : ctx.server.config.base}/runtime-env.js"></script>. ` +
|
|
74
|
+
"Runtime values will not be available. Please add the script tag.", undefined, ctx.server);
|
|
75
|
+
}
|
|
49
76
|
const tmpDir = getTempDir("dev-interpolate");
|
|
50
77
|
try {
|
|
51
78
|
const htmlFile = resolve(tmpDir, "index.html");
|
|
52
79
|
writeFileSync(htmlFile, html, "utf8");
|
|
53
|
-
runRuntimeEnvCommand("interpolate", htmlFile, envFiles, htmlFile);
|
|
80
|
+
const result = runRuntimeEnvCommand("interpolate", htmlFile, envFiles, htmlFile);
|
|
81
|
+
if (!result.success) {
|
|
82
|
+
logError(ctx.server.config.logger, "Failed to interpolate index.html", result.stderr || result.stdout, ctx.server);
|
|
83
|
+
return html;
|
|
84
|
+
}
|
|
54
85
|
html = readFileSync(htmlFile, "utf8");
|
|
55
86
|
return html;
|
|
56
87
|
}
|
package/dist/preview.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
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, validateSchema, logError, } from "./utils.js";
|
|
4
4
|
export function previewPlugin() {
|
|
5
5
|
return {
|
|
6
6
|
name: "runtime-env-preview",
|
|
7
|
+
apply(config, { command }) {
|
|
8
|
+
// preview command also uses 'serve' but it's often better to just let it be
|
|
9
|
+
// and rely on the hook itself if we don't have a specific command.
|
|
10
|
+
// However, to be consistent with others:
|
|
11
|
+
return command === "serve";
|
|
12
|
+
},
|
|
7
13
|
configurePreviewServer(server) {
|
|
8
14
|
server.middlewares.use((req, res, next) => {
|
|
9
15
|
const base = server.config.base || "/";
|
|
@@ -21,10 +27,21 @@ export function previewPlugin() {
|
|
|
21
27
|
const envFiles = getViteEnvFiles(server.config.mode, envDir);
|
|
22
28
|
// Serve runtime-env.js
|
|
23
29
|
if (path === "/runtime-env.js") {
|
|
30
|
+
const validation = validateSchema(server.config.root, server.config.envPrefix);
|
|
31
|
+
if (!validation.success) {
|
|
32
|
+
logError(server.config.logger, "Schema validation failed", validation.message);
|
|
33
|
+
next();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
24
36
|
const tmpDir = getTempDir("preview-gen-js");
|
|
25
37
|
const tmpPath = resolve(tmpDir, "runtime-env.js");
|
|
26
38
|
try {
|
|
27
|
-
runRuntimeEnvCommand("gen-js", tmpPath, envFiles);
|
|
39
|
+
const result = runRuntimeEnvCommand("gen-js", tmpPath, envFiles);
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
logError(server.config.logger, "Failed to generate runtime-env.js", result.stderr || result.stdout);
|
|
42
|
+
next();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
28
45
|
if (existsSync(tmpPath)) {
|
|
29
46
|
const content = readFileSync(tmpPath, "utf8");
|
|
30
47
|
res.setHeader("Content-Type", "application/javascript");
|
|
@@ -38,6 +55,10 @@ export function previewPlugin() {
|
|
|
38
55
|
}
|
|
39
56
|
// Intercept index.html
|
|
40
57
|
if (path === "/" || path === "/index.html") {
|
|
58
|
+
const validation = validateSchema(server.config.root, server.config.envPrefix);
|
|
59
|
+
if (!validation.success) {
|
|
60
|
+
logError(server.config.logger, "Schema validation failed", validation.message);
|
|
61
|
+
}
|
|
41
62
|
const outDir = server.config.build.outDir || "dist";
|
|
42
63
|
const distIndexHtml = resolve(server.config.root, outDir, "index.html");
|
|
43
64
|
if (existsSync(distIndexHtml)) {
|
|
@@ -46,7 +67,13 @@ export function previewPlugin() {
|
|
|
46
67
|
const tmpHtmlPath = resolve(tmpDir, "index.html");
|
|
47
68
|
const originalHtml = readFileSync(distIndexHtml, "utf8");
|
|
48
69
|
writeFileSync(tmpHtmlPath, originalHtml, "utf8");
|
|
49
|
-
runRuntimeEnvCommand("interpolate", tmpHtmlPath, envFiles, tmpHtmlPath);
|
|
70
|
+
const result = runRuntimeEnvCommand("interpolate", tmpHtmlPath, envFiles, tmpHtmlPath);
|
|
71
|
+
if (!result.success) {
|
|
72
|
+
logError(server.config.logger, "Failed to interpolate index.html", result.stderr || result.stdout);
|
|
73
|
+
res.setHeader("Content-Type", "text/html");
|
|
74
|
+
res.end(originalHtml);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
50
77
|
const interpolatedHtml = readFileSync(tmpHtmlPath, "utf8");
|
|
51
78
|
res.setHeader("Content-Type", "text/html");
|
|
52
79
|
res.end(interpolatedHtml);
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
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;
|
|
8
|
+
export declare function validateSchema(root: string, envPrefix?: string | string[]): {
|
|
9
|
+
success: boolean;
|
|
10
|
+
message?: string;
|
|
11
|
+
};
|
|
1
12
|
export declare function isTypeScriptProject(root: string): boolean;
|
|
2
13
|
export declare function getViteEnvFiles(mode: string, envDir: string): string[];
|
|
3
14
|
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):
|
|
15
|
+
export declare function runRuntimeEnvCommand(command: string, outputFile: string, envFiles?: string[], inputFile?: string): {
|
|
16
|
+
success: boolean;
|
|
17
|
+
stdout: string;
|
|
18
|
+
stderr: string;
|
|
19
|
+
};
|
|
5
20
|
export declare function getTempDir(subDir: string): string;
|
|
21
|
+
export declare function hasRuntimeEnvScript(html: string, base: string): boolean;
|
package/dist/utils.js
CHANGED
|
@@ -1,10 +1,84 @@
|
|
|
1
|
-
import { existsSync, mkdirSync } from "fs";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync } from "fs";
|
|
2
2
|
import { resolve } from "path";
|
|
3
3
|
import { spawnSync } from "child_process";
|
|
4
4
|
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
|
+
}
|
|
53
|
+
export function validateSchema(root, envPrefix = "VITE_") {
|
|
54
|
+
const schemaPath = resolve(root, schemaFile);
|
|
55
|
+
if (!existsSync(schemaPath)) {
|
|
56
|
+
return { success: true };
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const schemaContent = readFileSync(schemaPath, "utf-8");
|
|
60
|
+
const schema = JSON.parse(schemaContent);
|
|
61
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
62
|
+
return { success: true }; // Let the CLI handle invalid schema format
|
|
63
|
+
}
|
|
64
|
+
const keys = Object.keys(schema.properties);
|
|
65
|
+
const prefixes = Array.isArray(envPrefix) ? envPrefix : [envPrefix];
|
|
66
|
+
const invalidKeys = keys.filter((key) => !prefixes.some((prefix) => key.startsWith(prefix)));
|
|
67
|
+
if (invalidKeys.length > 0) {
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
message: `The following keys in ${schemaFile} do not match any of the allowed env prefixes (${prefixes.join(", ")}): ${invalidKeys.join(", ")}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
message: `Failed to parse ${schemaFile}: ${error instanceof Error ? error.message : String(error)}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return { success: true };
|
|
81
|
+
}
|
|
8
82
|
export function isTypeScriptProject(root) {
|
|
9
83
|
return existsSync(resolve(root, "tsconfig.json"));
|
|
10
84
|
}
|
|
@@ -45,7 +119,12 @@ export function runRuntimeEnvCommand(command, outputFile, envFiles = [], inputFi
|
|
|
45
119
|
// Fallback to local node_modules/.bin if require.resolve fails (e.g. during development or in some monorepo setups)
|
|
46
120
|
cliPath = resolve("node_modules", ".bin", "runtime-env");
|
|
47
121
|
}
|
|
48
|
-
spawnSync("node", [cliPath, ...args]);
|
|
122
|
+
const result = spawnSync("node", [cliPath, ...args], { encoding: "utf8" });
|
|
123
|
+
return {
|
|
124
|
+
success: result.status === 0,
|
|
125
|
+
stdout: result.stdout,
|
|
126
|
+
stderr: result.stderr,
|
|
127
|
+
};
|
|
49
128
|
}
|
|
50
129
|
export function getTempDir(subDir) {
|
|
51
130
|
const root = process.cwd();
|
|
@@ -53,3 +132,22 @@ export function getTempDir(subDir) {
|
|
|
53
132
|
mkdirSync(tempDir, { recursive: true });
|
|
54
133
|
return tempDir;
|
|
55
134
|
}
|
|
135
|
+
export function hasRuntimeEnvScript(html, base) {
|
|
136
|
+
// Normalize base: ensure it starts with / and doesn't end with / (unless it's just /)
|
|
137
|
+
const normalizedBase = base.startsWith("/") ? base : `/${base}`;
|
|
138
|
+
const finalBase = normalizedBase.endsWith("/") && normalizedBase.length > 1
|
|
139
|
+
? normalizedBase.slice(0, -1)
|
|
140
|
+
: normalizedBase;
|
|
141
|
+
const expectedSrc = `${finalBase === "/" ? "" : finalBase}/runtime-env.js`;
|
|
142
|
+
// Regex to find script tag with src matching runtime-env.js
|
|
143
|
+
// It accounts for varying whitespace, attribute order, and quote types.
|
|
144
|
+
const scriptRegex = /<script\b[^>]*?\bsrc\s*=\s*(['"])([^'"]*\/runtime-env\.js)\1[^>]*?>\s*<\/script>/gi;
|
|
145
|
+
let match;
|
|
146
|
+
while ((match = scriptRegex.exec(html)) !== null) {
|
|
147
|
+
const src = match[2];
|
|
148
|
+
if (src === expectedSrc || src === "/runtime-env.js") {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
package/dist/vitest.d.ts
CHANGED
package/dist/vitest.js
CHANGED
|
@@ -1,38 +1,60 @@
|
|
|
1
|
+
import "vitest/config";
|
|
1
2
|
import { resolve } from "path";
|
|
2
3
|
import { rmSync } from "fs";
|
|
3
|
-
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, } from "./utils.js";
|
|
4
|
+
import { isTypeScriptProject, runRuntimeEnvCommand, getTempDir, getViteEnvFiles, validateSchema, logError, } from "./utils.js";
|
|
4
5
|
export function vitestPlugin() {
|
|
5
6
|
return {
|
|
6
7
|
name: "runtime-env-vitest",
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
// Automatically inject setupFiles for Vitest
|
|
24
|
-
const vitestConfig = config.test || {};
|
|
25
|
-
const setupFiles = vitestConfig.setupFiles || [];
|
|
26
|
-
if (Array.isArray(setupFiles)) {
|
|
8
|
+
apply(_config, { mode }) {
|
|
9
|
+
return mode === "test";
|
|
10
|
+
},
|
|
11
|
+
config(config) {
|
|
12
|
+
// Generate runtime-env.js for Vitest runtime access
|
|
13
|
+
const vitestOutputDir = getTempDir("vitest");
|
|
14
|
+
const vitestOutputPath = resolve(vitestOutputDir, "runtime-env.js");
|
|
15
|
+
// Automatically inject setupFiles for Vitest
|
|
16
|
+
const vitestConfig = config.test || {};
|
|
17
|
+
const setupFiles = vitestConfig.setupFiles || [];
|
|
18
|
+
if (Array.isArray(setupFiles)) {
|
|
19
|
+
if (!setupFiles.includes(vitestOutputPath)) {
|
|
27
20
|
setupFiles.push(vitestOutputPath);
|
|
28
21
|
}
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
vitestConfig.setupFiles = [setupFiles, vitestOutputPath];
|
|
25
|
+
}
|
|
26
|
+
config.test = {
|
|
27
|
+
...vitestConfig,
|
|
28
|
+
setupFiles,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
configResolved(config) {
|
|
32
|
+
const root = config.root || process.cwd();
|
|
33
|
+
const validation = validateSchema(root, config.envPrefix);
|
|
34
|
+
if (!validation.success) {
|
|
35
|
+
logError(config.logger, "Schema validation failed", validation.message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Generate runtime-env.d.ts for Vitest type checking
|
|
39
|
+
if (isTypeScriptProject(root)) {
|
|
40
|
+
const result = runRuntimeEnvCommand("gen-ts", "src/runtime-env.d.ts");
|
|
41
|
+
if (!result.success) {
|
|
42
|
+
logError(config.logger, "Failed to generate runtime-env.d.ts", result.stderr || result.stdout);
|
|
43
|
+
process.exit(1);
|
|
31
44
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
}
|
|
46
|
+
const envDir = config.envDir || root;
|
|
47
|
+
const envFiles = getViteEnvFiles(config.mode, envDir);
|
|
48
|
+
// Generate runtime-env.js for Vitest runtime access
|
|
49
|
+
const vitestOutputDir = getTempDir("vitest");
|
|
50
|
+
const vitestOutputPath = resolve(vitestOutputDir, "runtime-env.js");
|
|
51
|
+
// Ensure directory is clean
|
|
52
|
+
rmSync(vitestOutputDir, { recursive: true, force: true });
|
|
53
|
+
getTempDir("vitest"); // Re-create it clean
|
|
54
|
+
const result = runRuntimeEnvCommand("gen-js", vitestOutputPath, envFiles);
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
logError(config.logger, "Failed to generate runtime-env.js", result.stderr || result.stdout);
|
|
57
|
+
process.exit(1);
|
|
36
58
|
}
|
|
37
59
|
},
|
|
38
60
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtime-env/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Opinionated Vite plugin for runtime-env",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ernest",
|
|
@@ -34,14 +34,20 @@
|
|
|
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
|
"peerDependencies": {
|
|
39
38
|
"@runtime-env/cli": "*",
|
|
40
|
-
"vite": "
|
|
39
|
+
"vite": "7.3.1",
|
|
40
|
+
"vitest": "4.0.17"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"vitest": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
41
46
|
},
|
|
42
47
|
"devDependencies": {
|
|
43
48
|
"@runtime-env/cli": "^1.0.0",
|
|
44
|
-
"vite": "7.3.
|
|
49
|
+
"vite": "7.3.1",
|
|
50
|
+
"vitest": "4.0.17"
|
|
45
51
|
},
|
|
46
52
|
"type": "module"
|
|
47
53
|
}
|