@model-w/preset-nuxt3 0.1.8 → 1.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/README.md +1 -1
- package/index.ts +261 -0
- package/package.json +34 -32
- package/.env-template +0 -21
- package/nuxt.config.ts +0 -54
package/README.md
CHANGED
package/index.ts
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import { defineNuxtConfig } from "nuxt/config";
|
|
3
|
+
import { defu } from "defu";
|
|
4
|
+
import type { NuxtConfig } from "nuxt/schema";
|
|
5
|
+
import type { ModuleOptions as SentryOptions } from "@model-w/sentry";
|
|
6
|
+
import type { ModuleOptions as ProxyOptions } from "@model-w/proxy";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Signature of calls to EnvManager to avoid inconsistent calls to the same
|
|
10
|
+
* var.
|
|
11
|
+
*/
|
|
12
|
+
type Signature = {
|
|
13
|
+
defaultValue: any;
|
|
14
|
+
buildDefault: any;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when a required env var is missing.
|
|
19
|
+
*/
|
|
20
|
+
class ImproperlyConfigured extends Error {
|
|
21
|
+
constructor(message: string) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "ImproperlyConfigured";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* This helps keeping track of environment variables that are used, mandatory,
|
|
29
|
+
* etc.
|
|
30
|
+
*/
|
|
31
|
+
class EnvManager {
|
|
32
|
+
private getSignatures: Record<string, Signature> = {};
|
|
33
|
+
private signatureMismatch: Set<string> = new Set();
|
|
34
|
+
private inBuildMode: boolean = JSON.parse(
|
|
35
|
+
process.env.BUILD_MODE || "false"
|
|
36
|
+
);
|
|
37
|
+
private missing: Set<string> = new Set();
|
|
38
|
+
private read: Record<string, { isRequired: boolean }> = {};
|
|
39
|
+
private syntaxError: Set<string> = new Set();
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Gets an environment variable
|
|
43
|
+
*
|
|
44
|
+
* @param name Name of the variable
|
|
45
|
+
* @param defaultValue Default value, if any
|
|
46
|
+
* @param buildDefault Default value when building to avoid an error to be
|
|
47
|
+
* raised
|
|
48
|
+
*/
|
|
49
|
+
get({
|
|
50
|
+
name,
|
|
51
|
+
defaultValue,
|
|
52
|
+
buildDefault,
|
|
53
|
+
}: {
|
|
54
|
+
name: string;
|
|
55
|
+
defaultValue?: any;
|
|
56
|
+
buildDefault?: any;
|
|
57
|
+
}): any {
|
|
58
|
+
const signature = { defaultValue, buildDefault };
|
|
59
|
+
|
|
60
|
+
if (this.getSignatures.hasOwnProperty(name)) {
|
|
61
|
+
if (
|
|
62
|
+
signature.defaultValue !==
|
|
63
|
+
this.getSignatures[name].defaultValue ||
|
|
64
|
+
signature.buildDefault !== this.getSignatures[name].buildDefault
|
|
65
|
+
) {
|
|
66
|
+
this.signatureMismatch.add(name);
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
this.getSignatures[name] = signature;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const currentDefault =
|
|
73
|
+
this.inBuildMode && buildDefault !== undefined
|
|
74
|
+
? buildDefault
|
|
75
|
+
: defaultValue;
|
|
76
|
+
|
|
77
|
+
this.read[name] = {
|
|
78
|
+
isRequired: currentDefault === undefined,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if (typeof process.env[name] === "undefined") {
|
|
82
|
+
if (currentDefault === undefined) {
|
|
83
|
+
this.missing.add(name);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return currentDefault;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return process.env[name];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Checks for any missing var or inconsistency in order to nicely warn
|
|
94
|
+
* the user.
|
|
95
|
+
*/
|
|
96
|
+
raiseParseFail(): void {
|
|
97
|
+
if (
|
|
98
|
+
this.get({
|
|
99
|
+
name: "NO_ENV_CHECK",
|
|
100
|
+
defaultValue: false,
|
|
101
|
+
buildDefault: false,
|
|
102
|
+
})
|
|
103
|
+
) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
!this.missing.size &&
|
|
109
|
+
!this.syntaxError.size &&
|
|
110
|
+
!this.signatureMismatch.size
|
|
111
|
+
) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const parts: string[] = ["Incorrect environment variables."];
|
|
116
|
+
|
|
117
|
+
if (this.missing.size) {
|
|
118
|
+
parts.push(` Missing: ${Array.from(this.missing).join(", ")}.`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.syntaxError.size) {
|
|
122
|
+
parts.push(
|
|
123
|
+
` Syntax error: ${Array.from(this.syntaxError).join(", ")}.`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.signatureMismatch.size) {
|
|
128
|
+
parts.push(
|
|
129
|
+
` get() calls mismatch: ${Array.from(
|
|
130
|
+
this.signatureMismatch
|
|
131
|
+
).join(", ")}.`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
throw new ImproperlyConfigured(parts.join(""));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface ModelWConfig {
|
|
140
|
+
siteName?: string;
|
|
141
|
+
apiUrl?: string;
|
|
142
|
+
runtimeConfig?: Extract<NuxtConfig, "runtimeConfig">;
|
|
143
|
+
sentryDsn?: string;
|
|
144
|
+
environment?: string;
|
|
145
|
+
app?: Extract<NuxtConfig, "app">;
|
|
146
|
+
head?: Extract<Extract<NuxtConfig, "app">, "head">;
|
|
147
|
+
moduleConfig?: Array<any>;
|
|
148
|
+
backAlias?: string;
|
|
149
|
+
cmsAlias?: string;
|
|
150
|
+
proxyFilters?: Array<any>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Context manager that checks env consistency at the end
|
|
155
|
+
*
|
|
156
|
+
* @param func Function to call. The return value will be propagated
|
|
157
|
+
*/
|
|
158
|
+
export function envManager<T>(func: (env: EnvManager) => T): T {
|
|
159
|
+
const env = new EnvManager();
|
|
160
|
+
const out = func(env);
|
|
161
|
+
|
|
162
|
+
env.raiseParseFail();
|
|
163
|
+
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Define a Nuxt config with Model W defaults
|
|
169
|
+
*
|
|
170
|
+
* @param env Env manager (from the envManager context manager)
|
|
171
|
+
* @param config Your config
|
|
172
|
+
*/
|
|
173
|
+
export function defineModelWConfig(
|
|
174
|
+
env: EnvManager,
|
|
175
|
+
config: ModelWConfig
|
|
176
|
+
): NuxtConfig {
|
|
177
|
+
const siteName = config.siteName || "Model W";
|
|
178
|
+
const head: Extract<Extract<NuxtConfig, "app">, "head"> = defu(
|
|
179
|
+
config.head || {},
|
|
180
|
+
{
|
|
181
|
+
titleTemplate: `%s - ${siteName}`,
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
const app: Extract<NuxtConfig, "app"> = defu(config.app || {}, {
|
|
185
|
+
head,
|
|
186
|
+
});
|
|
187
|
+
const apiUrl =
|
|
188
|
+
config.apiUrl ||
|
|
189
|
+
env.get({ name: "API_URL", buildDefault: "http://localhost" });
|
|
190
|
+
|
|
191
|
+
const backAlias = config.backAlias || "back";
|
|
192
|
+
const cmsAlias = config.cmsAlias || "wubba-lubba-dub-dub";
|
|
193
|
+
|
|
194
|
+
const previewEditRegex = new RegExp(
|
|
195
|
+
`^/${cmsAlias}/pages/[^/]+/edit/preview/$`
|
|
196
|
+
);
|
|
197
|
+
const previewAddRegex = new RegExp(
|
|
198
|
+
`^/${cmsAlias}/pages/add/[^/]+/[^/]+/[^/]+/preview/$`
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const sentryDsn =
|
|
202
|
+
config.sentryDsn || env.get({ name: "SENTRY_DSN", defaultValue: "" });
|
|
203
|
+
const environment =
|
|
204
|
+
config.environment ||
|
|
205
|
+
env.get({
|
|
206
|
+
name: "ENVIRONMENT",
|
|
207
|
+
defaultValue: sentryDsn ? undefined : "",
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const generatedConfig: NuxtConfig = {
|
|
211
|
+
app,
|
|
212
|
+
|
|
213
|
+
runtimeConfig: defu(config.runtimeConfig || {}, {
|
|
214
|
+
apiUrl,
|
|
215
|
+
}),
|
|
216
|
+
|
|
217
|
+
proxy: {
|
|
218
|
+
options: {
|
|
219
|
+
target: apiUrl,
|
|
220
|
+
changeOrigin: true,
|
|
221
|
+
},
|
|
222
|
+
forwardHost: true,
|
|
223
|
+
filters: [
|
|
224
|
+
{
|
|
225
|
+
header: /x-reach-api:.+/,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
path: `/${backAlias}`,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
path: `/${cmsAlias}`,
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
path: previewEditRegex,
|
|
235
|
+
method: /^(?!POST$).*/,
|
|
236
|
+
useProxy: false,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
path: previewAddRegex,
|
|
240
|
+
method: /^(?!POST$).*/,
|
|
241
|
+
useProxy: false,
|
|
242
|
+
},
|
|
243
|
+
...(config.proxyFilters || []),
|
|
244
|
+
],
|
|
245
|
+
} as ProxyOptions,
|
|
246
|
+
|
|
247
|
+
sentry: {
|
|
248
|
+
dsn: sentryDsn,
|
|
249
|
+
environment: environment,
|
|
250
|
+
} as SentryOptions,
|
|
251
|
+
|
|
252
|
+
modules: [
|
|
253
|
+
"@model-w/axios",
|
|
254
|
+
"@model-w/sentry",
|
|
255
|
+
"@model-w/proxy",
|
|
256
|
+
...(config.moduleConfig || []),
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
return defineNuxtConfig(generatedConfig);
|
|
261
|
+
}
|
package/package.json
CHANGED
|
@@ -1,50 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@model-w/preset-nuxt3",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Preset of Nuxt3 for ModelW",
|
|
6
|
+
"license": "WTFPL",
|
|
4
7
|
"repository": {
|
|
5
8
|
"type": "git",
|
|
6
9
|
"url": "git+https://github.com/ModelW/preset-nuxt3.git"
|
|
7
10
|
},
|
|
11
|
+
"homepage": "https://github.com/ModelW/preset-nuxt3#readme",
|
|
8
12
|
"bugs": {
|
|
9
13
|
"url": "https://github.com/ModelW/preset-nuxt3/issues"
|
|
10
14
|
},
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
15
|
+
"author": "Rémy Sanchez (@xowap)",
|
|
16
|
+
"contributors": [
|
|
17
|
+
"Laurent Treguier",
|
|
18
|
+
"Ivan Lorenzo"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"nuxt3",
|
|
22
|
+
"nuxt3-preset",
|
|
23
|
+
"model-w",
|
|
24
|
+
"modelw"
|
|
25
|
+
],
|
|
26
|
+
"main": "index.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"index.ts",
|
|
29
|
+
"README.md",
|
|
30
|
+
"package.json"
|
|
31
|
+
],
|
|
14
32
|
"scripts": {
|
|
15
33
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
16
34
|
},
|
|
17
35
|
"engines": {
|
|
18
|
-
"node": "
|
|
36
|
+
"node": "18.x"
|
|
19
37
|
},
|
|
20
38
|
"peerDependencies": {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
39
|
+
"@model-w/axios": "0.x || 1.x",
|
|
40
|
+
"@model-w/proxy": "0.x || 1.x",
|
|
41
|
+
"@model-w/sentry": "1.x",
|
|
42
|
+
"@vuelidate/core": "2.0.x",
|
|
43
|
+
"@vuelidate/validators": "2.0.x",
|
|
44
|
+
"nuxt": "3.4.x",
|
|
45
|
+
"sass": "1.62.x",
|
|
46
|
+
"vite-svg-loader": "4.0.x",
|
|
47
|
+
"vue": "3.2.x"
|
|
23
48
|
},
|
|
24
49
|
"dependencies": {
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"@model-w/sentry": "~0.1.1",
|
|
28
|
-
"@vuelidate/core": "~2.0.2",
|
|
29
|
-
"@vuelidate/validators": "~2.0.2",
|
|
30
|
-
"defu": "~6.1.2",
|
|
31
|
-
"jsdom": "~21.1.1",
|
|
32
|
-
"nuxt-runtime-compiler": "~1.2.2",
|
|
33
|
-
"vite-svg-loader": "~4.0.0",
|
|
34
|
-
"vue3-toastify": "~0.1.6",
|
|
35
|
-
"sass": "~1.62.0",
|
|
36
|
-
"sass-loader": "~13.2.2"
|
|
37
|
-
},
|
|
38
|
-
"keywords": [
|
|
39
|
-
"Nuxt3",
|
|
40
|
-
"modelw",
|
|
41
|
-
"model-w",
|
|
42
|
-
"Nuxt3-preset"
|
|
43
|
-
],
|
|
44
|
-
"author": "Rémy Sanchez (@xowap)",
|
|
45
|
-
"license": "WTFPL",
|
|
46
|
-
"contributors": [
|
|
47
|
-
"Laurent Treguier",
|
|
48
|
-
"Ivan Lorenzo"
|
|
49
|
-
]
|
|
50
|
+
"defu": "^6.1.2"
|
|
51
|
+
}
|
|
50
52
|
}
|
package/.env-template
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
set -a
|
|
2
|
-
|
|
3
|
-
# Base frontend configuration:
|
|
4
|
-
# Frontend desired URL for example "localhost:3000"
|
|
5
|
-
BASE_URL="http://localhost:3000"
|
|
6
|
-
|
|
7
|
-
# Backend URL location for example "localhost:8000"
|
|
8
|
-
API_URL="http://localhost:8000"
|
|
9
|
-
|
|
10
|
-
# Proxy configuration stuff
|
|
11
|
-
BACK_ALIAS="back"
|
|
12
|
-
CMS_ALIAS="cms"
|
|
13
|
-
|
|
14
|
-
# Template config
|
|
15
|
-
NUXT_PUBLIC_SERVER_TEMPLATED_COMPONENTS=true
|
|
16
|
-
|
|
17
|
-
# Site name
|
|
18
|
-
SITE_NAME="Model W"
|
|
19
|
-
|
|
20
|
-
# Sentry configuration dsn url
|
|
21
|
-
SENTRY_DSN="https://<number>.ingest.sentry.io/<number>"
|
package/nuxt.config.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export interface ModelWConfig {
|
|
2
|
-
siteName?: string;
|
|
3
|
-
apiURL?: string;
|
|
4
|
-
sentryDSN?: string;
|
|
5
|
-
ENV?: string;
|
|
6
|
-
charset?: string;
|
|
7
|
-
meta?: Array<any>;
|
|
8
|
-
moduleConfig?: Array<any>;
|
|
9
|
-
backAlias?: string;
|
|
10
|
-
cmsAlias?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function defineModelWConfig(config: ModelWConfig) {
|
|
14
|
-
return defineNuxtConfig({
|
|
15
|
-
app: {
|
|
16
|
-
head: {
|
|
17
|
-
titleTemplate: config.siteName,
|
|
18
|
-
},
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
meta: config.meta,
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
routeRules: {
|
|
24
|
-
'/': {
|
|
25
|
-
prerender: true,
|
|
26
|
-
cors: true
|
|
27
|
-
},
|
|
28
|
-
'/*': {
|
|
29
|
-
cors: true
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
runtimeConfig: {
|
|
34
|
-
apiURL: config.apiURL,
|
|
35
|
-
backAlias: config.backAlias,
|
|
36
|
-
cmsAlias: config.cmsAlias,
|
|
37
|
-
public: {
|
|
38
|
-
sentryDSN: config.sentryDSN,
|
|
39
|
-
serverTemplatedComponents: false,
|
|
40
|
-
},
|
|
41
|
-
ENV: config.ENV,
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
build: {},
|
|
45
|
-
|
|
46
|
-
modules: [
|
|
47
|
-
"nuxt-runtime-compiler",
|
|
48
|
-
"@model-w/axios",
|
|
49
|
-
"@model-w/sentry",
|
|
50
|
-
"@model-w/proxy",
|
|
51
|
-
...(config.moduleConfig ? config.moduleConfig : []),
|
|
52
|
-
]
|
|
53
|
-
})
|
|
54
|
-
}
|