@depup/nuxt__kit 4.5.1-depup.0 → 4.5.2-depup.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 -4
- package/changes.json +8 -4
- package/dist/index.d.mts +53 -2
- package/dist/index.mjs +238 -32
- package/package.json +20 -15
package/README.md
CHANGED
|
@@ -13,17 +13,18 @@ npm install @depup/nuxt__kit
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [@nuxt/kit](https://www.npmjs.com/package/@nuxt/kit) @ 4.5.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [@nuxt/kit](https://www.npmjs.com/package/@nuxt/kit) @ 4.5.2 |
|
|
17
|
+
| Processed | 2026-08-15 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
|
-
| Deps updated |
|
|
19
|
+
| Deps updated | 3 |
|
|
20
20
|
|
|
21
21
|
## Dependency Changes
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
25
|
| c12 | ^3.3.4 | ^4.0.0-beta.5 |
|
|
26
|
-
|
|
|
26
|
+
| ohash | ^2.0.11 | ^2.0.12 |
|
|
27
|
+
| verkit | ^0.3.1 | ^0.4.0 |
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
package/changes.json
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
"from": "^3.3.4",
|
|
5
5
|
"to": "^4.0.0-beta.5"
|
|
6
6
|
},
|
|
7
|
+
"ohash": {
|
|
8
|
+
"from": "^2.0.11",
|
|
9
|
+
"to": "^2.0.12"
|
|
10
|
+
},
|
|
7
11
|
"verkit": {
|
|
8
|
-
"from": "^0.
|
|
9
|
-
"to": "^0.
|
|
12
|
+
"from": "^0.3.1",
|
|
13
|
+
"to": "^0.4.0"
|
|
10
14
|
}
|
|
11
15
|
},
|
|
12
|
-
"timestamp": "2026-
|
|
13
|
-
"totalUpdated":
|
|
16
|
+
"timestamp": "2026-08-15T16:05:00.236Z",
|
|
17
|
+
"totalUpdated": 3
|
|
14
18
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ConsolaInstance, ConsolaOptions } from "consola";
|
|
2
2
|
import { UseContext } from "unctx";
|
|
3
|
+
import "pkg-types";
|
|
3
4
|
import { GlobOptions } from "tinyglobby";
|
|
4
5
|
import { LoadConfigOptions } from "c12";
|
|
5
6
|
import { Component, ComponentsDir, ModuleDefinition, ModuleMeta, ModuleOptions, Nuxt, NuxtAppConfig, NuxtBuildOutputs, NuxtCompatibility, NuxtCompatibilityIssues, NuxtConfig, NuxtHooks, NuxtMiddleware, NuxtModule, NuxtOptions, NuxtPlugin, NuxtPluginTemplate, NuxtServerTemplate, NuxtTemplate, NuxtTypeTemplate, ResolvedNuxtTemplate, SchemaDefinition } from "@nuxt/schema";
|
|
@@ -7,7 +8,6 @@ import { Import, Preset } from "unimport";
|
|
|
7
8
|
import { Configuration, WebpackPluginInstance } from "webpack";
|
|
8
9
|
import { Plugin, UserConfig } from "vite";
|
|
9
10
|
import { Nitro, NitroDevEventHandler, NitroEventHandler, NitroRouteConfig } from "nitropack/types";
|
|
10
|
-
|
|
11
11
|
//#region src/module/define.d.ts
|
|
12
12
|
/**
|
|
13
13
|
* Define a Nuxt module, automatically merging defaults with user provided options, installing
|
|
@@ -581,6 +581,35 @@ declare function packageName(specifier: string): string;
|
|
|
581
581
|
*/
|
|
582
582
|
declare function resolveTypePaths(packages: string[], searchPaths: string[]): Promise<Array<[string, string]>>;
|
|
583
583
|
//#endregion
|
|
584
|
+
//#region src/watch.d.ts
|
|
585
|
+
/**
|
|
586
|
+
* The subset of a chokidar `FSWatcher` this helper needs. Callers hold
|
|
587
|
+
* different chokidar majors (Nuxt core watches with v5, Vite bundles v3), so
|
|
588
|
+
* the parameter is structural rather than an import of either package.
|
|
589
|
+
*/
|
|
590
|
+
interface RecoverableWatcher {
|
|
591
|
+
on: (event: any, listener: (...args: any[]) => void) => any;
|
|
592
|
+
emit: (event: any, ...args: any[]) => any;
|
|
593
|
+
options?: {
|
|
594
|
+
cwd?: string | undefined;
|
|
595
|
+
} | undefined;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* chokidar suppresses a `change` event that lands within 50ms of the previous
|
|
599
|
+
* `change` for the same path, and never replays it. A save that follows a fast
|
|
600
|
+
* HMR round trip is therefore silently lost until the file is touched again,
|
|
601
|
+
* which looks exactly like broken HMR. This is true of every chokidar major
|
|
602
|
+
* Nuxt uses.
|
|
603
|
+
*
|
|
604
|
+
* Raw fs events are not throttled, so once chokidar has reported a file at
|
|
605
|
+
* least once we can use them to notice a modification that never surfaced as a
|
|
606
|
+
* `change` event, and re-emit it after the throttle window has passed.
|
|
607
|
+
*
|
|
608
|
+
* @param watcher the chokidar watcher to patch
|
|
609
|
+
* @returns a disposer releasing the recovery state; call it when the watcher closes
|
|
610
|
+
*/
|
|
611
|
+
declare function recoverThrottledChanges(watcher: RecoverableWatcher): () => void;
|
|
612
|
+
//#endregion
|
|
584
613
|
//#region src/logger.d.ts
|
|
585
614
|
declare const logger: ConsolaInstance;
|
|
586
615
|
declare function useLogger(tag?: string, options?: Partial<ConsolaOptions>): ConsolaInstance;
|
|
@@ -1008,6 +1037,16 @@ declare const pageDiagnostics: import("nostics").Diagnostics<{
|
|
|
1008
1037
|
readonly fix: "Use only JSON-serializable values (strings, numbers, booleans, arrays, plain objects) in `defineRouteRules()`.";
|
|
1009
1038
|
readonly docs: false;
|
|
1010
1039
|
};
|
|
1040
|
+
readonly NUXT_B4007: {
|
|
1041
|
+
readonly why: (p: {
|
|
1042
|
+
fnName: string;
|
|
1043
|
+
file: string;
|
|
1044
|
+
}) => string;
|
|
1045
|
+
readonly fix: (p: {
|
|
1046
|
+
fnName: string;
|
|
1047
|
+
}) => string;
|
|
1048
|
+
readonly docs: false;
|
|
1049
|
+
};
|
|
1011
1050
|
readonly NUXT_B4008: {
|
|
1012
1051
|
readonly why: "Server pages with `ssr: false` are not supported while component islands are auto-detected.";
|
|
1013
1052
|
readonly fix: "Set `experimental.componentIslands` to `true`.";
|
|
@@ -1335,6 +1374,18 @@ declare const bundlerDiagnostics: import("nostics").Diagnostics<{
|
|
|
1335
1374
|
readonly fix: "Externalize dependencies in the server build (`externals`) for better build performance.";
|
|
1336
1375
|
readonly docs: false;
|
|
1337
1376
|
};
|
|
1377
|
+
readonly NUXT_B7020: {
|
|
1378
|
+
readonly why: "The client build manifest is disabled, but Nuxt requires it to render the correct assets for each route.";
|
|
1379
|
+
readonly fix: "Remove any `build.manifest: false` override from your `nuxt.config` `vite` options or from a Vite plugin `config`/`configEnvironment` hook.";
|
|
1380
|
+
readonly docs: false;
|
|
1381
|
+
};
|
|
1382
|
+
readonly NUXT_B7021: {
|
|
1383
|
+
readonly why: (p: {
|
|
1384
|
+
manifestFile: string;
|
|
1385
|
+
}) => string;
|
|
1386
|
+
readonly fix: "Check that no Vite plugin removes or renames the client build manifest in a `generateBundle`/`writeBundle` hook. If this happens with no such plugin, please report it at https://github.com/nuxt/nuxt/issues.";
|
|
1387
|
+
readonly docs: false;
|
|
1388
|
+
};
|
|
1338
1389
|
}, readonly [import("nostics").DiagnosticReporter<{
|
|
1339
1390
|
method?: import("nostics").ConsoleMethod;
|
|
1340
1391
|
}>]>;
|
|
@@ -1373,4 +1424,4 @@ declare function requireModule<T = unknown>(id: string, opts?: ImportModuleOptio
|
|
|
1373
1424
|
*/
|
|
1374
1425
|
declare function tryRequireModule<T = unknown>(id: string, opts?: ImportModuleOptions): T | undefined;
|
|
1375
1426
|
//#endregion
|
|
1376
|
-
export { type AddComponentOptions, type AddPluginOptions, type AddRouteMiddlewareOptions, DEFAULT_JSX_FILE_EXTENSIONS, DEFAULT_JS_FILE_EXTENSIONS, type ExtendConfigOptions, type ExtendRouteRulesOptions, type ExtendViteConfigOptions, type ExtendWebpackConfigOptions, type ImportModuleOptions, type LayerDirectories, type LoadNuxtConfigOptions, type LoadNuxtOptions, type NuxtMajorVersion, type ResolveModuleOptions, type ResolvePathOptions, type Resolver, addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildDiagnostics, buildNuxt, bundlerDiagnostics, checkNuxtCompatibility, componentDiagnostics, configDiagnostics, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, headDiagnostics, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, packageName, pageDiagnostics, pluginDiagnostics, requireModule, resolveAlias, resolveDeclarationPath, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, resolveTypePaths, runWithNuxtContext, setBuildOutput, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateAppConfig, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
|
|
1427
|
+
export { type AddComponentOptions, type AddPluginOptions, type AddRouteMiddlewareOptions, DEFAULT_JSX_FILE_EXTENSIONS, DEFAULT_JS_FILE_EXTENSIONS, type ExtendConfigOptions, type ExtendRouteRulesOptions, type ExtendViteConfigOptions, type ExtendWebpackConfigOptions, type ImportModuleOptions, type LayerDirectories, type LoadNuxtConfigOptions, type LoadNuxtOptions, type NuxtMajorVersion, type RecoverableWatcher, type ResolveModuleOptions, type ResolvePathOptions, type Resolver, addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildDiagnostics, buildNuxt, bundlerDiagnostics, checkNuxtCompatibility, componentDiagnostics, configDiagnostics, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, headDiagnostics, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, packageName, pageDiagnostics, pluginDiagnostics, recoverThrottledChanges, requireModule, resolveAlias, resolveDeclarationPath, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, resolveTypePaths, runWithNuxtContext, setBuildOutput, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateAppConfig, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { performance } from "node:perf_hooks";
|
|
2
2
|
import { createDefu, defu } from "defu";
|
|
3
|
-
import { applyDefaults } from "untyped";
|
|
4
3
|
import { consola } from "consola";
|
|
5
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
5
|
import { getContext } from "unctx";
|
|
@@ -13,22 +12,23 @@ import { readPackageJSON, resolvePackageJSON } from "pkg-types";
|
|
|
13
12
|
import { existsSync, lstatSync, promises, readFileSync, realpathSync, statSync } from "node:fs";
|
|
14
13
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
15
14
|
import { basename, dirname, isAbsolute, join, normalize, parse, relative, resolve } from "pathe";
|
|
16
|
-
import { createJiti } from "jiti";
|
|
17
15
|
import { interopDefault, lookupNodeModuleSubpath, parseNodeModulePath, resolveModuleExportNames } from "mlly";
|
|
18
16
|
import { resolveModulePath, resolveModuleURL } from "exsolve";
|
|
19
17
|
import { isRelative, withTrailingSlash, withoutTrailingSlash } from "ufo";
|
|
20
18
|
import { read, update } from "rc9";
|
|
19
|
+
import { createJiti } from "jiti";
|
|
21
20
|
import { captureStackTrace } from "errx";
|
|
22
21
|
import { glob } from "tinyglobby";
|
|
23
22
|
import { resolveAlias as resolveAlias$1, reverseResolveAlias } from "pathe/utils";
|
|
24
23
|
import ignore from "ignore";
|
|
24
|
+
import { applyDefaults } from "untyped";
|
|
25
25
|
import { loadConfig, setupDotenv } from "c12";
|
|
26
|
-
import { klona } from "klona
|
|
26
|
+
import { klona } from "klona";
|
|
27
27
|
import destr from "destr";
|
|
28
28
|
import { kebabCase, pascalCase, snakeCase } from "scule";
|
|
29
|
-
import { klona as klona$1 } from "klona";
|
|
30
29
|
import { hash } from "ohash";
|
|
31
|
-
import { isAbsolute as isAbsolute$1 } from "node:path";
|
|
30
|
+
import { isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "node:path";
|
|
31
|
+
import { stat } from "node:fs/promises";
|
|
32
32
|
//#region src/logger.ts
|
|
33
33
|
const logger = consola;
|
|
34
34
|
function useLogger(tag, options = {}) {
|
|
@@ -209,7 +209,8 @@ const builderMap = {
|
|
|
209
209
|
"@nuxt/webpack-builder": "webpack"
|
|
210
210
|
};
|
|
211
211
|
function checkNuxtVersion(version, nuxt = useNuxt()) {
|
|
212
|
-
|
|
212
|
+
const nuxtVersion = getNuxtVersion(nuxt);
|
|
213
|
+
return satisfies(normalizeSemanticVersion(nuxtVersion), version, { includePrerelease: true });
|
|
213
214
|
}
|
|
214
215
|
/**
|
|
215
216
|
* Check version constraints and return incompatibility issues as an array
|
|
@@ -305,8 +306,13 @@ function _defineNuxtModule(definition) {
|
|
|
305
306
|
module.meta.configKey ||= module.meta.name;
|
|
306
307
|
async function getOptions(inlineOptions, nuxt = useNuxt()) {
|
|
307
308
|
const nuxtConfigOptionsKey = module.meta.configKey || module.meta.name;
|
|
308
|
-
|
|
309
|
-
|
|
309
|
+
const nuxtConfigOptions = nuxtConfigOptionsKey && nuxtConfigOptionsKey in nuxt.options ? nuxt.options[nuxtConfigOptionsKey] : {};
|
|
310
|
+
const optionsDefaults = module.defaults instanceof Function ? await module.defaults(nuxt) : module.defaults ?? {};
|
|
311
|
+
let options = defu(inlineOptions, nuxtConfigOptions, optionsDefaults);
|
|
312
|
+
if (module.schema) {
|
|
313
|
+
const { applyDefaults } = await import("untyped");
|
|
314
|
+
options = await applyDefaults(module.schema, options);
|
|
315
|
+
}
|
|
310
316
|
return Promise.resolve(options);
|
|
311
317
|
}
|
|
312
318
|
function getModuleDependencies(nuxt = useNuxt()) {
|
|
@@ -692,7 +698,8 @@ function resolveModule(id, options) {
|
|
|
692
698
|
});
|
|
693
699
|
}
|
|
694
700
|
async function importModule(id, opts) {
|
|
695
|
-
|
|
701
|
+
const resolvedPath = resolveModule(id, opts);
|
|
702
|
+
return await import(pathToFileURL(resolvedPath).href).then((r) => opts?.interopDefault !== false ? interopDefault(r) : r);
|
|
696
703
|
}
|
|
697
704
|
function tryImportModule(id, opts) {
|
|
698
705
|
try {
|
|
@@ -768,7 +775,8 @@ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useN
|
|
|
768
775
|
continue;
|
|
769
776
|
}
|
|
770
777
|
if (value.version) {
|
|
771
|
-
const
|
|
778
|
+
const resolvePaths = [res.resolvedModulePath, ...nuxt.options.modulesDir].filter(Boolean);
|
|
779
|
+
const pkg = await readPackageJSON(name, { from: resolvePaths }).catch(() => null);
|
|
772
780
|
if (pkg?.version && !satisfies(pkg.version, value.version, { includePrerelease: true })) {
|
|
773
781
|
const message = `Module \`${name}\` version (\`${pkg.version}\`) does not satisfy \`${value.version}\` (requested by ${moduleToAttribute}).`;
|
|
774
782
|
error = new TypeError(message);
|
|
@@ -896,7 +904,7 @@ function getSharedJiti(nuxt) {
|
|
|
896
904
|
_jitiCache ||= /* @__PURE__ */ new WeakMap();
|
|
897
905
|
let jiti = _jitiCache.get(nuxt);
|
|
898
906
|
if (!jiti) {
|
|
899
|
-
jiti = createJiti(nuxt.options.rootDir, { alias: nuxt.options.alias });
|
|
907
|
+
jiti = import("jiti").then(({ createJiti }) => createJiti(nuxt.options.rootDir, { alias: nuxt.options.alias }));
|
|
900
908
|
_jitiCache.set(nuxt, jiti);
|
|
901
909
|
}
|
|
902
910
|
return jiti;
|
|
@@ -908,7 +916,7 @@ async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
|
|
|
908
916
|
buildTimeModuleMeta
|
|
909
917
|
};
|
|
910
918
|
if (typeof nuxtModule !== "string") throw kitDiagnostics.NUXT_B8015({ received: `${typeof nuxtModule} (${JSON.stringify(nuxtModule)})` });
|
|
911
|
-
const jiti = getSharedJiti(nuxt);
|
|
919
|
+
const jiti = await getSharedJiti(nuxt);
|
|
912
920
|
nuxtModule = resolveAlias(nuxtModule, nuxt.options.alias);
|
|
913
921
|
if (isRelative(nuxtModule)) nuxtModule = resolve(nuxt.options.rootDir, nuxtModule);
|
|
914
922
|
let src;
|
|
@@ -1448,7 +1456,7 @@ function addServerScanDir(dirs, opts = {}) {
|
|
|
1448
1456
|
*/
|
|
1449
1457
|
function useRuntimeConfig() {
|
|
1450
1458
|
const nuxt = useNuxt();
|
|
1451
|
-
return applyEnv(klona
|
|
1459
|
+
return applyEnv(klona(nuxt.options.nitro.runtimeConfig), {
|
|
1452
1460
|
prefix: "NITRO_",
|
|
1453
1461
|
altPrefix: "NUXT_",
|
|
1454
1462
|
envExpansion: nuxt.options.nitro.experimental?.envExpansion ?? !!process.env.NITRO_ENV_EXPANSION
|
|
@@ -1581,14 +1589,18 @@ function addVitePlugin(pluginOrGetter, options = {}) {
|
|
|
1581
1589
|
return;
|
|
1582
1590
|
}
|
|
1583
1591
|
const environmentName = options.server === false ? "client" : "ssr";
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
+
const defaultEnforce = options?.prepend ? "pre" : "post";
|
|
1593
|
+
const method = options?.prepend ? "unshift" : "push";
|
|
1594
|
+
for (const [enforce, plugins] of groupByEnforce(plugin, defaultEnforce)) {
|
|
1595
|
+
const pluginName = plugins.map((p) => p.name).join("|");
|
|
1596
|
+
config.plugins[method]({
|
|
1597
|
+
name: `${pluginName}:wrapper`,
|
|
1598
|
+
enforce,
|
|
1599
|
+
applyToEnvironment(environment) {
|
|
1600
|
+
if (environment.name === environmentName) return resolveNestedPlugins(plugins, config, environment, nuxt);
|
|
1601
|
+
}
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1592
1604
|
});
|
|
1593
1605
|
nuxt.hook("vite:extendConfig", async (config, env) => {
|
|
1594
1606
|
if (!needsEnvInjection) return;
|
|
@@ -1598,6 +1610,53 @@ function addVitePlugin(pluginOrGetter, options = {}) {
|
|
|
1598
1610
|
if (env.isServer && options.client === false) config.plugins[method](...plugin);
|
|
1599
1611
|
});
|
|
1600
1612
|
}
|
|
1613
|
+
function groupByEnforce(plugins, defaultEnforce) {
|
|
1614
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1615
|
+
for (const plugin of plugins) {
|
|
1616
|
+
const enforce = plugin.enforce ?? defaultEnforce;
|
|
1617
|
+
const group = groups.get(enforce);
|
|
1618
|
+
if (group) group.push(plugin);
|
|
1619
|
+
else groups.set(enforce, [plugin]);
|
|
1620
|
+
}
|
|
1621
|
+
return groups;
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Vite only honours `apply` and `applyToEnvironment` for plugins it finds in the
|
|
1625
|
+
* top-level plugin array, so plugins nested behind a wrapper have to be resolved
|
|
1626
|
+
* by hand or (for example) dev-only plugins would leak into production builds.
|
|
1627
|
+
*/
|
|
1628
|
+
async function resolveNestedPlugins(plugins, config, environment, nuxt) {
|
|
1629
|
+
const configEnv = resolveConfigEnv(environment, config, nuxt);
|
|
1630
|
+
const resolved = [];
|
|
1631
|
+
for (const plugin of plugins) {
|
|
1632
|
+
const { apply, applyToEnvironment } = plugin;
|
|
1633
|
+
if (apply && (typeof apply === "function" ? !apply(config, configEnv) : apply !== configEnv.command)) continue;
|
|
1634
|
+
const applied = applyToEnvironment ? await applyToEnvironment(environment) : true;
|
|
1635
|
+
if (applied === true) {
|
|
1636
|
+
resolved.push(plugin);
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1639
|
+
resolved.push(...await flattenPlugins(applied));
|
|
1640
|
+
}
|
|
1641
|
+
return resolved;
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* `getTopLevelConfig` is only available from Vite 6, and kit is used with older
|
|
1645
|
+
* versions of nuxt (and therefore vite), so fall back to what we can infer.
|
|
1646
|
+
*/
|
|
1647
|
+
function resolveConfigEnv(environment, config, nuxt) {
|
|
1648
|
+
const topLevelConfig = environment.getTopLevelConfig?.() ?? environment.config;
|
|
1649
|
+
return {
|
|
1650
|
+
command: topLevelConfig?.command ?? (nuxt.options.dev ? "serve" : "build"),
|
|
1651
|
+
mode: topLevelConfig?.mode ?? config.mode ?? nuxt.options.vite?.mode ?? (nuxt.options.dev ? "development" : "production")
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
async function flattenPlugins(option) {
|
|
1655
|
+
const resolved = await option;
|
|
1656
|
+
if (!resolved) return [];
|
|
1657
|
+
if (Array.isArray(resolved)) return (await Promise.all(resolved.map(flattenPlugins))).flat();
|
|
1658
|
+
return [resolved];
|
|
1659
|
+
}
|
|
1601
1660
|
function addBuildPlugin(pluginFactory, options) {
|
|
1602
1661
|
if (pluginFactory.vite) addVitePlugin(pluginFactory.vite, options);
|
|
1603
1662
|
if (pluginFactory.webpack) addWebpackPlugin(pluginFactory.webpack, options);
|
|
@@ -1708,7 +1767,8 @@ function addComponentExports(opts) {
|
|
|
1708
1767
|
const nuxt = useNuxt();
|
|
1709
1768
|
const components = [];
|
|
1710
1769
|
nuxt.hook("components:dirs", async () => {
|
|
1711
|
-
const
|
|
1770
|
+
const filePath = await resolvePath(opts.filePath);
|
|
1771
|
+
const names = await resolveModuleExportNames(filePath, { extensions: nuxt.options.extensions });
|
|
1712
1772
|
components.length = 0;
|
|
1713
1773
|
for (const name of names) components.push(normalizeComponent({
|
|
1714
1774
|
name: pascalCase([opts.prefix || "", name === "default" ? "" : name]),
|
|
@@ -1806,6 +1866,11 @@ const pageDiagnostics = /* #__PURE__ */ defineDiagnostics({
|
|
|
1806
1866
|
fix: "Use only JSON-serializable values (strings, numbers, booleans, arrays, plain objects) in `defineRouteRules()`.",
|
|
1807
1867
|
docs: false
|
|
1808
1868
|
},
|
|
1869
|
+
NUXT_B4007: {
|
|
1870
|
+
why: (p) => `\`${p.fnName}\` is called conditionally or used as an expression in \`${p.file}\`, but it is a compiler macro that is extracted at build time and always applies.`,
|
|
1871
|
+
fix: (p) => `Call \`${p.fnName}({ ... })\` once, as a statement at the top level of the \`<script setup>\` block.`,
|
|
1872
|
+
docs: false
|
|
1873
|
+
},
|
|
1809
1874
|
NUXT_B4008: {
|
|
1810
1875
|
why: "Server pages with `ssr: false` are not supported while component islands are auto-detected.",
|
|
1811
1876
|
fix: "Set `experimental.componentIslands` to `true`.",
|
|
@@ -1906,10 +1971,11 @@ function resolveRoot(basePkg, from) {
|
|
|
1906
1971
|
if (rootCache.has(cacheKey)) return rootCache.get(cacheKey);
|
|
1907
1972
|
const promise = (async () => {
|
|
1908
1973
|
try {
|
|
1909
|
-
|
|
1974
|
+
const r = resolveModulePath(basePkg, {
|
|
1910
1975
|
from,
|
|
1911
1976
|
...TYPE_RESOLVE_OPTIONS
|
|
1912
|
-
})
|
|
1977
|
+
});
|
|
1978
|
+
return dirname(await resolvePackageJSON(r));
|
|
1913
1979
|
} catch {
|
|
1914
1980
|
return;
|
|
1915
1981
|
}
|
|
@@ -2386,16 +2452,25 @@ async function writeTypes(nuxt) {
|
|
|
2386
2452
|
const sharedDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.shared.d.ts");
|
|
2387
2453
|
await promises.mkdir(nuxt.options.buildDir, { recursive: true });
|
|
2388
2454
|
await Promise.all([
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2455
|
+
writeIfChanged(appTsConfigPath, JSON.stringify(tsConfig, null, 2)),
|
|
2456
|
+
writeIfChanged(legacyTsConfigPath, JSON.stringify(legacyTsConfig, null, 2)),
|
|
2457
|
+
writeIfChanged(nodeTsConfigPath, JSON.stringify(nodeTsConfig, null, 2)),
|
|
2458
|
+
writeIfChanged(sharedTsConfigPath, JSON.stringify(sharedTsConfig, null, 2)),
|
|
2459
|
+
writeIfChanged(declarationPath, declaration),
|
|
2460
|
+
writeIfChanged(nodeDeclarationPath, nodeDeclaration),
|
|
2461
|
+
writeIfChanged(sharedDeclarationPath, sharedDeclaration)
|
|
2396
2462
|
]);
|
|
2397
2463
|
}
|
|
2398
2464
|
/**
|
|
2465
|
+
* Types are regenerated on every start and are usually identical, so avoid
|
|
2466
|
+
* touching the files: an unchanged mtime keeps editors and `tsc --watch` from
|
|
2467
|
+
* redoing work they have already done.
|
|
2468
|
+
*/
|
|
2469
|
+
async function writeIfChanged(path, contents) {
|
|
2470
|
+
if (await promises.readFile(path, "utf8").catch(() => void 0) === contents) return;
|
|
2471
|
+
await promises.writeFile(path, contents);
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2399
2474
|
* Sort the paths in the tsconfig.json file, so
|
|
2400
2475
|
* - Hoisted package paths stay at the top (`typescript.hoist`)
|
|
2401
2476
|
* - Custom layer aliases follow, then generic `#layers/*` aliases
|
|
@@ -2627,6 +2702,127 @@ function addPluginTemplate(plugin, opts = {}) {
|
|
|
2627
2702
|
}, opts);
|
|
2628
2703
|
}
|
|
2629
2704
|
//#endregion
|
|
2705
|
+
//#region src/watch.ts
|
|
2706
|
+
const RECHECK_DELAY = 70;
|
|
2707
|
+
/**
|
|
2708
|
+
* A single write moves the mtime more than once (truncate, then write) and
|
|
2709
|
+
* chokidar may dispatch `change` off the first of those, so a mtime a hair
|
|
2710
|
+
* newer than the one recorded is the tail of a write that *was* reported
|
|
2711
|
+
* rather than one that was dropped.
|
|
2712
|
+
*/
|
|
2713
|
+
const MTIME_EPSILON = 10;
|
|
2714
|
+
const RECOVERY_FLAG = Symbol.for("nuxt:watch-recovery");
|
|
2715
|
+
/**
|
|
2716
|
+
* chokidar suppresses a `change` event that lands within 50ms of the previous
|
|
2717
|
+
* `change` for the same path, and never replays it. A save that follows a fast
|
|
2718
|
+
* HMR round trip is therefore silently lost until the file is touched again,
|
|
2719
|
+
* which looks exactly like broken HMR. This is true of every chokidar major
|
|
2720
|
+
* Nuxt uses.
|
|
2721
|
+
*
|
|
2722
|
+
* Raw fs events are not throttled, so once chokidar has reported a file at
|
|
2723
|
+
* least once we can use them to notice a modification that never surfaced as a
|
|
2724
|
+
* `change` event, and re-emit it after the throttle window has passed.
|
|
2725
|
+
*
|
|
2726
|
+
* @param watcher the chokidar watcher to patch
|
|
2727
|
+
* @returns a disposer releasing the recovery state; call it when the watcher closes
|
|
2728
|
+
*/
|
|
2729
|
+
function recoverThrottledChanges(watcher) {
|
|
2730
|
+
if (watcher[RECOVERY_FLAG]) return () => {};
|
|
2731
|
+
Object.defineProperty(watcher, RECOVERY_FLAG, {
|
|
2732
|
+
value: true,
|
|
2733
|
+
configurable: true
|
|
2734
|
+
});
|
|
2735
|
+
const tracked = /* @__PURE__ */ new Map();
|
|
2736
|
+
const pending = /* @__PURE__ */ new Map();
|
|
2737
|
+
let disposed = false;
|
|
2738
|
+
/**
|
|
2739
|
+
* With `cwd` set, chokidar emits high-level events relative to it while raw
|
|
2740
|
+
* events carry an absolute `watchedPath`, so everything is keyed absolutely
|
|
2741
|
+
* and the emitted path is kept alongside to re-emit in chokidar's namespace.
|
|
2742
|
+
*/
|
|
2743
|
+
const cwd = watcher.options?.cwd;
|
|
2744
|
+
const toKey = (path) => cwd ? resolve$1(cwd, path) : path;
|
|
2745
|
+
/**
|
|
2746
|
+
* `watchedPath` is the (possibly relative) path chokidar handed to `fs.watch`
|
|
2747
|
+
* and `path` is the name `fs.watch` reported, which is a basename both when
|
|
2748
|
+
* the file itself is watched and when its parent directory is. The two are
|
|
2749
|
+
* indistinguishable for a directory containing a child of the same name, so
|
|
2750
|
+
* pick whichever candidate chokidar has already reported a modification time
|
|
2751
|
+
* for, and use native separators to match the paths chokidar emits.
|
|
2752
|
+
*/
|
|
2753
|
+
const resolveTracked = (path, details) => {
|
|
2754
|
+
const watched = typeof details?.watchedPath === "string" ? details.watchedPath : void 0;
|
|
2755
|
+
if (!watched) {
|
|
2756
|
+
const key = toKey(path);
|
|
2757
|
+
return tracked.has(key) ? key : void 0;
|
|
2758
|
+
}
|
|
2759
|
+
const child = toKey(join$1(watched, path));
|
|
2760
|
+
if (tracked.has(child)) return child;
|
|
2761
|
+
const parent = toKey(watched);
|
|
2762
|
+
return tracked.has(parent) ? parent : void 0;
|
|
2763
|
+
};
|
|
2764
|
+
const track = (path, stats) => {
|
|
2765
|
+
if (disposed) return;
|
|
2766
|
+
const key = toKey(path);
|
|
2767
|
+
if (stats) {
|
|
2768
|
+
tracked.set(key, {
|
|
2769
|
+
mtimeMs: stats.mtimeMs,
|
|
2770
|
+
path
|
|
2771
|
+
});
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
stat(key).then((s) => {
|
|
2775
|
+
if (!disposed) tracked.set(key, {
|
|
2776
|
+
mtimeMs: s.mtimeMs,
|
|
2777
|
+
path
|
|
2778
|
+
});
|
|
2779
|
+
}, () => {});
|
|
2780
|
+
};
|
|
2781
|
+
const forget = (path) => {
|
|
2782
|
+
const key = toKey(path);
|
|
2783
|
+
tracked.delete(key);
|
|
2784
|
+
const timeout = pending.get(key);
|
|
2785
|
+
if (timeout) {
|
|
2786
|
+
clearTimeout(timeout);
|
|
2787
|
+
pending.delete(key);
|
|
2788
|
+
}
|
|
2789
|
+
};
|
|
2790
|
+
watcher.on("add", track);
|
|
2791
|
+
watcher.on("change", track);
|
|
2792
|
+
watcher.on("unlink", forget);
|
|
2793
|
+
watcher.on("raw", (event, path, details) => {
|
|
2794
|
+
if (disposed) return;
|
|
2795
|
+
if (event !== "change" && event !== "rename" && event !== "modified") return;
|
|
2796
|
+
if (typeof path !== "string" || !path) return;
|
|
2797
|
+
const file = resolveTracked(path, details);
|
|
2798
|
+
if (!file || pending.has(file)) return;
|
|
2799
|
+
const timeout = setTimeout(() => {
|
|
2800
|
+
pending.delete(file);
|
|
2801
|
+
if (disposed) return;
|
|
2802
|
+
stat(file).then((stats) => {
|
|
2803
|
+
if (disposed) return;
|
|
2804
|
+
const previous = tracked.get(file);
|
|
2805
|
+
if (!previous) return;
|
|
2806
|
+
tracked.set(file, {
|
|
2807
|
+
mtimeMs: stats.mtimeMs,
|
|
2808
|
+
path: previous.path
|
|
2809
|
+
});
|
|
2810
|
+
if (stats.mtimeMs - previous.mtimeMs <= MTIME_EPSILON) return;
|
|
2811
|
+
watcher.emit("change", previous.path, stats);
|
|
2812
|
+
watcher.emit("all", "change", previous.path, stats);
|
|
2813
|
+
}, () => {});
|
|
2814
|
+
}, RECHECK_DELAY);
|
|
2815
|
+
timeout.unref();
|
|
2816
|
+
pending.set(file, timeout);
|
|
2817
|
+
});
|
|
2818
|
+
return () => {
|
|
2819
|
+
disposed = true;
|
|
2820
|
+
for (const timeout of pending.values()) clearTimeout(timeout);
|
|
2821
|
+
pending.clear();
|
|
2822
|
+
tracked.clear();
|
|
2823
|
+
};
|
|
2824
|
+
}
|
|
2825
|
+
//#endregion
|
|
2630
2826
|
//#region src/diagnostics/build.ts
|
|
2631
2827
|
/**
|
|
2632
2828
|
* B1xxx
|
|
@@ -2941,8 +3137,18 @@ const bundlerDiagnostics = /* #__PURE__ */ defineDiagnostics({
|
|
|
2941
3137
|
why: "The server webpack build does not externalize dependencies.",
|
|
2942
3138
|
fix: "Externalize dependencies in the server build (`externals`) for better build performance.",
|
|
2943
3139
|
docs: false
|
|
3140
|
+
},
|
|
3141
|
+
NUXT_B7020: {
|
|
3142
|
+
why: "The client build manifest is disabled, but Nuxt requires it to render the correct assets for each route.",
|
|
3143
|
+
fix: "Remove any `build.manifest: false` override from your `nuxt.config` `vite` options or from a Vite plugin `config`/`configEnvironment` hook.",
|
|
3144
|
+
docs: false
|
|
3145
|
+
},
|
|
3146
|
+
NUXT_B7021: {
|
|
3147
|
+
why: (p) => `The client build manifest was expected at \`${p.manifestFile}\` but was not emitted by the client build.`,
|
|
3148
|
+
fix: "Check that no Vite plugin removes or renames the client build manifest in a `generateBundle`/`writeBundle` hook. If this happens with no such plugin, please report it at https://github.com/nuxt/nuxt/issues.",
|
|
3149
|
+
docs: false
|
|
2944
3150
|
}
|
|
2945
3151
|
}
|
|
2946
3152
|
});
|
|
2947
3153
|
//#endregion
|
|
2948
|
-
export { DEFAULT_JSX_FILE_EXTENSIONS, DEFAULT_JS_FILE_EXTENSIONS, addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildDiagnostics, buildNuxt, bundlerDiagnostics, checkNuxtCompatibility, componentDiagnostics, configDiagnostics, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, headDiagnostics, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, packageName, pageDiagnostics, pluginDiagnostics, requireModule, resolveAlias, resolveDeclarationPath, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, resolveTypePaths, runWithNuxtContext, setBuildOutput, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateAppConfig, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
|
|
3154
|
+
export { DEFAULT_JSX_FILE_EXTENSIONS, DEFAULT_JS_FILE_EXTENSIONS, addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildDiagnostics, buildNuxt, bundlerDiagnostics, checkNuxtCompatibility, componentDiagnostics, configDiagnostics, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, headDiagnostics, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, packageName, pageDiagnostics, pluginDiagnostics, recoverThrottledChanges, requireModule, resolveAlias, resolveDeclarationPath, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, resolveTypePaths, runWithNuxtContext, setBuildOutput, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateAppConfig, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/nuxt__kit",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.2-depup.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
"consola": "^3.4.2",
|
|
26
26
|
"defu": "^6.1.7",
|
|
27
27
|
"destr": "^2.0.5",
|
|
28
|
-
"errx": "^0.1.
|
|
29
|
-
"exsolve": "^1.1.
|
|
28
|
+
"errx": "^0.1.2",
|
|
29
|
+
"exsolve": "^1.1.1",
|
|
30
30
|
"ignore": "^7.0.6",
|
|
31
31
|
"jiti": "^2.7.0",
|
|
32
32
|
"klona": "^2.0.6",
|
|
33
33
|
"mlly": "^1.8.2",
|
|
34
34
|
"nostics": "^1.2.0",
|
|
35
|
-
"ohash": "^2.0.
|
|
35
|
+
"ohash": "^2.0.12",
|
|
36
36
|
"pathe": "^2.0.3",
|
|
37
37
|
"pkg-types": "^2.3.1",
|
|
38
38
|
"rc9": "^3.0.1",
|
|
@@ -41,17 +41,18 @@
|
|
|
41
41
|
"ufo": "^1.6.4",
|
|
42
42
|
"unctx": "^3.0.0",
|
|
43
43
|
"untyped": "^2.0.0",
|
|
44
|
-
"verkit": "^0.
|
|
44
|
+
"verkit": "^0.4.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
+
"chokidar": "^5.0.0",
|
|
47
48
|
"hookable": "^6.1.1",
|
|
48
49
|
"nitropack": "2.13.4",
|
|
49
|
-
"tsdown": "0.22.
|
|
50
|
-
"unimport": "^6.
|
|
51
|
-
"vite": "^8.
|
|
50
|
+
"tsdown": "0.22.14",
|
|
51
|
+
"unimport": "^6.4.0",
|
|
52
|
+
"vite": "^8.2.0",
|
|
52
53
|
"vitest": "4.1.10",
|
|
53
|
-
"webpack": "^5.
|
|
54
|
-
"@nuxt/schema": "4.5.
|
|
54
|
+
"webpack": "^5.109.2",
|
|
55
|
+
"@nuxt/schema": "4.5.2"
|
|
55
56
|
},
|
|
56
57
|
"engines": {
|
|
57
58
|
"node": ">=18.12.0"
|
|
@@ -74,15 +75,19 @@
|
|
|
74
75
|
"from": "^3.3.4",
|
|
75
76
|
"to": "^4.0.0-beta.5"
|
|
76
77
|
},
|
|
78
|
+
"ohash": {
|
|
79
|
+
"from": "^2.0.11",
|
|
80
|
+
"to": "^2.0.12"
|
|
81
|
+
},
|
|
77
82
|
"verkit": {
|
|
78
|
-
"from": "^0.
|
|
79
|
-
"to": "^0.
|
|
83
|
+
"from": "^0.3.1",
|
|
84
|
+
"to": "^0.4.0"
|
|
80
85
|
}
|
|
81
86
|
},
|
|
82
|
-
"depsUpdated":
|
|
87
|
+
"depsUpdated": 3,
|
|
83
88
|
"originalPackage": "@nuxt/kit",
|
|
84
|
-
"originalVersion": "4.5.
|
|
85
|
-
"processedAt": "2026-
|
|
89
|
+
"originalVersion": "4.5.2",
|
|
90
|
+
"processedAt": "2026-08-15T16:05:28.364Z",
|
|
86
91
|
"smokeTest": "passed"
|
|
87
92
|
}
|
|
88
93
|
}
|