nuxt-i18n-micro 3.26.0 → 3.27.0
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/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/fcc4b5e8-a04c-49bd-9cb3-620fcda4d432.json +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +36 -7
- package/dist/runtime/devtools/bridge.d.ts +11 -0
- package/dist/runtime/devtools/bridge.js +8 -0
- package/dist/runtime/devtools/vue-devtools.d.ts +18 -0
- package/dist/runtime/devtools/vue-devtools.js +261 -0
- package/dist/runtime/plugins/01.plugin.js +8 -0
- package/dist/runtime/plugins/04.vue-devtools.d.ts +2 -0
- package/dist/runtime/plugins/04.vue-devtools.js +60 -0
- package/dist/runtime/utils/nuxt-i18n.d.ts +9 -2
- package/dist/runtime/utils/nuxt-i18n.js +37 -4
- package/package.json +24 -23
- package/dist/client/_nuxt/builds/meta/24f3c578-f02b-41bc-953a-c7ff7b504d56.json +0 -1
package/dist/client/200.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"fcc4b5e8-a04c-49bd-9cb3-620fcda4d432",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1785932351898,false]</script></body></html>
|
package/dist/client/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"fcc4b5e8-a04c-49bd-9cb3-620fcda4d432",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1785932351899,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"fcc4b5e8-a04c-49bd-9cb3-620fcda4d432","timestamp":1785932349529}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"fcc4b5e8-a04c-49bd-9cb3-620fcda4d432","timestamp":1785932349529,"prerendered":[]}
|
package/dist/client/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"}}</script><link rel="stylesheet" href="/__nuxt-i18n-micro/_nuxt/entry.CJGrD2VA.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DBXvRcU1.js"><script type="module" src="/__nuxt-i18n-micro/_nuxt/Bwak6g3b.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-i18n-micro/_nuxt/error-500.BcWSpGYy.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/p3h4sA5-.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DbtvxgAm.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"fcc4b5e8-a04c-49bd-9cb3-620fcda4d432",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1785932351899,false]</script></body></html>
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import fs__default, { readFileSync, mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
3
|
-
import path, { resolve, join
|
|
3
|
+
import path, { dirname, resolve, join } from 'node:path';
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
5
|
import { defaultPlural, isNoPrefixStrategy, withPrefixStrategy } from '@i18n-micro/core';
|
|
6
6
|
import { generateHmrPlugin } from '@i18n-micro/hmr/generate-plugin';
|
|
@@ -22,12 +22,31 @@ import { parse } from '@vue/compiler-sfc';
|
|
|
22
22
|
const DEVTOOLS_UI_PORT = 3030;
|
|
23
23
|
const DEVTOOLS_UI_ROUTE = "/__nuxt-i18n-micro";
|
|
24
24
|
const DEVTOOLS_RPC_NAMESPACE = "nuxt-i18n-micro";
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const packageRoot = resolve(thisDir, "..");
|
|
27
|
+
const clientDir = resolveClientDir();
|
|
28
|
+
function resolveClientDir() {
|
|
29
|
+
const candidates = [
|
|
30
|
+
resolve(thisDir, "client"),
|
|
31
|
+
// dist/client next to dist/module.mjs
|
|
32
|
+
resolve(thisDir, "../dist/client"),
|
|
33
|
+
// src/devtools.ts → repo dist/client
|
|
34
|
+
resolve(thisDir, "../client/dist")
|
|
35
|
+
// client/dist symlink used in-repo
|
|
36
|
+
];
|
|
37
|
+
return candidates.find((dir) => fs.existsSync(path.join(dir, "index.html"))) ?? candidates[0];
|
|
38
|
+
}
|
|
39
|
+
function resolveClientPackageDir() {
|
|
40
|
+
return resolve(packageRoot, "client");
|
|
41
|
+
}
|
|
42
|
+
function useLiveClientDevServer() {
|
|
43
|
+
return process.env.I18N_DEVTOOLS_CLIENT_DEV === "1" || process.env.I18N_DEVTOOLS_CLIENT_DEV === "true";
|
|
44
|
+
}
|
|
27
45
|
function setupDevToolsUI(options, rootDirs) {
|
|
28
46
|
const nuxt = useNuxt();
|
|
29
|
-
const hasPrebuiltClient = fs.existsSync(clientDir);
|
|
30
|
-
|
|
47
|
+
const hasPrebuiltClient = fs.existsSync(path.join(clientDir, "index.html"));
|
|
48
|
+
const liveClient = useLiveClientDevServer();
|
|
49
|
+
if (hasPrebuiltClient && !liveClient) {
|
|
31
50
|
addDevServerHandler({
|
|
32
51
|
route: DEVTOOLS_UI_ROUTE,
|
|
33
52
|
handler: fromNodeMiddleware(sirv(clientDir, { dev: true, single: true }))
|
|
@@ -37,7 +56,7 @@ function setupDevToolsUI(options, rootDirs) {
|
|
|
37
56
|
{
|
|
38
57
|
command: "npx",
|
|
39
58
|
args: ["nuxi", "dev", "--port", String(DEVTOOLS_UI_PORT)],
|
|
40
|
-
cwd:
|
|
59
|
+
cwd: resolveClientPackageDir()
|
|
41
60
|
},
|
|
42
61
|
{ id: "nuxt-i18n-micro:client", name: "i18n Micro DevTools UI" }
|
|
43
62
|
);
|
|
@@ -46,7 +65,9 @@ function setupDevToolsUI(options, rootDirs) {
|
|
|
46
65
|
// `addDevServerHandler` strips the mount prefix, so `event.path` arrives as `/`
|
|
47
66
|
// or `/_nuxt/...` and the route has to be put back on for the client dev server,
|
|
48
67
|
// which serves itself under that same base.
|
|
49
|
-
handler: defineEventHandler(
|
|
68
|
+
handler: defineEventHandler(
|
|
69
|
+
(event) => proxyRequest(event, `http://localhost:${DEVTOOLS_UI_PORT}${joinURL(DEVTOOLS_UI_ROUTE, event.path || "/")}`)
|
|
70
|
+
)
|
|
50
71
|
});
|
|
51
72
|
}
|
|
52
73
|
addCustomTab({
|
|
@@ -852,6 +873,14 @@ const module$1 = defineNuxtModule({
|
|
|
852
873
|
order: 3
|
|
853
874
|
});
|
|
854
875
|
}
|
|
876
|
+
if (nuxt.options.dev && options.plugin !== false && options.vueDevtools !== false) {
|
|
877
|
+
addPlugin({
|
|
878
|
+
src: resolver.resolve("./runtime/plugins/04.vue-devtools"),
|
|
879
|
+
name: "i18n-vue-devtools",
|
|
880
|
+
mode: "client",
|
|
881
|
+
order: 5
|
|
882
|
+
});
|
|
883
|
+
}
|
|
855
884
|
addPlugin({
|
|
856
885
|
src: resolver.resolve("./runtime/plugins/06.redirect"),
|
|
857
886
|
mode: "server",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ModuleOptionsExtend } from '@i18n-micro/types';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import type { NuxtI18n } from '../utils/nuxt-i18n.js';
|
|
4
|
+
export declare const I18N_DEVTOOLS_BRIDGE_KEY = "i18n-micro-devtools-bridge";
|
|
5
|
+
export interface I18nDevtoolsBridge {
|
|
6
|
+
i18n: NuxtI18n;
|
|
7
|
+
i18nConfig: ModuleOptionsExtend;
|
|
8
|
+
localeState: Ref<string | null>;
|
|
9
|
+
}
|
|
10
|
+
export declare function setI18nDevtoolsBridge(value: I18nDevtoolsBridge | null): void;
|
|
11
|
+
export declare function getI18nDevtoolsBridge(): I18nDevtoolsBridge | null;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ModuleOptionsExtend } from '@i18n-micro/types';
|
|
2
|
+
import type { App } from 'vue';
|
|
3
|
+
import type { I18nContextChangeReason, NuxtI18n } from '../utils/nuxt-i18n.js';
|
|
4
|
+
export interface VueI18nDevtoolsContext {
|
|
5
|
+
app: App;
|
|
6
|
+
i18n: NuxtI18n;
|
|
7
|
+
i18nConfig: ModuleOptionsExtend;
|
|
8
|
+
onContextChange: (listener: (reason: I18nContextChangeReason) => void) => () => void;
|
|
9
|
+
onMissingKey: (listener: (locale: string, key: string, routeName: string) => void) => () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface VueI18nDevtoolsNotifier {
|
|
12
|
+
notifyLocaleSwitch: (from: string, to: string, routeName: string) => void;
|
|
13
|
+
notifyLoad: (locale: string, routeName: string, keyCount: number) => void;
|
|
14
|
+
notifyTranslate: (key: string, result: unknown) => void;
|
|
15
|
+
refreshInspector: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function setupVueI18nDevtools(ctx: VueI18nDevtoolsContext): Promise<VueI18nDevtoolsNotifier | null>;
|
|
18
|
+
export declare function countLoadedTranslationKeys(i18n: NuxtI18n, locale: string, routeName: string): number;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildInspectorState,
|
|
3
|
+
buildInspectorTree,
|
|
4
|
+
countTranslationKeys,
|
|
5
|
+
getByInspectorPath,
|
|
6
|
+
parseInspectorNodeId
|
|
7
|
+
} from "@i18n-micro/core/devtools";
|
|
8
|
+
const INSPECTOR_ID = "i18n-micro-inspector";
|
|
9
|
+
const PLUGIN_ID = "nuxt-i18n-micro";
|
|
10
|
+
const TIMELINE_LAYER_ID = "i18n-micro";
|
|
11
|
+
const isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
12
|
+
function toInspectorState(snapshot) {
|
|
13
|
+
const groups = buildInspectorState(snapshot);
|
|
14
|
+
const state = {};
|
|
15
|
+
for (const [group, entries] of Object.entries(groups)) {
|
|
16
|
+
state[group] = entries.map((entry) => ({
|
|
17
|
+
key: entry.key,
|
|
18
|
+
value: entry.value
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
function createSnapshot(i18n, i18nConfig) {
|
|
24
|
+
return {
|
|
25
|
+
locale: i18n.getCurrentLocale(),
|
|
26
|
+
routeName: i18n.getCurrentRouteName() || "index",
|
|
27
|
+
strategy: i18nConfig.strategy,
|
|
28
|
+
defaultLocale: i18nConfig.defaultLocale,
|
|
29
|
+
fallbackLocale: i18nConfig.fallbackLocale,
|
|
30
|
+
cachedChunks: i18n.storage.translations.size,
|
|
31
|
+
locales: (i18nConfig.locales ?? []).map((locale) => ({
|
|
32
|
+
code: locale.code,
|
|
33
|
+
displayName: locale.displayName,
|
|
34
|
+
disabled: locale.disabled
|
|
35
|
+
}))
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function buildNodeState(i18n, i18nConfig, nodeId) {
|
|
39
|
+
const parsed = parseInspectorNodeId(nodeId);
|
|
40
|
+
if (parsed.kind === "active") {
|
|
41
|
+
return {
|
|
42
|
+
Translations: objectToStateEntries(i18n.resolveTranslations())
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (parsed.kind === "locale" && parsed.locale) {
|
|
46
|
+
const locale = parsed.locale;
|
|
47
|
+
const configured = (i18nConfig.locales ?? []).find((item) => item.code === locale);
|
|
48
|
+
const prefix = `${locale}:`;
|
|
49
|
+
const chunks = [];
|
|
50
|
+
for (const [cacheKey, data] of i18n.storage.translations) {
|
|
51
|
+
if (!cacheKey.startsWith(prefix)) continue;
|
|
52
|
+
const routeName = cacheKey.slice(prefix.length) || "index";
|
|
53
|
+
chunks.push({
|
|
54
|
+
key: routeName,
|
|
55
|
+
value: `${countTranslationKeys(data)} keys`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
chunks.sort((a, b) => a.key.localeCompare(b.key));
|
|
59
|
+
return {
|
|
60
|
+
Locale: [
|
|
61
|
+
{ key: "code", value: locale },
|
|
62
|
+
{ key: "displayName", value: configured?.displayName ?? locale },
|
|
63
|
+
{ key: "disabled", value: Boolean(configured?.disabled) },
|
|
64
|
+
{ key: "isActive", value: i18n.getCurrentLocale() === locale },
|
|
65
|
+
{ key: "loadedChunks", value: chunks.length }
|
|
66
|
+
],
|
|
67
|
+
Chunks: chunks.length ? chunks : [{ key: "\u2014", value: "No translation chunks loaded for this locale yet" }]
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (parsed.kind === "chunk" && parsed.locale) {
|
|
71
|
+
const routeName = parsed.routeName || "index";
|
|
72
|
+
const cacheKey = `${parsed.locale}:${routeName}`;
|
|
73
|
+
const chunk = i18n.storage.translations.get(cacheKey);
|
|
74
|
+
if (!chunk) {
|
|
75
|
+
return {
|
|
76
|
+
Chunk: [
|
|
77
|
+
{ key: "cacheKey", value: cacheKey },
|
|
78
|
+
{ key: "status", value: "not loaded" }
|
|
79
|
+
]
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const entries = objectToStateEntries(chunk);
|
|
83
|
+
return {
|
|
84
|
+
Chunk: [
|
|
85
|
+
{ key: "cacheKey", value: cacheKey },
|
|
86
|
+
{ key: "keys", value: countTranslationKeys(chunk) },
|
|
87
|
+
{
|
|
88
|
+
key: "isActive",
|
|
89
|
+
value: i18n.getCurrentLocale() === parsed.locale && (i18n.getCurrentRouteName() || "index") === routeName
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
Translations: entries.length ? entries : [{ key: "\u2014", value: "Chunk is loaded but empty" }]
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (parsed.kind === "key" && parsed.locale) {
|
|
96
|
+
const routeName = parsed.routeName || "index";
|
|
97
|
+
const segments = parsed.segments ?? [];
|
|
98
|
+
const chunk = i18n.storage.translations.get(`${parsed.locale}:${routeName}`);
|
|
99
|
+
const isActive = i18n.getCurrentLocale() === parsed.locale && (i18n.getCurrentRouteName() || "index") === routeName;
|
|
100
|
+
const source = isActive ? i18n.resolveTranslations() : chunk ?? {};
|
|
101
|
+
const value = segments.length ? getByInspectorPath(source, segments) : source;
|
|
102
|
+
if (isPlainObject(value)) {
|
|
103
|
+
return { [segments.join(".") || "root"]: objectToStateEntries(value) };
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
Value: [{ key: segments.join(".") || "value", value }]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return toInspectorState(createSnapshot(i18n, i18nConfig));
|
|
110
|
+
}
|
|
111
|
+
function objectToStateEntries(obj, limit = 500) {
|
|
112
|
+
const entries = [];
|
|
113
|
+
let truncated = false;
|
|
114
|
+
const queue = [{ node: obj, prefix: "" }];
|
|
115
|
+
while (queue.length > 0) {
|
|
116
|
+
const { node, prefix } = queue.shift();
|
|
117
|
+
const nested = [];
|
|
118
|
+
for (const key of Object.keys(node)) {
|
|
119
|
+
if (key === "__proto__") continue;
|
|
120
|
+
if (entries.length >= limit) {
|
|
121
|
+
truncated = true;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
125
|
+
const value = node[key];
|
|
126
|
+
if (isPlainObject(value)) {
|
|
127
|
+
nested.push({ node: value, prefix: path });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
entries.push({ key: path, value });
|
|
131
|
+
}
|
|
132
|
+
if (truncated) break;
|
|
133
|
+
queue.push(...nested);
|
|
134
|
+
}
|
|
135
|
+
entries.sort((a, b) => a.key.localeCompare(b.key));
|
|
136
|
+
if (truncated) {
|
|
137
|
+
entries.push({
|
|
138
|
+
key: "\u2026",
|
|
139
|
+
value: `Showing first ${limit} leaves (nested keys flattened)`
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return entries;
|
|
143
|
+
}
|
|
144
|
+
export async function setupVueI18nDevtools(ctx) {
|
|
145
|
+
if (!import.meta.dev || import.meta.server) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
let notifier = null;
|
|
149
|
+
try {
|
|
150
|
+
const { setupDevtoolsPlugin } = await import("@vue/devtools-api");
|
|
151
|
+
setupDevtoolsPlugin(
|
|
152
|
+
{
|
|
153
|
+
id: PLUGIN_ID,
|
|
154
|
+
label: "i18n Micro",
|
|
155
|
+
packageName: "nuxt-i18n-micro",
|
|
156
|
+
homepage: "https://s00d.github.io/nuxt-i18n-micro/",
|
|
157
|
+
logo: "https://s00d.github.io/nuxt-i18n-micro/favicon.svg",
|
|
158
|
+
app: ctx.app,
|
|
159
|
+
enableEarlyProxy: true
|
|
160
|
+
},
|
|
161
|
+
(api) => {
|
|
162
|
+
const refreshInspector = () => {
|
|
163
|
+
api.sendInspectorTree(INSPECTOR_ID);
|
|
164
|
+
api.sendInspectorState(INSPECTOR_ID);
|
|
165
|
+
};
|
|
166
|
+
api.addInspector({
|
|
167
|
+
id: INSPECTOR_ID,
|
|
168
|
+
label: "i18n Micro",
|
|
169
|
+
icon: "carbon:language",
|
|
170
|
+
actions: [
|
|
171
|
+
{
|
|
172
|
+
icon: "refresh",
|
|
173
|
+
tooltip: "Refresh inspector",
|
|
174
|
+
action: refreshInspector
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
api.addTimelineLayer({
|
|
179
|
+
id: TIMELINE_LAYER_ID,
|
|
180
|
+
label: "i18n Micro",
|
|
181
|
+
color: 4372611
|
|
182
|
+
});
|
|
183
|
+
api.on.getInspectorTree((payload) => {
|
|
184
|
+
if (payload.inspectorId !== INSPECTOR_ID) return;
|
|
185
|
+
payload.rootNodes = buildInspectorTree({
|
|
186
|
+
nodeId: "root",
|
|
187
|
+
storage: ctx.i18n.storage,
|
|
188
|
+
configuredLocales: ctx.i18nConfig.locales ?? [],
|
|
189
|
+
activeLocale: ctx.i18n.getCurrentLocale(),
|
|
190
|
+
activeRouteName: ctx.i18n.getCurrentRouteName() || "index",
|
|
191
|
+
activeTranslations: ctx.i18n.resolveTranslations()
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
api.on.getInspectorState((payload) => {
|
|
195
|
+
if (payload.inspectorId !== INSPECTOR_ID) return;
|
|
196
|
+
payload.state = payload.nodeId ? buildNodeState(ctx.i18n, ctx.i18nConfig, payload.nodeId) : toInspectorState(createSnapshot(ctx.i18n, ctx.i18nConfig));
|
|
197
|
+
});
|
|
198
|
+
ctx.onContextChange(() => {
|
|
199
|
+
refreshInspector();
|
|
200
|
+
});
|
|
201
|
+
ctx.onMissingKey((locale, key, routeName) => {
|
|
202
|
+
api.addTimelineEvent({
|
|
203
|
+
layerId: TIMELINE_LAYER_ID,
|
|
204
|
+
event: {
|
|
205
|
+
time: api.now(),
|
|
206
|
+
title: "Missing translation",
|
|
207
|
+
subtitle: key,
|
|
208
|
+
data: { locale, key, routeName }
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
notifier = {
|
|
213
|
+
notifyLocaleSwitch(from, to, routeName) {
|
|
214
|
+
api.addTimelineEvent({
|
|
215
|
+
layerId: TIMELINE_LAYER_ID,
|
|
216
|
+
event: {
|
|
217
|
+
time: api.now(),
|
|
218
|
+
title: "Locale switch",
|
|
219
|
+
subtitle: `${from || "\u2014"} \u2192 ${to}`,
|
|
220
|
+
data: { from, to, routeName }
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
refreshInspector();
|
|
224
|
+
},
|
|
225
|
+
notifyLoad(locale, routeName, keyCount) {
|
|
226
|
+
api.addTimelineEvent({
|
|
227
|
+
layerId: TIMELINE_LAYER_ID,
|
|
228
|
+
event: {
|
|
229
|
+
time: api.now(),
|
|
230
|
+
title: "Translations loaded",
|
|
231
|
+
subtitle: `${locale}:${routeName}`,
|
|
232
|
+
data: { locale, routeName, keyCount }
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
refreshInspector();
|
|
236
|
+
},
|
|
237
|
+
notifyTranslate(key, result) {
|
|
238
|
+
api.addTimelineEvent({
|
|
239
|
+
layerId: TIMELINE_LAYER_ID,
|
|
240
|
+
event: {
|
|
241
|
+
time: api.now(),
|
|
242
|
+
title: "$t",
|
|
243
|
+
subtitle: key,
|
|
244
|
+
data: { key, result }
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
refreshInspector
|
|
249
|
+
};
|
|
250
|
+
refreshInspector();
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
} catch {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return notifier;
|
|
257
|
+
}
|
|
258
|
+
export function countLoadedTranslationKeys(i18n, locale, routeName) {
|
|
259
|
+
const chunk = i18n.storage.translations.get(i18n.getCacheKey(locale, routeName));
|
|
260
|
+
return countTranslationKeys(chunk);
|
|
261
|
+
}
|
|
@@ -7,6 +7,7 @@ import { createError, defineNuxtPlugin, navigateTo, useRouter, useRuntimeConfig
|
|
|
7
7
|
import { useI18nHead } from "../composables/useI18nHead.js";
|
|
8
8
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
9
9
|
import { createNuxtI18nPluginApi, NuxtI18n, NuxtTranslationLoader } from "../utils/nuxt-i18n.js";
|
|
10
|
+
import { setI18nDevtoolsBridge } from "../devtools/bridge.js";
|
|
10
11
|
import { translationStorage } from "../utils/storage.js";
|
|
11
12
|
const isDev = process.env.NODE_ENV !== "production";
|
|
12
13
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
@@ -102,6 +103,13 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
102
103
|
customMissingHandler.value = handler;
|
|
103
104
|
}
|
|
104
105
|
});
|
|
106
|
+
if (import.meta.dev && import.meta.client) {
|
|
107
|
+
setI18nDevtoolsBridge({
|
|
108
|
+
i18n,
|
|
109
|
+
i18nConfig,
|
|
110
|
+
localeState
|
|
111
|
+
});
|
|
112
|
+
}
|
|
105
113
|
router.beforeEach(async (to, from) => {
|
|
106
114
|
if (to.name !== from.name) {
|
|
107
115
|
i18nRouteParams.value = {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useNuxtApp } from "#imports";
|
|
2
|
+
import { watch } from "vue";
|
|
3
|
+
import { getI18nDevtoolsBridge } from "../devtools/bridge.js";
|
|
4
|
+
import { countLoadedTranslationKeys, setupVueI18nDevtools } from "../devtools/vue-devtools.js";
|
|
5
|
+
export default defineNuxtPlugin({
|
|
6
|
+
name: "i18n-vue-devtools",
|
|
7
|
+
dependsOn: ["i18n-plugin-loader"],
|
|
8
|
+
async setup() {
|
|
9
|
+
if (!import.meta.dev || import.meta.server) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nuxtApp = useNuxtApp();
|
|
13
|
+
const bridge = getI18nDevtoolsBridge();
|
|
14
|
+
if (!bridge) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const notifier = await setupVueI18nDevtools({
|
|
18
|
+
app: nuxtApp.vueApp,
|
|
19
|
+
i18n: bridge.i18n,
|
|
20
|
+
i18nConfig: bridge.i18nConfig,
|
|
21
|
+
onContextChange: (listener) => bridge.i18n.onContextChange(listener),
|
|
22
|
+
onMissingKey: (listener) => bridge.i18n.onMissingKey(listener)
|
|
23
|
+
});
|
|
24
|
+
if (!notifier) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const notifyCurrentLoad = () => {
|
|
28
|
+
const locale = bridge.i18n.getCurrentLocale();
|
|
29
|
+
const routeName = bridge.i18n.getCurrentRouteName() || "index";
|
|
30
|
+
notifier.notifyLoad(locale, routeName, countLoadedTranslationKeys(bridge.i18n, locale, routeName));
|
|
31
|
+
};
|
|
32
|
+
notifyCurrentLoad();
|
|
33
|
+
watch(
|
|
34
|
+
() => bridge.localeState.value,
|
|
35
|
+
(to, from) => {
|
|
36
|
+
if (to && from && to !== from) {
|
|
37
|
+
notifier.notifyLocaleSwitch(from, to, bridge.i18n.getCurrentRouteName() || "index");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
bridge.i18n.onContextChange((reason) => {
|
|
42
|
+
if (reason === "load") {
|
|
43
|
+
notifyCurrentLoad();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
notifier.refreshInspector();
|
|
47
|
+
});
|
|
48
|
+
if (bridge.i18nConfig.debug) {
|
|
49
|
+
const wrapTranslate = (translate) => ((key, ...args) => {
|
|
50
|
+
const result = translate(key, ...args);
|
|
51
|
+
notifier.notifyTranslate(key, result);
|
|
52
|
+
return result;
|
|
53
|
+
});
|
|
54
|
+
const app = nuxtApp;
|
|
55
|
+
app.$t = wrapTranslate(app.$t.bind(app));
|
|
56
|
+
app.$ts = wrapTranslate(app.$ts.bind(app));
|
|
57
|
+
app.$tc = wrapTranslate(app.$tc.bind(app));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
@@ -10,6 +10,8 @@ export interface RouteTranslationContext {
|
|
|
10
10
|
}
|
|
11
11
|
export type GetRouteTranslationContext = (route?: unknown) => RouteTranslationContext;
|
|
12
12
|
export type LoadTranslationsChunk = (locale: string, routeName?: string) => Promise<Record<string, unknown>>;
|
|
13
|
+
/** Why the active translation context changed — used by Vue DevTools timeline. */
|
|
14
|
+
export type I18nContextChangeReason = 'load' | 'refresh';
|
|
13
15
|
export interface NuxtI18nOptions extends BaseI18nOptions {
|
|
14
16
|
}
|
|
15
17
|
export declare class NuxtI18n extends BaseI18n {
|
|
@@ -26,6 +28,8 @@ export declare class NuxtI18n extends BaseI18n {
|
|
|
26
28
|
private currentLocale;
|
|
27
29
|
private currentRouteName;
|
|
28
30
|
private resolveRouteContext?;
|
|
31
|
+
private readonly contextListeners;
|
|
32
|
+
private missingKeyListener?;
|
|
29
33
|
constructor(options?: NuxtI18nOptions);
|
|
30
34
|
setRouteContextResolver(resolver: GetRouteTranslationContext): void;
|
|
31
35
|
getCacheKey(locale: string, routeName?: string): string;
|
|
@@ -48,6 +52,9 @@ export declare class NuxtI18n extends BaseI18n {
|
|
|
48
52
|
getRoute(): string;
|
|
49
53
|
getCurrentLocale(): string;
|
|
50
54
|
getCurrentRouteName(): string;
|
|
55
|
+
onContextChange(listener: (reason: I18nContextChangeReason) => void): () => void;
|
|
56
|
+
onMissingKey(listener: (locale: string, key: string, routeName: string) => void): () => void;
|
|
57
|
+
private notifyContextChange;
|
|
51
58
|
/**
|
|
52
59
|
* Hot-reload the active dictionary for the next route — replace, don't merge.
|
|
53
60
|
*
|
|
@@ -82,11 +89,11 @@ export declare class NuxtI18n extends BaseI18n {
|
|
|
82
89
|
* first makes the change vanish on the next navigation.
|
|
83
90
|
*/
|
|
84
91
|
setTranslation(key: TranslationKey, value: unknown): void;
|
|
85
|
-
protected getMissingContext(
|
|
92
|
+
protected getMissingContext(routeContext?: unknown): {
|
|
86
93
|
locale: string;
|
|
87
94
|
routeName: string;
|
|
88
95
|
};
|
|
89
|
-
protected warnMissing(key: TranslationKey): void;
|
|
96
|
+
protected warnMissing(key: TranslationKey, routeContext?: unknown): void;
|
|
90
97
|
clearCache(): void;
|
|
91
98
|
}
|
|
92
99
|
export interface NuxtTranslationLoaderOptions {
|
|
@@ -44,6 +44,8 @@ export class NuxtI18n extends BaseI18n {
|
|
|
44
44
|
currentLocale = "";
|
|
45
45
|
currentRouteName = "";
|
|
46
46
|
resolveRouteContext;
|
|
47
|
+
contextListeners = /* @__PURE__ */ new Set();
|
|
48
|
+
missingKeyListener;
|
|
47
49
|
constructor(options = {}) {
|
|
48
50
|
const storage = {
|
|
49
51
|
translations: /* @__PURE__ */ new Map()
|
|
@@ -105,6 +107,25 @@ export class NuxtI18n extends BaseI18n {
|
|
|
105
107
|
getCurrentRouteName() {
|
|
106
108
|
return this.currentRouteName;
|
|
107
109
|
}
|
|
110
|
+
onContextChange(listener) {
|
|
111
|
+
this.contextListeners.add(listener);
|
|
112
|
+
return () => {
|
|
113
|
+
this.contextListeners.delete(listener);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
onMissingKey(listener) {
|
|
117
|
+
this.missingKeyListener = listener;
|
|
118
|
+
return () => {
|
|
119
|
+
if (this.missingKeyListener === listener) {
|
|
120
|
+
this.missingKeyListener = void 0;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
notifyContextChange(reason) {
|
|
125
|
+
for (const listener of this.contextListeners) {
|
|
126
|
+
listener(reason);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
108
129
|
/**
|
|
109
130
|
* Hot-reload the active dictionary for the next route — replace, don't merge.
|
|
110
131
|
*
|
|
@@ -122,23 +143,27 @@ export class NuxtI18n extends BaseI18n {
|
|
|
122
143
|
this.currentLocale = locale;
|
|
123
144
|
this.currentRouteName = routeName || "";
|
|
124
145
|
triggerRef(this.contextSignal);
|
|
146
|
+
this.notifyContextChange("load");
|
|
125
147
|
}
|
|
126
148
|
/** The outgoing page has unmounted, so its keys must stop resolving. */
|
|
127
149
|
finishTransition() {
|
|
128
150
|
if (this.outgoingTranslations === null) return;
|
|
129
151
|
this.outgoingTranslations = null;
|
|
130
152
|
triggerRef(this.contextSignal);
|
|
153
|
+
this.notifyContextChange("refresh");
|
|
131
154
|
}
|
|
132
155
|
mergeTranslations(newTranslations) {
|
|
133
156
|
this.mergeChunk(this.currentLocale, this.currentRouteName, newTranslations);
|
|
134
157
|
this.cachedTranslations = deepMergeTranslationsRecursive(this.cachedTranslations, newTranslations);
|
|
135
158
|
triggerRef(this.contextSignal);
|
|
159
|
+
this.notifyContextChange("load");
|
|
136
160
|
}
|
|
137
161
|
async loadPageTranslations(locale, routeName, translations) {
|
|
138
162
|
this.mergeChunk(locale, routeName, translations);
|
|
139
163
|
if (locale === this.currentLocale && routeName === this.currentRouteName) {
|
|
140
164
|
this.cachedTranslations = deepMergeTranslationsRecursive(this.cachedTranslations, translations);
|
|
141
165
|
triggerRef(this.contextSignal);
|
|
166
|
+
this.notifyContextChange("load");
|
|
142
167
|
}
|
|
143
168
|
}
|
|
144
169
|
async mergeTranslationAsync(locale, routeName, newTranslations, loadIfMissing) {
|
|
@@ -150,6 +175,7 @@ export class NuxtI18n extends BaseI18n {
|
|
|
150
175
|
if (locale === this.currentLocale && routeName === this.currentRouteName) {
|
|
151
176
|
this.cachedTranslations = deepMergeTranslationsRecursive(this.cachedTranslations, newTranslations);
|
|
152
177
|
triggerRef(this.contextSignal);
|
|
178
|
+
this.notifyContextChange("load");
|
|
153
179
|
}
|
|
154
180
|
}
|
|
155
181
|
tForRoute(route) {
|
|
@@ -201,18 +227,24 @@ export class NuxtI18n extends BaseI18n {
|
|
|
201
227
|
setTranslationAtKey(this.getChunk(this.currentLocale, this.currentRouteName), String(key), value)
|
|
202
228
|
);
|
|
203
229
|
triggerRef(this.contextSignal);
|
|
230
|
+
this.notifyContextChange("refresh");
|
|
204
231
|
}
|
|
205
|
-
getMissingContext(
|
|
232
|
+
getMissingContext(routeContext) {
|
|
233
|
+
if (routeContext && this.resolveRouteContext) {
|
|
234
|
+
return this.resolveRouteContext(routeContext);
|
|
235
|
+
}
|
|
206
236
|
return { locale: this.currentLocale, routeName: this.currentRouteName };
|
|
207
237
|
}
|
|
208
|
-
warnMissing(key) {
|
|
238
|
+
warnMissing(key, routeContext) {
|
|
239
|
+
const { locale, routeName } = this.getMissingContext(routeContext);
|
|
240
|
+
this.missingKeyListener?.(locale, String(key), routeName);
|
|
209
241
|
const customHandler = this.getCustomMissingHandler?.();
|
|
210
242
|
if (customHandler) {
|
|
211
|
-
customHandler(
|
|
243
|
+
customHandler(locale, String(key), routeName);
|
|
212
244
|
return;
|
|
213
245
|
}
|
|
214
246
|
if (this.missingWarn && process.env.NODE_ENV !== "production" && import.meta.client) {
|
|
215
|
-
console.warn(`[i18n] Missing key '${key}' in '${
|
|
247
|
+
console.warn(`[i18n] Missing key '${key}' in '${locale}' for route '${routeName}'`);
|
|
216
248
|
}
|
|
217
249
|
}
|
|
218
250
|
clearCache() {
|
|
@@ -220,6 +252,7 @@ export class NuxtI18n extends BaseI18n {
|
|
|
220
252
|
this.cachedTranslations = {};
|
|
221
253
|
this.outgoingTranslations = null;
|
|
222
254
|
triggerRef(this.contextSignal);
|
|
255
|
+
this.notifyContextChange("refresh");
|
|
223
256
|
}
|
|
224
257
|
}
|
|
225
258
|
export class NuxtTranslationLoader {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-i18n-micro",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.27.0",
|
|
4
|
+
"description": "Fast, lightweight i18n for Nuxt with strategy-based routing and minimal overhead.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
7
7
|
"internationalization",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"seo",
|
|
15
15
|
"translation"
|
|
16
16
|
],
|
|
17
|
-
"homepage": "https://github.
|
|
17
|
+
"homepage": "https://s00d.github.io/nuxt-i18n-micro/",
|
|
18
18
|
"bugs": {
|
|
19
19
|
"url": "https://github.com/s00d/nuxt-i18n-micro/issues"
|
|
20
20
|
},
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"repository": "s00d/nuxt-i18n-micro",
|
|
28
28
|
"workspaces": [
|
|
29
29
|
"client",
|
|
30
|
+
"docs",
|
|
30
31
|
"packages/**",
|
|
31
32
|
"test/fixtures/**/*"
|
|
32
33
|
],
|
|
@@ -81,38 +82,38 @@
|
|
|
81
82
|
"sirv": "^2.0.3",
|
|
82
83
|
"ufo": "^1.5.4",
|
|
83
84
|
"unplugin": "^1.16.1 || ^2.0.0 || ^3.3.0",
|
|
84
|
-
"@i18n-micro/
|
|
85
|
-
"@i18n-micro/
|
|
86
|
-
"@i18n-micro/
|
|
87
|
-
"@i18n-micro/
|
|
88
|
-
"@i18n-micro/
|
|
89
|
-
"@i18n-micro/utils": "^1.
|
|
90
|
-
"@i18n-micro/
|
|
85
|
+
"@i18n-micro/core": "^1.3.13",
|
|
86
|
+
"@i18n-micro/path-strategy": "^1.3.10",
|
|
87
|
+
"@i18n-micro/route-strategy": "^1.1.15",
|
|
88
|
+
"@i18n-micro/types": "^1.2.11",
|
|
89
|
+
"@i18n-micro/utils": "^1.0.14",
|
|
90
|
+
"@i18n-micro/test-utils": "^1.2.9",
|
|
91
|
+
"@i18n-micro/hmr": "^1.0.7"
|
|
91
92
|
},
|
|
92
93
|
"devDependencies": {
|
|
93
94
|
"@nuxt/devtools": "^3.3.1",
|
|
94
95
|
"@nuxt/devtools-ui-kit": "^3.3.1",
|
|
96
|
+
"@vue/devtools-api": "^8.1.5",
|
|
95
97
|
"@nuxt/module-builder": "^1.0.0",
|
|
96
98
|
"@nuxt/schema": "^3.18.1 || ^4.0.0",
|
|
97
99
|
"@nuxt/test-utils": "^4.0.3",
|
|
98
100
|
"@playwright/test": "^1.55.0",
|
|
99
101
|
"@types/node": "^20.19.26",
|
|
100
102
|
"changelogen": "^0.5.7",
|
|
101
|
-
"chart.js": "^4.5.1",
|
|
102
|
-
"mermaid": "^11.12.2",
|
|
103
103
|
"oxfmt": "^0.43.0",
|
|
104
104
|
"oxlint": "^1.58.0",
|
|
105
105
|
"typescript": "^5.9.3",
|
|
106
|
-
"vitepress": "^2.0.0-alpha.18",
|
|
107
|
-
"vitepress-plugin-chartjs": "^1.2.1",
|
|
108
|
-
"vitepress-plugin-folder-tree": "^1.2.1",
|
|
109
|
-
"vitepress-plugin-llms": "^1.13.3",
|
|
110
|
-
"vitepress-plugin-mermaid": "^2.0.17",
|
|
111
106
|
"vitest": "^4.1.10",
|
|
112
107
|
"vue-tsc": "^2.0.21"
|
|
113
108
|
},
|
|
114
109
|
"peerDependencies": {
|
|
115
|
-
"vue-router": "^4.6.3 || ^5.0.0"
|
|
110
|
+
"vue-router": "^4.6.3 || ^5.0.0",
|
|
111
|
+
"@vue/devtools-api": "^8.1.5"
|
|
112
|
+
},
|
|
113
|
+
"peerDependenciesMeta": {
|
|
114
|
+
"@vue/devtools-api": {
|
|
115
|
+
"optional": true
|
|
116
|
+
}
|
|
116
117
|
},
|
|
117
118
|
"optionalDependencies": {
|
|
118
119
|
"@rollup/rollup-linux-x64-gnu": "^4.28.1",
|
|
@@ -161,11 +162,11 @@
|
|
|
161
162
|
"test:dist:packages": "pnpm --filter \"@i18n-micro/core\" --filter \"@i18n-micro/utils\" --filter \"@i18n-micro/hmr\" --filter \"@i18n-micro/vue\" --filter \"@i18n-micro/path-strategy\" --filter \"@i18n-micro/route-strategy\" --filter \"@i18n-micro/devtools-ui\" --filter \"@i18n-micro/astro\" run test:dist",
|
|
162
163
|
"typecheck": "tsc --noEmit",
|
|
163
164
|
"typecheck:nuxt": "nuxt typecheck --no-emit",
|
|
164
|
-
"docs:dev": "pnpm
|
|
165
|
-
"docs:build": "pnpm
|
|
166
|
-
"docs:serve": "
|
|
167
|
-
"docs:clean-dev": "pnpm
|
|
168
|
-
"docs:preview": "
|
|
165
|
+
"docs:dev": "pnpm --filter @i18n-micro/docs dev",
|
|
166
|
+
"docs:build": "pnpm --filter @i18n-micro/docs build",
|
|
167
|
+
"docs:serve": "pnpm --filter @i18n-micro/docs preview",
|
|
168
|
+
"docs:clean-dev": "pnpm --filter @i18n-micro/docs clean-dev",
|
|
169
|
+
"docs:preview": "pnpm --filter @i18n-micro/docs preview",
|
|
169
170
|
"smoke:pack": "pnpm -C scripts cli smoke-pack",
|
|
170
171
|
"smoke:verify": "pnpm -C scripts cli smoke-verify",
|
|
171
172
|
"smoke:browser": "pnpm -C scripts cli smoke-browser",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"24f3c578-f02b-41bc-953a-c7ff7b504d56","timestamp":1785527483273,"prerendered":[]}
|