@ox-content/vite-plugin 0.12.0 → 0.14.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/index.cjs +287 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +92 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +286 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -6725,39 +6725,40 @@ var import_dist = /* @__PURE__ */ require_chunk.__toESM(require_dist(), 1);
|
|
|
6725
6725
|
/**
|
|
6726
6726
|
* Syntax highlighting with Shiki via rehype.
|
|
6727
6727
|
*/
|
|
6728
|
+
const BUILTIN_LANGS = [
|
|
6729
|
+
"javascript",
|
|
6730
|
+
"typescript",
|
|
6731
|
+
"jsx",
|
|
6732
|
+
"tsx",
|
|
6733
|
+
"vue",
|
|
6734
|
+
"svelte",
|
|
6735
|
+
"html",
|
|
6736
|
+
"css",
|
|
6737
|
+
"scss",
|
|
6738
|
+
"json",
|
|
6739
|
+
"yaml",
|
|
6740
|
+
"markdown",
|
|
6741
|
+
"bash",
|
|
6742
|
+
"shell",
|
|
6743
|
+
"rust",
|
|
6744
|
+
"python",
|
|
6745
|
+
"go",
|
|
6746
|
+
"java",
|
|
6747
|
+
"c",
|
|
6748
|
+
"cpp",
|
|
6749
|
+
"sql",
|
|
6750
|
+
"graphql",
|
|
6751
|
+
"diff",
|
|
6752
|
+
"toml"
|
|
6753
|
+
];
|
|
6728
6754
|
let highlighterPromise = null;
|
|
6729
6755
|
/**
|
|
6730
6756
|
* Get or create the Shiki highlighter.
|
|
6731
6757
|
*/
|
|
6732
|
-
async function getHighlighter(theme) {
|
|
6758
|
+
async function getHighlighter(theme, customLangs = []) {
|
|
6733
6759
|
if (!highlighterPromise) highlighterPromise = (0, shiki.createHighlighter)({
|
|
6734
6760
|
themes: [theme],
|
|
6735
|
-
langs: [
|
|
6736
|
-
"javascript",
|
|
6737
|
-
"typescript",
|
|
6738
|
-
"jsx",
|
|
6739
|
-
"tsx",
|
|
6740
|
-
"vue",
|
|
6741
|
-
"svelte",
|
|
6742
|
-
"html",
|
|
6743
|
-
"css",
|
|
6744
|
-
"scss",
|
|
6745
|
-
"json",
|
|
6746
|
-
"yaml",
|
|
6747
|
-
"markdown",
|
|
6748
|
-
"bash",
|
|
6749
|
-
"shell",
|
|
6750
|
-
"rust",
|
|
6751
|
-
"python",
|
|
6752
|
-
"go",
|
|
6753
|
-
"java",
|
|
6754
|
-
"c",
|
|
6755
|
-
"cpp",
|
|
6756
|
-
"sql",
|
|
6757
|
-
"graphql",
|
|
6758
|
-
"diff",
|
|
6759
|
-
"toml"
|
|
6760
|
-
]
|
|
6761
|
+
langs: [...BUILTIN_LANGS, ...customLangs]
|
|
6761
6762
|
});
|
|
6762
6763
|
return highlighterPromise;
|
|
6763
6764
|
}
|
|
@@ -6765,9 +6766,9 @@ async function getHighlighter(theme) {
|
|
|
6765
6766
|
* Rehype plugin for syntax highlighting with Shiki.
|
|
6766
6767
|
*/
|
|
6767
6768
|
function rehypeShikiHighlight(options) {
|
|
6768
|
-
const { theme } = options;
|
|
6769
|
+
const { theme, langs } = options;
|
|
6769
6770
|
return async (tree) => {
|
|
6770
|
-
const highlighter = await getHighlighter(theme);
|
|
6771
|
+
const highlighter = await getHighlighter(theme, langs);
|
|
6771
6772
|
const visit = async (node) => {
|
|
6772
6773
|
if ("children" in node) for (let i = 0; i < node.children.length; i++) {
|
|
6773
6774
|
const child = node.children[i];
|
|
@@ -6810,8 +6811,11 @@ function getTextContent(node) {
|
|
|
6810
6811
|
/**
|
|
6811
6812
|
* Apply syntax highlighting to HTML using Shiki.
|
|
6812
6813
|
*/
|
|
6813
|
-
async function highlightCode(html, theme = "github-dark") {
|
|
6814
|
-
const result = await (0, unified.unified)().use(rehype_parse.default, { fragment: true }).use(rehypeShikiHighlight, {
|
|
6814
|
+
async function highlightCode(html, theme = "github-dark", langs = []) {
|
|
6815
|
+
const result = await (0, unified.unified)().use(rehype_parse.default, { fragment: true }).use(rehypeShikiHighlight, {
|
|
6816
|
+
theme,
|
|
6817
|
+
langs
|
|
6818
|
+
}).use(rehype_stringify.default).process(html);
|
|
6815
6819
|
return String(result);
|
|
6816
6820
|
}
|
|
6817
6821
|
|
|
@@ -6989,7 +6993,7 @@ async function transformMarkdown(source, filePath, options, ssgOptions) {
|
|
|
6989
6993
|
if (options.mermaid) html = await require_mermaid.transformMermaidStatic(html);
|
|
6990
6994
|
const { html: protectedHtml, svgs } = protectMermaidSvgs(html);
|
|
6991
6995
|
html = protectedHtml;
|
|
6992
|
-
if (options.highlight) html = await highlightCode(html, options.highlightTheme);
|
|
6996
|
+
if (options.highlight) html = await highlightCode(html, options.highlightTheme, options.highlightLangs);
|
|
6993
6997
|
html = restoreMermaidSvgs(html, svgs);
|
|
6994
6998
|
return {
|
|
6995
6999
|
code: generateModuleCode(html, frontmatter, toc, filePath, options),
|
|
@@ -10960,6 +10964,251 @@ function createOgViewerPlugin(options) {
|
|
|
10960
10964
|
};
|
|
10961
10965
|
}
|
|
10962
10966
|
|
|
10967
|
+
//#endregion
|
|
10968
|
+
//#region src/i18n.ts
|
|
10969
|
+
/**
|
|
10970
|
+
* i18n plugin for Ox Content.
|
|
10971
|
+
*
|
|
10972
|
+
* Provides:
|
|
10973
|
+
* - Dictionary loading and validation at build time
|
|
10974
|
+
* - Virtual module for i18n config
|
|
10975
|
+
* - Build-time i18n checking
|
|
10976
|
+
* - Locale-aware routing middleware for dev server
|
|
10977
|
+
*/
|
|
10978
|
+
/**
|
|
10979
|
+
* Resolves i18n options with defaults.
|
|
10980
|
+
*/
|
|
10981
|
+
function resolveI18nOptions(options) {
|
|
10982
|
+
if (options === false) return false;
|
|
10983
|
+
if (!options || !options.enabled) return false;
|
|
10984
|
+
const defaultLocale = options.defaultLocale ?? "en";
|
|
10985
|
+
const locales = options.locales ?? [{
|
|
10986
|
+
code: defaultLocale,
|
|
10987
|
+
name: defaultLocale
|
|
10988
|
+
}];
|
|
10989
|
+
if (!locales.some((l) => l.code === defaultLocale)) locales.unshift({
|
|
10990
|
+
code: defaultLocale,
|
|
10991
|
+
name: defaultLocale
|
|
10992
|
+
});
|
|
10993
|
+
return {
|
|
10994
|
+
enabled: true,
|
|
10995
|
+
dir: options.dir ?? "content/i18n",
|
|
10996
|
+
defaultLocale,
|
|
10997
|
+
locales,
|
|
10998
|
+
hideDefaultLocale: options.hideDefaultLocale ?? true,
|
|
10999
|
+
check: options.check ?? true,
|
|
11000
|
+
functionNames: options.functionNames ?? ["t", "$t"]
|
|
11001
|
+
};
|
|
11002
|
+
}
|
|
11003
|
+
/**
|
|
11004
|
+
* Creates the i18n sub-plugin for the Vite plugin array.
|
|
11005
|
+
*/
|
|
11006
|
+
function createI18nPlugin(resolvedOptions) {
|
|
11007
|
+
const i18nOptions = resolvedOptions.i18n;
|
|
11008
|
+
let root = process.cwd();
|
|
11009
|
+
return {
|
|
11010
|
+
name: "ox-content:i18n",
|
|
11011
|
+
configResolved(config) {
|
|
11012
|
+
root = config.root;
|
|
11013
|
+
},
|
|
11014
|
+
resolveId(id) {
|
|
11015
|
+
if (id === "virtual:ox-content/i18n") return "\0virtual:ox-content/i18n";
|
|
11016
|
+
return null;
|
|
11017
|
+
},
|
|
11018
|
+
load(id) {
|
|
11019
|
+
if (id === "\0virtual:ox-content/i18n") {
|
|
11020
|
+
if (!i18nOptions) return `export const i18n = { enabled: false }; export default i18n;`;
|
|
11021
|
+
return generateI18nModule(i18nOptions, root);
|
|
11022
|
+
}
|
|
11023
|
+
return null;
|
|
11024
|
+
},
|
|
11025
|
+
async buildStart() {
|
|
11026
|
+
if (!i18nOptions || !i18nOptions.check) return;
|
|
11027
|
+
const dictDir = path$1.resolve(root, i18nOptions.dir);
|
|
11028
|
+
if (!fs.existsSync(dictDir)) {
|
|
11029
|
+
console.warn(`[ox-content:i18n] Dictionary directory not found: ${dictDir}`);
|
|
11030
|
+
return;
|
|
11031
|
+
}
|
|
11032
|
+
try {
|
|
11033
|
+
const { loadDictionaries, checkI18n, extractTranslationKeys } = await import("@ox-content/napi");
|
|
11034
|
+
const loadResult = loadDictionaries(dictDir);
|
|
11035
|
+
if (loadResult.errors.length > 0) {
|
|
11036
|
+
for (const error of loadResult.errors) console.warn(`[ox-content:i18n] ${error}`);
|
|
11037
|
+
return;
|
|
11038
|
+
}
|
|
11039
|
+
console.log(`[ox-content:i18n] Loaded ${loadResult.localeCount} locales: ${loadResult.locales.join(", ")}`);
|
|
11040
|
+
const checkResult = checkI18n(dictDir, collectKeysFromSource(root, extractTranslationKeys, i18nOptions));
|
|
11041
|
+
if (checkResult.errorCount > 0 || checkResult.warningCount > 0) {
|
|
11042
|
+
for (const diag of checkResult.diagnostics) if (diag.severity === "error") console.error(`[ox-content:i18n] ${diag.message}`);
|
|
11043
|
+
else if (diag.severity === "warning") console.warn(`[ox-content:i18n] ${diag.message}`);
|
|
11044
|
+
}
|
|
11045
|
+
} catch {}
|
|
11046
|
+
},
|
|
11047
|
+
configureServer(server) {
|
|
11048
|
+
if (!i18nOptions) return;
|
|
11049
|
+
const dictDir = path$1.resolve(root, i18nOptions.dir);
|
|
11050
|
+
if (fs.existsSync(dictDir)) {
|
|
11051
|
+
server.watcher.add(dictDir);
|
|
11052
|
+
server.watcher.on("change", (filePath) => {
|
|
11053
|
+
if (!filePath.startsWith(dictDir)) return;
|
|
11054
|
+
if (!/\.(json|yaml|yml)$/.test(filePath)) return;
|
|
11055
|
+
const mod = server.moduleGraph.getModuleById("\0virtual:ox-content/i18n");
|
|
11056
|
+
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
11057
|
+
server.ws.send({ type: "full-reload" });
|
|
11058
|
+
});
|
|
11059
|
+
}
|
|
11060
|
+
server.middlewares.use((req, _res, next) => {
|
|
11061
|
+
if (!req.url) return next();
|
|
11062
|
+
const localeMatch = req.url.match(/^\/([a-z]{2}(?:-[a-zA-Z]+)?)(\/|$)/);
|
|
11063
|
+
if (localeMatch) {
|
|
11064
|
+
const localeCode = localeMatch[1];
|
|
11065
|
+
if (i18nOptions.locales.some((l) => l.code === localeCode)) req.__oxLocale = localeCode;
|
|
11066
|
+
} else if (i18nOptions.hideDefaultLocale) req.__oxLocale = i18nOptions.defaultLocale;
|
|
11067
|
+
next();
|
|
11068
|
+
});
|
|
11069
|
+
}
|
|
11070
|
+
};
|
|
11071
|
+
}
|
|
11072
|
+
/**
|
|
11073
|
+
* Generates the virtual module for i18n configuration.
|
|
11074
|
+
*/
|
|
11075
|
+
function generateI18nModule(options, root) {
|
|
11076
|
+
const dictDir = path$1.resolve(root, options.dir);
|
|
11077
|
+
const localesJson = JSON.stringify(options.locales);
|
|
11078
|
+
const defaultLocale = JSON.stringify(options.defaultLocale);
|
|
11079
|
+
let dictionariesCode = "{}";
|
|
11080
|
+
try {
|
|
11081
|
+
const napi = require("@ox-content/napi");
|
|
11082
|
+
if (napi.loadDictionariesFlat) {
|
|
11083
|
+
const dictData = napi.loadDictionariesFlat(dictDir);
|
|
11084
|
+
dictionariesCode = JSON.stringify(dictData);
|
|
11085
|
+
} else dictionariesCode = JSON.stringify(loadDictionariesFallback(options, dictDir));
|
|
11086
|
+
} catch {
|
|
11087
|
+
try {
|
|
11088
|
+
dictionariesCode = JSON.stringify(loadDictionariesFallback(options, dictDir));
|
|
11089
|
+
} catch {}
|
|
11090
|
+
}
|
|
11091
|
+
return `
|
|
11092
|
+
export const i18nConfig = {
|
|
11093
|
+
enabled: true,
|
|
11094
|
+
defaultLocale: ${defaultLocale},
|
|
11095
|
+
locales: ${localesJson},
|
|
11096
|
+
hideDefaultLocale: ${JSON.stringify(options.hideDefaultLocale)},
|
|
11097
|
+
};
|
|
11098
|
+
|
|
11099
|
+
export const dictionaries = ${dictionariesCode};
|
|
11100
|
+
|
|
11101
|
+
export function t(key, params, locale) {
|
|
11102
|
+
const dict = dictionaries[locale || i18nConfig.defaultLocale] || {};
|
|
11103
|
+
let message = dict[key];
|
|
11104
|
+
if (!message) {
|
|
11105
|
+
const fallback = dictionaries[i18nConfig.defaultLocale] || {};
|
|
11106
|
+
message = fallback[key] || key;
|
|
11107
|
+
}
|
|
11108
|
+
if (params) {
|
|
11109
|
+
for (const [k, v] of Object.entries(params)) {
|
|
11110
|
+
message = message.replace(new RegExp('\\\\{\\\\$' + k + '\\\\}', 'g'), String(v));
|
|
11111
|
+
}
|
|
11112
|
+
}
|
|
11113
|
+
return message;
|
|
11114
|
+
}
|
|
11115
|
+
|
|
11116
|
+
export function getLocaleFromPath(pathname) {
|
|
11117
|
+
const match = pathname.match(/^\\/([a-z]{2}(?:-[a-zA-Z]+)?)(\\//|$)/);
|
|
11118
|
+
if (match) {
|
|
11119
|
+
const code = match[1];
|
|
11120
|
+
if (i18nConfig.locales.some(l => l.code === code)) {
|
|
11121
|
+
return code;
|
|
11122
|
+
}
|
|
11123
|
+
}
|
|
11124
|
+
return i18nConfig.defaultLocale;
|
|
11125
|
+
}
|
|
11126
|
+
|
|
11127
|
+
export function localePath(pathname, locale) {
|
|
11128
|
+
const current = getLocaleFromPath(pathname);
|
|
11129
|
+
let clean = pathname;
|
|
11130
|
+
if (current !== i18nConfig.defaultLocale || !i18nConfig.hideDefaultLocale) {
|
|
11131
|
+
clean = pathname.replace(new RegExp('^/' + current + '(/|$)'), '/');
|
|
11132
|
+
}
|
|
11133
|
+
if (locale === i18nConfig.defaultLocale && i18nConfig.hideDefaultLocale) {
|
|
11134
|
+
return clean || '/';
|
|
11135
|
+
}
|
|
11136
|
+
return '/' + locale + (clean.startsWith('/') ? clean : '/' + clean);
|
|
11137
|
+
}
|
|
11138
|
+
|
|
11139
|
+
export default { i18nConfig, dictionaries, t, getLocaleFromPath, localePath };
|
|
11140
|
+
`;
|
|
11141
|
+
}
|
|
11142
|
+
/**
|
|
11143
|
+
* Flattens a nested object into dot-separated keys.
|
|
11144
|
+
*/
|
|
11145
|
+
function flattenObject(obj, prefix, result) {
|
|
11146
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
11147
|
+
const fullKey = `${prefix}.${key}`;
|
|
11148
|
+
if (typeof value === "string") result[fullKey] = value;
|
|
11149
|
+
else if (typeof value === "object" && value !== null && !Array.isArray(value)) flattenObject(value, fullKey, result);
|
|
11150
|
+
else result[fullKey] = String(value);
|
|
11151
|
+
}
|
|
11152
|
+
}
|
|
11153
|
+
/**
|
|
11154
|
+
* Fallback dictionary loading using TS-based JSON file reading.
|
|
11155
|
+
*/
|
|
11156
|
+
function loadDictionariesFallback(options, dictDir) {
|
|
11157
|
+
const dictData = {};
|
|
11158
|
+
for (const locale of options.locales) {
|
|
11159
|
+
const localeDir = path$1.join(dictDir, locale.code);
|
|
11160
|
+
if (!fs.existsSync(localeDir)) continue;
|
|
11161
|
+
const files = fs.readdirSync(localeDir);
|
|
11162
|
+
const localeDict = {};
|
|
11163
|
+
for (const file of files) {
|
|
11164
|
+
if (!file.endsWith(".json")) continue;
|
|
11165
|
+
const filePath = path$1.join(localeDir, file);
|
|
11166
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
11167
|
+
const namespace = path$1.basename(file, ".json");
|
|
11168
|
+
try {
|
|
11169
|
+
flattenObject(JSON.parse(content), namespace, localeDict);
|
|
11170
|
+
} catch {}
|
|
11171
|
+
}
|
|
11172
|
+
dictData[locale.code] = localeDict;
|
|
11173
|
+
}
|
|
11174
|
+
return dictData;
|
|
11175
|
+
}
|
|
11176
|
+
/**
|
|
11177
|
+
* Collects translation keys from source files using NAPI extractTranslationKeys.
|
|
11178
|
+
*/
|
|
11179
|
+
function collectKeysFromSource(root, extractTranslationKeys, options) {
|
|
11180
|
+
const srcDir = path$1.resolve(root, "src");
|
|
11181
|
+
const keys = /* @__PURE__ */ new Set();
|
|
11182
|
+
if (fs.existsSync(srcDir)) walkDir(srcDir, /\.(ts|tsx|js|jsx)$/, (filePath) => {
|
|
11183
|
+
const usages = extractTranslationKeys(fs.readFileSync(filePath, "utf-8"), filePath, options.functionNames);
|
|
11184
|
+
for (const usage of usages) keys.add(usage.key);
|
|
11185
|
+
});
|
|
11186
|
+
const contentDir = path$1.resolve(root, "content");
|
|
11187
|
+
if (fs.existsSync(contentDir)) {
|
|
11188
|
+
const tPattern = /\{\{t\(['"]([^'"]+)['"]\)\}\}/g;
|
|
11189
|
+
walkDir(contentDir, /\.(md|mdx)$/, (filePath) => {
|
|
11190
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
11191
|
+
let match;
|
|
11192
|
+
while ((match = tPattern.exec(content)) !== null) keys.add(match[1]);
|
|
11193
|
+
tPattern.lastIndex = 0;
|
|
11194
|
+
});
|
|
11195
|
+
}
|
|
11196
|
+
return Array.from(keys);
|
|
11197
|
+
}
|
|
11198
|
+
/**
|
|
11199
|
+
* Recursively walks a directory, calling the callback for files matching the pattern.
|
|
11200
|
+
*/
|
|
11201
|
+
function walkDir(dir, pattern, callback) {
|
|
11202
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
11203
|
+
for (const entry of entries) {
|
|
11204
|
+
const fullPath = path$1.join(dir, entry.name);
|
|
11205
|
+
if (entry.isDirectory()) {
|
|
11206
|
+
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
11207
|
+
walkDir(fullPath, pattern, callback);
|
|
11208
|
+
} else if (pattern.test(entry.name)) callback(fullPath);
|
|
11209
|
+
}
|
|
11210
|
+
}
|
|
11211
|
+
|
|
10963
11212
|
//#endregion
|
|
10964
11213
|
//#region src/jsx-runtime.ts
|
|
10965
11214
|
/**
|
|
@@ -11686,6 +11935,7 @@ function oxContent(options = {}) {
|
|
|
11686
11935
|
}
|
|
11687
11936
|
}
|
|
11688
11937
|
];
|
|
11938
|
+
if (resolvedOptions.i18n) plugins.push(createI18nPlugin(resolvedOptions));
|
|
11689
11939
|
if (resolvedOptions.ogViewer) plugins.push(createOgViewerPlugin(resolvedOptions));
|
|
11690
11940
|
return plugins;
|
|
11691
11941
|
}
|
|
@@ -11705,6 +11955,7 @@ function resolveOptions(options) {
|
|
|
11705
11955
|
strikethrough: options.strikethrough ?? true,
|
|
11706
11956
|
highlight: options.highlight ?? false,
|
|
11707
11957
|
highlightTheme: options.highlightTheme ?? "github-dark",
|
|
11958
|
+
highlightLangs: options.highlightLangs ?? [],
|
|
11708
11959
|
mermaid: options.mermaid ?? false,
|
|
11709
11960
|
frontmatter: options.frontmatter ?? true,
|
|
11710
11961
|
toc: options.toc ?? true,
|
|
@@ -11714,7 +11965,8 @@ function resolveOptions(options) {
|
|
|
11714
11965
|
transformers: options.transformers ?? [],
|
|
11715
11966
|
docs: resolveDocsOptions(options.docs),
|
|
11716
11967
|
search: resolveSearchOptions(options.search),
|
|
11717
|
-
ogViewer: options.ogViewer ?? true
|
|
11968
|
+
ogViewer: options.ogViewer ?? true,
|
|
11969
|
+
i18n: resolveI18nOptions(options.i18n)
|
|
11718
11970
|
};
|
|
11719
11971
|
}
|
|
11720
11972
|
/**
|
|
@@ -11744,6 +11996,7 @@ exports.buildSsg = buildSsg;
|
|
|
11744
11996
|
exports.clearRenderContext = clearRenderContext;
|
|
11745
11997
|
exports.collectGitHubRepos = require_github.collectGitHubRepos;
|
|
11746
11998
|
exports.collectOgpUrls = require_ogp.collectOgpUrls;
|
|
11999
|
+
exports.createI18nPlugin = createI18nPlugin;
|
|
11747
12000
|
exports.createMarkdownEnvironment = createMarkdownEnvironment;
|
|
11748
12001
|
exports.createTheme = createTheme;
|
|
11749
12002
|
exports.defaultTheme = defaultTheme;
|
|
@@ -11774,6 +12027,7 @@ exports.renderAllPages = renderAllPages;
|
|
|
11774
12027
|
exports.renderPage = renderPage;
|
|
11775
12028
|
exports.renderToString = renderToString;
|
|
11776
12029
|
exports.resolveDocsOptions = resolveDocsOptions;
|
|
12030
|
+
exports.resolveI18nOptions = resolveI18nOptions;
|
|
11777
12031
|
exports.resolveOgImageOptions = resolveOgImageOptions;
|
|
11778
12032
|
exports.resolveSearchOptions = resolveSearchOptions;
|
|
11779
12033
|
exports.resolveSsgOptions = resolveSsgOptions;
|