nuxt-safe-runtime-config 0.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 onmax
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/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # Nuxt Safe Runtime Config
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![Nuxt][nuxt-src]][nuxt-href]
7
+
8
+ Validate Nuxt runtime config at build time using **Zod**, **Valibot**, **ArkType**, or any Standard Schema compatible library.
9
+
10
+ - [✨  Release Notes](/CHANGELOG.md)
11
+
12
+ ## Features
13
+
14
+ - 🔒  Validate runtime config at build time with **Zod**, **Valibot**, **ArkType**, and more
15
+ - 🚀  Works with any [Standard Schema](https://standardschema.dev/) compatible library
16
+ - 🛠  Only runs during dev/build/generate phases
17
+ - ⚡  Zero runtime overhead - validation happens at build time only
18
+ - 📝  Does not modify your runtime config or types - only validates them
19
+
20
+ ## Quick Setup
21
+
22
+ Install the module to your Nuxt application with one command:
23
+
24
+ ```bash
25
+ npx nuxi module add nuxt-safe-runtime-config
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ 1. Add the module to your `nuxt.config.ts`:
31
+
32
+ ```typescript
33
+ export default defineNuxtConfig({
34
+ modules: ['nuxt-safe-runtime-config']
35
+ })
36
+ ```
37
+
38
+ 2. Define your runtime config schema using **Valibot**, **Zod**, **ArkType**, or any other Standard Schema compatible library:
39
+
40
+ ### With Valibot
41
+
42
+ ```typescript
43
+ import { number, object, optional, string } from 'valibot'
44
+
45
+ const runtimeConfigSchema = object({
46
+ public: object({
47
+ apiBase: string(),
48
+ appName: optional(string()),
49
+ }),
50
+ databaseUrl: string(),
51
+ secretKey: string(),
52
+ port: optional(number()),
53
+ })
54
+ ```
55
+
56
+ ### With Zod
57
+
58
+ ```typescript
59
+ import { z } from 'zod'
60
+
61
+ const runtimeConfigSchema = z.object({
62
+ public: z.object({
63
+ apiBase: z.string(),
64
+ appName: z.string().optional(),
65
+ }),
66
+ databaseUrl: z.string(),
67
+ secretKey: z.string(),
68
+ port: z.number().optional(),
69
+ })
70
+ ```
71
+
72
+ ### With ArkType
73
+
74
+ ```typescript
75
+ import { type } from 'arktype'
76
+
77
+ const runtimeConfigSchema = type({
78
+ 'public': {
79
+ 'apiBase': 'string',
80
+ 'appName?': 'string'
81
+ },
82
+ 'databaseUrl': 'string',
83
+ 'secretKey': 'string',
84
+ 'port?': 'number'
85
+ })
86
+ ```
87
+
88
+ 3. Configure your Nuxt app:
89
+
90
+ ```typescript
91
+ export default defineNuxtConfig({
92
+ modules: ['nuxt-safe-runtime-config'],
93
+
94
+ // Your regular runtime config
95
+ runtimeConfig: {
96
+ databaseUrl: process.env.DATABASE_URL || 'postgresql://localhost:5432/mydb',
97
+ secretKey: process.env.SECRET_KEY || 'default-secret-key',
98
+ port: Number.parseInt(process.env.PORT || '3000'),
99
+ public: {
100
+ apiBase: process.env.PUBLIC_API_BASE || 'https://api.example.com',
101
+ appName: 'My Nuxt App',
102
+ },
103
+ },
104
+
105
+ // Add your schema for validation
106
+ safeRuntimeConfig: {
107
+ $schema: runtimeConfigSchema,
108
+ },
109
+ })
110
+ ```
111
+
112
+ The module will validate your runtime config against the schema during:
113
+
114
+ - `nuxi dev` (development mode)
115
+ - `nuxi build`
116
+ - `nuxi generate`
117
+
118
+ If validation fails, the build process will stop with detailed error messages.
119
+
120
+ ## Important Notes
121
+
122
+ **This module only validates your runtime config - it does not modify it.** Your native `runtimeConfig` remains unchanged, and no TypeScript types are modified. The module simply ensures that your runtime configuration matches your schema at build time, helping you catch configuration errors early in the development process.
123
+
124
+ ## Error Messages
125
+
126
+ When validation fails, you'll see detailed error messages like:
127
+
128
+ ```
129
+ Safe Runtime Config: Validation failed!
130
+ 1. databaseUrl: This field is required
131
+ 2. public.apiBase: Expected string, received undefined
132
+ 3. port: Expected number, received string
133
+ ```
134
+
135
+ The module will stop the build process until all validation errors are resolved.
136
+
137
+ ## Why This Module?
138
+
139
+ I wanted to use **Valibot** for runtime config validation, but Nuxt doesn't currently support Standard Schema. While Nuxt has its own schema validation system, it's primarily designed for module authors and broader Nuxt configuration.
140
+
141
+ This module focuses specifically on **runtime config validation** using the Standard Schema specification, allowing you to use your preferred validation library (Valibot, Zod, ArkType, etc.).
142
+
143
+ The goal is to eventually make Standard Schema a first-class citizen in Nuxt. If this module gains enough adoption, I plan to create a PR to add `standardSchema` support to Nuxt core.
144
+
145
+ ## Contribution
146
+
147
+ <details>
148
+ <summary>Local development</summary>
149
+
150
+ ```bash
151
+ # Install dependencies
152
+ pnpm install
153
+
154
+ # Generate type stubs
155
+ pnpm run dev:prepare
156
+
157
+ # Develop with the playground
158
+ pnpm run dev
159
+
160
+ # Build the playground
161
+ pnpm run dev:build
162
+
163
+ # Run ESLint
164
+ pnpm run lint
165
+
166
+ # Run Vitest
167
+ pnpm run test
168
+ pnpm run test:watch
169
+
170
+ # Release new version
171
+ pnpm run release
172
+ ```
173
+
174
+ </details>
175
+
176
+ <!-- Badges -->
177
+
178
+ [npm-version-src]: https://img.shields.io/npm/v/nuxt-safe-runtime-config/latest.svg?style=flat&colorA=020420&colorB=00DC82
179
+ [npm-version-href]: https://npmjs.com/package/nuxt-safe-runtime-config
180
+ [npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-safe-runtime-config.svg?style=flat&colorA=020420&colorB=00DC82
181
+ [npm-downloads-href]: https://npm.chart.dev/nuxt-safe-runtime-config
182
+ [license-src]: https://img.shields.io/npm/l/nuxt-safe-runtime-config.svg?style=flat&colorA=020420&colorB=00DC82
183
+ [license-href]: https://npmjs.com/package/nuxt-safe-runtime-config
184
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
185
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,10 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { StandardSchemaV1 } from '@standard-schema/spec';
3
+
4
+ interface ModuleOptions {
5
+ $schema: StandardSchemaV1;
6
+ }
7
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
8
+
9
+ export { _default as default };
10
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "nuxt-safe-runtime-config",
3
+ "configKey": "safeRuntimeConfig",
4
+ "version": "0.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.1",
7
+ "unbuild": "3.5.0"
8
+ }
9
+ }
@@ -0,0 +1,59 @@
1
+ import { defineNuxtModule } from '@nuxt/kit';
2
+ import { consola } from 'consola';
3
+
4
+ const module = defineNuxtModule({
5
+ meta: {
6
+ name: "nuxt-safe-runtime-config",
7
+ configKey: "safeRuntimeConfig"
8
+ },
9
+ defaults: {
10
+ $schema: void 0
11
+ // No default schema, users must provide their own
12
+ },
13
+ setup(options, nuxt) {
14
+ if (!options.$schema)
15
+ return;
16
+ if (nuxt.options.dev) {
17
+ nuxt.hook("modules:done", async () => {
18
+ await validateRuntimeConfig(nuxt, options);
19
+ });
20
+ return;
21
+ }
22
+ nuxt.hook("build:done", async () => {
23
+ await validateRuntimeConfig(nuxt, options);
24
+ });
25
+ }
26
+ });
27
+ async function validateRuntimeConfig(nuxt, options) {
28
+ const schemaConfig = options.$schema;
29
+ if (!schemaConfig)
30
+ return;
31
+ try {
32
+ const runtimeConfig = nuxt.options.runtimeConfig || {};
33
+ if (!isStandardSchema(schemaConfig)) {
34
+ consola.error("Safe Runtime Config: Schema is not Standard Schema compatible");
35
+ return;
36
+ }
37
+ const result = await schemaConfig["~standard"].validate(runtimeConfig);
38
+ if ("issues" in result && result.issues && result.issues.length > 0) {
39
+ consola.error("Safe Runtime Config: Validation failed!");
40
+ result.issues.forEach((issue, index) => {
41
+ consola.error(` ${index + 1}. ${formatIssue(issue)}`);
42
+ });
43
+ throw new Error("Runtime config validation failed");
44
+ }
45
+ consola.success("Validated Runtime Config");
46
+ } catch (error) {
47
+ consola.error("Safe Runtime Config: Validation error:", error);
48
+ throw error;
49
+ }
50
+ }
51
+ function isStandardSchema(schema) {
52
+ return schema && typeof schema === "object" && "~standard" in schema && typeof schema["~standard"] === "object" && typeof schema["~standard"].validate === "function";
53
+ }
54
+ function formatIssue(issue) {
55
+ const path = issue.path ? issue.path.map((p) => p.key || p).join(".") : "root";
56
+ return `${path}: ${issue.message || "Validation error"}`;
57
+ }
58
+
59
+ export { module as default };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ export default defineNuxtPlugin((_nuxtApp) => {
3
+ });
@@ -0,0 +1,3 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "nuxt-safe-runtime-config",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "description": "Validate Nuxt runtime config with Standard Schema at build time",
6
+ "author": {
7
+ "name": "onmax"
8
+ },
9
+ "license": "MIT",
10
+ "repository": "onmax/nuxt-safe-runtime-config",
11
+ "keywords": [
12
+ "nuxt",
13
+ "nuxt-module",
14
+ "runtime-config",
15
+ "validation",
16
+ "standard-schema",
17
+ "valibot",
18
+ "zod",
19
+ "arktype",
20
+ "build-time"
21
+ ],
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/types.d.mts",
25
+ "import": "./dist/module.mjs"
26
+ }
27
+ },
28
+ "main": "./dist/module.mjs",
29
+ "typesVersions": {
30
+ "*": {
31
+ ".": [
32
+ "./dist/types.d.mts"
33
+ ]
34
+ }
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "dependencies": {
40
+ "@nuxt/kit": "^3.17.4",
41
+ "@standard-schema/spec": "^1.0.0",
42
+ "consola": "^3.4.2"
43
+ },
44
+ "devDependencies": {
45
+ "@antfu/eslint-config": "^4.13.3",
46
+ "@antfu/ni": "^25.0.0",
47
+ "@nuxt/devtools": "^2.4.1",
48
+ "@nuxt/eslint": "^1.4.1",
49
+ "@nuxt/eslint-config": "^1.4.1",
50
+ "@nuxt/module-builder": "^1.0.1",
51
+ "@nuxt/schema": "^3.17.4",
52
+ "@nuxt/test-utils": "^3.19.1",
53
+ "@types/node": "latest",
54
+ "bumpp": "^10.1.1",
55
+ "changelogen": "^0.6.1",
56
+ "eslint": "^9.28.0",
57
+ "eslint-plugin-format": "^1.0.1",
58
+ "lint-staged": "^16.1.0",
59
+ "nuxt": "^3.17.4",
60
+ "simple-git-hooks": "^2.13.0",
61
+ "typescript": "~5.8.3",
62
+ "valibot": "^1.1.0",
63
+ "vitest": "^3.2.0",
64
+ "vue-tsc": "^2.2.10"
65
+ },
66
+ "simple-git-hooks": {
67
+ "pre-commit": "pnpm lint-staged"
68
+ },
69
+ "lint-staged": {
70
+ "*": "eslint --fix"
71
+ },
72
+ "scripts": {
73
+ "dev": "nuxi dev playground",
74
+ "dev:build": "nuxi build playground",
75
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && pnpm -C test/fixtures/validation-failure prepare && pnpm -C test/fixtures/validation-success prepare",
76
+ "release": "nr lint && nr typecheck && nr test && nr prepack && bumpp && pnpm publish",
77
+ "typecheck": "nuxt typecheck && pnpm -C playground typecheck",
78
+ "lint": "eslint .",
79
+ "lint:fix": "eslint . --fix",
80
+ "test": "vitest run",
81
+ "test:watch": "vitest watch",
82
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
83
+ }
84
+ }