nuxt-spec 0.4.0-alpha.2 → 0.4.0-alpha.3
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 +21 -21
- package/README.md +13 -13
- package/app/app.vue +10 -10
- package/app/components/NuxtSpecApiTestComponent.vue +24 -24
- package/app/components/NuxtSpecTestComponent.vue +9 -9
- package/app/components/index.d.ts +7 -7
- package/app/components/index.ts +2 -2
- package/app/utils/vitest-utils.ts +5 -5
- package/config/index.d.ts +36 -36
- package/config/index.mjs +147 -147
- package/config/report/report-entry.html +6 -6
- package/config/report/report-head.html +34 -34
- package/config/report/report-screenshot.html +8 -8
- package/config/report/report-tail.html +4 -4
- package/config/templates/.github/workflows/ci-test-update.yml.template +105 -105
- package/config/templates/.github/workflows/ci-test-verify.yml.template +68 -68
- package/config/templates/.gitlab/ci/ci-test-update.yml.template +69 -69
- package/config/templates/.gitlab/ci/ci-test-verify.yml.template +41 -41
- package/config/templates/.gitlab-ci.yml.template +6 -6
- package/config/templates/pnpm-workspace.yaml.template +19 -19
- package/config/templates/vitest.config.ts.template +5 -5
- package/config/utils/merge.mjs +43 -43
- package/config/utils/options.d.mts +59 -59
- package/config/utils/options.mjs +116 -116
- package/config/utils/reporter.mjs +409 -409
- package/config/utils/warnings.mjs +38 -38
- package/modules/spec-options.ts +23 -23
- package/nuxt.config.ts +20 -20
- package/package.json +17 -23
- package/utils/e2e.ts +131 -131
- package/utils/helpers/check-params.ts +44 -44
- package/utils/helpers/location-hint.ts +30 -30
- package/utils/helpers/screenshot-utils.ts +27 -27
- package/utils/index.ts +12 -12
- package/utils/playwright.ts +28 -28
- package/utils/screenshot.ts +201 -201
- package/bin/_internal/prepublish-check.js +0 -16
- package/bin/cli.js +0 -53
- package/bin/commands/ci.js +0 -124
- package/bin/commands/setup.js +0 -367
- package/bin/commands/update.js +0 -126
- package/bin/helpers/commands.js +0 -82
- package/bin/helpers/constants.js +0 -8
- package/bin/helpers/git.js +0 -73
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { loadVitestConfig } from 'nuxt-spec/config'
|
|
2
|
-
|
|
3
|
-
export default loadVitestConfig({
|
|
4
|
-
// custom config here
|
|
5
|
-
})
|
|
1
|
+
import { loadVitestConfig } from 'nuxt-spec/config'
|
|
2
|
+
|
|
3
|
+
export default loadVitestConfig({
|
|
4
|
+
// custom config here
|
|
5
|
+
})
|
package/config/utils/merge.mjs
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
// custom merger function based on defu
|
|
2
|
-
// allows working with the "projects" array properly
|
|
3
|
-
// user-defined config overrides are merged by "name"
|
|
4
|
-
|
|
5
|
-
// for consistent and predictable results, passing "include" or "browser.instances"
|
|
6
|
-
// will result in OVERRIDE instead of merging with nuxt-spec defaults
|
|
7
|
-
|
|
8
|
-
import { createDefu } from 'defu'
|
|
9
|
-
|
|
10
|
-
// in real Vitest config, "name" is nested inside another "test" object
|
|
11
|
-
const getProjectName = project => project?.name ?? project?.test?.name
|
|
12
|
-
|
|
13
|
-
export const mergeConfig = createDefu((obj, key, value) => {
|
|
14
|
-
if (key === 'projects' && Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
15
|
-
const defaults = obj[key]
|
|
16
|
-
const overrides = value
|
|
17
|
-
|
|
18
|
-
// override default values if user-defined config specifies them
|
|
19
|
-
obj[key] = defaults.map((defaultProject) => {
|
|
20
|
-
const override = overrides.find(o => getProjectName(o) === getProjectName(defaultProject))
|
|
21
|
-
return override ? mergeProject(override, defaultProject) : defaultProject
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// add any user projects that don't exist in defaults
|
|
25
|
-
for (const override of overrides) {
|
|
26
|
-
if (!defaults.some(d => getProjectName(d) === getProjectName(override))) {
|
|
27
|
-
obj[key].push(override)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return true
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
// Keys where user value should fully replace the default, not merge
|
|
36
|
-
const overrideKeys = new Set(['include', 'instances'])
|
|
37
|
-
|
|
38
|
-
const mergeProject = createDefu((obj, key, value) => {
|
|
39
|
-
if (overrideKeys.has(key)) {
|
|
40
|
-
obj[key] = value
|
|
41
|
-
return true
|
|
42
|
-
}
|
|
43
|
-
})
|
|
1
|
+
// custom merger function based on defu
|
|
2
|
+
// allows working with the "projects" array properly
|
|
3
|
+
// user-defined config overrides are merged by "name"
|
|
4
|
+
|
|
5
|
+
// for consistent and predictable results, passing "include" or "browser.instances"
|
|
6
|
+
// will result in OVERRIDE instead of merging with nuxt-spec defaults
|
|
7
|
+
|
|
8
|
+
import { createDefu } from 'defu'
|
|
9
|
+
|
|
10
|
+
// in real Vitest config, "name" is nested inside another "test" object
|
|
11
|
+
const getProjectName = project => project?.name ?? project?.test?.name
|
|
12
|
+
|
|
13
|
+
export const mergeConfig = createDefu((obj, key, value) => {
|
|
14
|
+
if (key === 'projects' && Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
15
|
+
const defaults = obj[key]
|
|
16
|
+
const overrides = value
|
|
17
|
+
|
|
18
|
+
// override default values if user-defined config specifies them
|
|
19
|
+
obj[key] = defaults.map((defaultProject) => {
|
|
20
|
+
const override = overrides.find(o => getProjectName(o) === getProjectName(defaultProject))
|
|
21
|
+
return override ? mergeProject(override, defaultProject) : defaultProject
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// add any user projects that don't exist in defaults
|
|
25
|
+
for (const override of overrides) {
|
|
26
|
+
if (!defaults.some(d => getProjectName(d) === getProjectName(override))) {
|
|
27
|
+
obj[key].push(override)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Keys where user value should fully replace the default, not merge
|
|
36
|
+
const overrideKeys = new Set(['include', 'instances'])
|
|
37
|
+
|
|
38
|
+
const mergeProject = createDefu((obj, key, value) => {
|
|
39
|
+
if (overrideKeys.has(key)) {
|
|
40
|
+
obj[key] = value
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
})
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
export type HtmlReportOpenMode = 'always' | 'failed' | 'never'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Nuxt Spec options set via `spec` key in nuxt.config.ts.
|
|
5
|
-
* Each option can also be set via respective NUXT_SPEC_* env variable,
|
|
6
|
-
* which takes precedence over the value from nuxt.config.ts.
|
|
7
|
-
*/
|
|
8
|
-
export interface NuxtSpecOptions {
|
|
9
|
-
/**
|
|
10
|
-
* Include `@nuxt/hints` module.
|
|
11
|
-
* Env: `NUXT_SPEC_HINTS_ENABLED`
|
|
12
|
-
* @default true
|
|
13
|
-
*/
|
|
14
|
-
hints?: boolean
|
|
15
|
-
/**
|
|
16
|
-
* WebSocket endpoint of an external Playwright server used by `e2e` and `browser` projects.
|
|
17
|
-
* Env: `NUXT_SPEC_EXTERNAL_PLAYWRIGHT`
|
|
18
|
-
*/
|
|
19
|
-
externalPlaywright?: string
|
|
20
|
-
/** HTML test report settings */
|
|
21
|
-
htmlReport?: {
|
|
22
|
-
/**
|
|
23
|
-
* Generate HTML report after each test run.
|
|
24
|
-
* Env: `NUXT_SPEC_HTML_REPORT`
|
|
25
|
-
* @default true
|
|
26
|
-
*/
|
|
27
|
-
enabled?: boolean
|
|
28
|
-
/**
|
|
29
|
-
* When to open the report in the default browser.
|
|
30
|
-
* Env: `NUXT_SPEC_HTML_REPORT_OPEN`
|
|
31
|
-
* @default 'failed'
|
|
32
|
-
*/
|
|
33
|
-
open?: HtmlReportOpenMode
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Plain text patterns of log messages that should be omitted.
|
|
37
|
-
* Env: `NUXT_SPEC_MESSAGE_FILTERS` (comma-separated, added to values from nuxt.config.ts)
|
|
38
|
-
*/
|
|
39
|
-
messageFilters?: string[]
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface ResolvedNuxtSpecOptions {
|
|
43
|
-
hints: boolean
|
|
44
|
-
externalPlaywright: string | undefined
|
|
45
|
-
htmlReport: {
|
|
46
|
-
enabled: boolean
|
|
47
|
-
open: HtmlReportOpenMode
|
|
48
|
-
}
|
|
49
|
-
messageFilters: string[]
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export declare const NUXT_SPEC_DEFAULTS: ResolvedNuxtSpecOptions
|
|
53
|
-
|
|
54
|
-
export declare function resolveSpecOptions(
|
|
55
|
-
fromConfig?: NuxtSpecOptions | false | null,
|
|
56
|
-
env?: Record<string, string | undefined>,
|
|
57
|
-
): ResolvedNuxtSpecOptions
|
|
58
|
-
|
|
59
|
-
export declare function loadSpecOptions(cwd?: string): Promise<ResolvedNuxtSpecOptions>
|
|
1
|
+
export type HtmlReportOpenMode = 'always' | 'failed' | 'never'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Nuxt Spec options set via `spec` key in nuxt.config.ts.
|
|
5
|
+
* Each option can also be set via respective NUXT_SPEC_* env variable,
|
|
6
|
+
* which takes precedence over the value from nuxt.config.ts.
|
|
7
|
+
*/
|
|
8
|
+
export interface NuxtSpecOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Include `@nuxt/hints` module.
|
|
11
|
+
* Env: `NUXT_SPEC_HINTS_ENABLED`
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
hints?: boolean
|
|
15
|
+
/**
|
|
16
|
+
* WebSocket endpoint of an external Playwright server used by `e2e` and `browser` projects.
|
|
17
|
+
* Env: `NUXT_SPEC_EXTERNAL_PLAYWRIGHT`
|
|
18
|
+
*/
|
|
19
|
+
externalPlaywright?: string
|
|
20
|
+
/** HTML test report settings */
|
|
21
|
+
htmlReport?: {
|
|
22
|
+
/**
|
|
23
|
+
* Generate HTML report after each test run.
|
|
24
|
+
* Env: `NUXT_SPEC_HTML_REPORT`
|
|
25
|
+
* @default true
|
|
26
|
+
*/
|
|
27
|
+
enabled?: boolean
|
|
28
|
+
/**
|
|
29
|
+
* When to open the report in the default browser.
|
|
30
|
+
* Env: `NUXT_SPEC_HTML_REPORT_OPEN`
|
|
31
|
+
* @default 'failed'
|
|
32
|
+
*/
|
|
33
|
+
open?: HtmlReportOpenMode
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Plain text patterns of log messages that should be omitted.
|
|
37
|
+
* Env: `NUXT_SPEC_MESSAGE_FILTERS` (comma-separated, added to values from nuxt.config.ts)
|
|
38
|
+
*/
|
|
39
|
+
messageFilters?: string[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ResolvedNuxtSpecOptions {
|
|
43
|
+
hints: boolean
|
|
44
|
+
externalPlaywright: string | undefined
|
|
45
|
+
htmlReport: {
|
|
46
|
+
enabled: boolean
|
|
47
|
+
open: HtmlReportOpenMode
|
|
48
|
+
}
|
|
49
|
+
messageFilters: string[]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export declare const NUXT_SPEC_DEFAULTS: ResolvedNuxtSpecOptions
|
|
53
|
+
|
|
54
|
+
export declare function resolveSpecOptions(
|
|
55
|
+
fromConfig?: NuxtSpecOptions | false | null,
|
|
56
|
+
env?: Record<string, string | undefined>,
|
|
57
|
+
): ResolvedNuxtSpecOptions
|
|
58
|
+
|
|
59
|
+
export declare function loadSpecOptions(cwd?: string): Promise<ResolvedNuxtSpecOptions>
|
package/config/utils/options.mjs
CHANGED
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
// Nuxt Spec options resolution
|
|
2
|
-
// - values can be set via `spec` key in nuxt.config.ts or via NUXT_SPEC_* env variables
|
|
3
|
-
// - precedence: env variables > nuxt.config.ts > defaults
|
|
4
|
-
|
|
5
|
-
import { loadNuxtConfig } from 'nuxt/kit'
|
|
6
|
-
|
|
7
|
-
export const NUXT_SPEC_DEFAULTS = {
|
|
8
|
-
hints: true,
|
|
9
|
-
externalPlaywright: undefined,
|
|
10
|
-
htmlReport: {
|
|
11
|
-
enabled: true,
|
|
12
|
-
open: 'failed',
|
|
13
|
-
},
|
|
14
|
-
messageFilters: [],
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const HTML_REPORT_OPEN_MODES = ['always', 'failed', 'never']
|
|
18
|
-
|
|
19
|
-
// raw `spec` values per cwd - nuxt.config.ts is only loaded once
|
|
20
|
-
const specCache = new Map()
|
|
21
|
-
|
|
22
|
-
// options are resolved by both the Nuxt module and the Vitest config in the same process
|
|
23
|
-
const reportedWarnings = new Set()
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Resolve final Nuxt Spec options.
|
|
27
|
-
* @param {import('./options.d.mts').NuxtSpecOptions | false | null} [fromConfig] - `spec` key from nuxt.config.ts
|
|
28
|
-
* @param {Record<string, string | undefined>} [env] - env variables
|
|
29
|
-
* @returns {import('./options.d.mts').ResolvedNuxtSpecOptions}
|
|
30
|
-
*/
|
|
31
|
-
export function resolveSpecOptions(fromConfig, env = process.env) {
|
|
32
|
-
const config = isObject(fromConfig) ? fromConfig : {}
|
|
33
|
-
const htmlReport = checkType('htmlReport', config.htmlReport, 'object') ?? {}
|
|
34
|
-
return {
|
|
35
|
-
hints: toBoolean(env.NUXT_SPEC_HINTS_ENABLED)
|
|
36
|
-
?? checkType('hints', config.hints, 'boolean')
|
|
37
|
-
?? NUXT_SPEC_DEFAULTS.hints,
|
|
38
|
-
externalPlaywright: env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
|
|
39
|
-
|| checkType('externalPlaywright', config.externalPlaywright, 'string')
|
|
40
|
-
|| NUXT_SPEC_DEFAULTS.externalPlaywright,
|
|
41
|
-
htmlReport: {
|
|
42
|
-
enabled: toBoolean(env.NUXT_SPEC_HTML_REPORT)
|
|
43
|
-
?? checkType('htmlReport.enabled', htmlReport.enabled, 'boolean')
|
|
44
|
-
?? NUXT_SPEC_DEFAULTS.htmlReport.enabled,
|
|
45
|
-
open: env.NUXT_SPEC_HTML_REPORT_OPEN
|
|
46
|
-
? toOpenMode('NUXT_SPEC_HTML_REPORT_OPEN', env.NUXT_SPEC_HTML_REPORT_OPEN)
|
|
47
|
-
: toOpenMode('htmlReport.open', htmlReport.open),
|
|
48
|
-
},
|
|
49
|
-
messageFilters: [
|
|
50
|
-
...(checkType('messageFilters', config.messageFilters, 'array') ?? []),
|
|
51
|
-
...(env.NUXT_SPEC_MESSAGE_FILTERS?.split(',') ?? []),
|
|
52
|
-
]
|
|
53
|
-
.filter((f) => {
|
|
54
|
-
if (typeof f === 'string') return true
|
|
55
|
-
warnInvalid('messageFilters', f, 'string', 'Value is ignored.')
|
|
56
|
-
return false
|
|
57
|
-
})
|
|
58
|
-
.map(f => f.trim())
|
|
59
|
-
// empty pattern would match (and swallow) every message
|
|
60
|
-
.filter(Boolean),
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Load `spec` key from nuxt.config.ts (including extended layers)
|
|
66
|
-
* and resolve final Nuxt Spec options.
|
|
67
|
-
* @param {string} [cwd] - directory with nuxt.config.ts
|
|
68
|
-
* @returns {Promise<import('./options.d.mts').ResolvedNuxtSpecOptions>}
|
|
69
|
-
*/
|
|
70
|
-
export async function loadSpecOptions(cwd = process.cwd()) {
|
|
71
|
-
if (!specCache.has(cwd)) {
|
|
72
|
-
specCache.set(cwd, loadNuxtConfig({ cwd })
|
|
73
|
-
.then(config => config.spec)
|
|
74
|
-
.catch((error) => {
|
|
75
|
-
console.warn(`[Nuxt Spec] Failed to read \`spec\` options from nuxt.config: ${error?.message ?? error}`)
|
|
76
|
-
return undefined
|
|
77
|
-
}))
|
|
78
|
-
}
|
|
79
|
-
return resolveSpecOptions(await specCache.get(cwd))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function isObject(value) {
|
|
83
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// returns the value if it matches the expected type, otherwise warns and returns undefined
|
|
87
|
-
function checkType(option, value, type) {
|
|
88
|
-
if (value === undefined) return undefined
|
|
89
|
-
const matches = type === 'object'
|
|
90
|
-
? isObject(value)
|
|
91
|
-
: type === 'array' ? Array.isArray(value) : typeof value === type
|
|
92
|
-
if (matches) return value
|
|
93
|
-
warnInvalid(option, value, type)
|
|
94
|
-
return undefined
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function toOpenMode(option, value) {
|
|
98
|
-
if (value === undefined) return NUXT_SPEC_DEFAULTS.htmlReport.open
|
|
99
|
-
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : value
|
|
100
|
-
if (HTML_REPORT_OPEN_MODES.includes(normalized)) return normalized
|
|
101
|
-
warnInvalid(option, value, HTML_REPORT_OPEN_MODES.map(m => `'${m}'`).join(' | '))
|
|
102
|
-
return NUXT_SPEC_DEFAULTS.htmlReport.open
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function warnInvalid(option, value, expected, outcome = 'Falling back to default.') {
|
|
106
|
-
const message = `[Nuxt Spec] Invalid value ${JSON.stringify(value) ?? String(value)} for \`${option}\` (expected ${expected}). ${outcome}`
|
|
107
|
-
if (reportedWarnings.has(message)) return
|
|
108
|
-
reportedWarnings.add(message)
|
|
109
|
-
console.warn(message)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// unset or empty = not defined, only explicit 'false' disables
|
|
113
|
-
function toBoolean(value) {
|
|
114
|
-
if (value === undefined || value === '') return undefined
|
|
115
|
-
return value !== 'false'
|
|
116
|
-
}
|
|
1
|
+
// Nuxt Spec options resolution
|
|
2
|
+
// - values can be set via `spec` key in nuxt.config.ts or via NUXT_SPEC_* env variables
|
|
3
|
+
// - precedence: env variables > nuxt.config.ts > defaults
|
|
4
|
+
|
|
5
|
+
import { loadNuxtConfig } from 'nuxt/kit'
|
|
6
|
+
|
|
7
|
+
export const NUXT_SPEC_DEFAULTS = {
|
|
8
|
+
hints: true,
|
|
9
|
+
externalPlaywright: undefined,
|
|
10
|
+
htmlReport: {
|
|
11
|
+
enabled: true,
|
|
12
|
+
open: 'failed',
|
|
13
|
+
},
|
|
14
|
+
messageFilters: [],
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const HTML_REPORT_OPEN_MODES = ['always', 'failed', 'never']
|
|
18
|
+
|
|
19
|
+
// raw `spec` values per cwd - nuxt.config.ts is only loaded once
|
|
20
|
+
const specCache = new Map()
|
|
21
|
+
|
|
22
|
+
// options are resolved by both the Nuxt module and the Vitest config in the same process
|
|
23
|
+
const reportedWarnings = new Set()
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve final Nuxt Spec options.
|
|
27
|
+
* @param {import('./options.d.mts').NuxtSpecOptions | false | null} [fromConfig] - `spec` key from nuxt.config.ts
|
|
28
|
+
* @param {Record<string, string | undefined>} [env] - env variables
|
|
29
|
+
* @returns {import('./options.d.mts').ResolvedNuxtSpecOptions}
|
|
30
|
+
*/
|
|
31
|
+
export function resolveSpecOptions(fromConfig, env = process.env) {
|
|
32
|
+
const config = isObject(fromConfig) ? fromConfig : {}
|
|
33
|
+
const htmlReport = checkType('htmlReport', config.htmlReport, 'object') ?? {}
|
|
34
|
+
return {
|
|
35
|
+
hints: toBoolean(env.NUXT_SPEC_HINTS_ENABLED)
|
|
36
|
+
?? checkType('hints', config.hints, 'boolean')
|
|
37
|
+
?? NUXT_SPEC_DEFAULTS.hints,
|
|
38
|
+
externalPlaywright: env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
|
|
39
|
+
|| checkType('externalPlaywright', config.externalPlaywright, 'string')
|
|
40
|
+
|| NUXT_SPEC_DEFAULTS.externalPlaywright,
|
|
41
|
+
htmlReport: {
|
|
42
|
+
enabled: toBoolean(env.NUXT_SPEC_HTML_REPORT)
|
|
43
|
+
?? checkType('htmlReport.enabled', htmlReport.enabled, 'boolean')
|
|
44
|
+
?? NUXT_SPEC_DEFAULTS.htmlReport.enabled,
|
|
45
|
+
open: env.NUXT_SPEC_HTML_REPORT_OPEN
|
|
46
|
+
? toOpenMode('NUXT_SPEC_HTML_REPORT_OPEN', env.NUXT_SPEC_HTML_REPORT_OPEN)
|
|
47
|
+
: toOpenMode('htmlReport.open', htmlReport.open),
|
|
48
|
+
},
|
|
49
|
+
messageFilters: [
|
|
50
|
+
...(checkType('messageFilters', config.messageFilters, 'array') ?? []),
|
|
51
|
+
...(env.NUXT_SPEC_MESSAGE_FILTERS?.split(',') ?? []),
|
|
52
|
+
]
|
|
53
|
+
.filter((f) => {
|
|
54
|
+
if (typeof f === 'string') return true
|
|
55
|
+
warnInvalid('messageFilters', f, 'string', 'Value is ignored.')
|
|
56
|
+
return false
|
|
57
|
+
})
|
|
58
|
+
.map(f => f.trim())
|
|
59
|
+
// empty pattern would match (and swallow) every message
|
|
60
|
+
.filter(Boolean),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Load `spec` key from nuxt.config.ts (including extended layers)
|
|
66
|
+
* and resolve final Nuxt Spec options.
|
|
67
|
+
* @param {string} [cwd] - directory with nuxt.config.ts
|
|
68
|
+
* @returns {Promise<import('./options.d.mts').ResolvedNuxtSpecOptions>}
|
|
69
|
+
*/
|
|
70
|
+
export async function loadSpecOptions(cwd = process.cwd()) {
|
|
71
|
+
if (!specCache.has(cwd)) {
|
|
72
|
+
specCache.set(cwd, loadNuxtConfig({ cwd })
|
|
73
|
+
.then(config => config.spec)
|
|
74
|
+
.catch((error) => {
|
|
75
|
+
console.warn(`[Nuxt Spec] Failed to read \`spec\` options from nuxt.config: ${error?.message ?? error}`)
|
|
76
|
+
return undefined
|
|
77
|
+
}))
|
|
78
|
+
}
|
|
79
|
+
return resolveSpecOptions(await specCache.get(cwd))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isObject(value) {
|
|
83
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// returns the value if it matches the expected type, otherwise warns and returns undefined
|
|
87
|
+
function checkType(option, value, type) {
|
|
88
|
+
if (value === undefined) return undefined
|
|
89
|
+
const matches = type === 'object'
|
|
90
|
+
? isObject(value)
|
|
91
|
+
: type === 'array' ? Array.isArray(value) : typeof value === type
|
|
92
|
+
if (matches) return value
|
|
93
|
+
warnInvalid(option, value, type)
|
|
94
|
+
return undefined
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function toOpenMode(option, value) {
|
|
98
|
+
if (value === undefined) return NUXT_SPEC_DEFAULTS.htmlReport.open
|
|
99
|
+
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : value
|
|
100
|
+
if (HTML_REPORT_OPEN_MODES.includes(normalized)) return normalized
|
|
101
|
+
warnInvalid(option, value, HTML_REPORT_OPEN_MODES.map(m => `'${m}'`).join(' | '))
|
|
102
|
+
return NUXT_SPEC_DEFAULTS.htmlReport.open
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function warnInvalid(option, value, expected, outcome = 'Falling back to default.') {
|
|
106
|
+
const message = `[Nuxt Spec] Invalid value ${JSON.stringify(value) ?? String(value)} for \`${option}\` (expected ${expected}). ${outcome}`
|
|
107
|
+
if (reportedWarnings.has(message)) return
|
|
108
|
+
reportedWarnings.add(message)
|
|
109
|
+
console.warn(message)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// unset or empty = not defined, only explicit 'false' disables
|
|
113
|
+
function toBoolean(value) {
|
|
114
|
+
if (value === undefined || value === '') return undefined
|
|
115
|
+
return value !== 'false'
|
|
116
|
+
}
|