Add internationalization support with astro-i18next integration

- Implemented astro-i18next for multi-language support, including English, Dutch, and Italian.
- Configured default locale and language fallback settings.
- Defined routes for localized content in the configuration.
- Updated package.json and package-lock.json to include new dependencies for i18next and related plugins.
This commit is contained in:
becarta
2025-05-23 15:10:00 +02:00
parent 8a3507dce0
commit 3168826fa8
581 changed files with 88691 additions and 494 deletions

284
node_modules/@proload/core/lib/esm/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,284 @@
import escalade from "escalade";
import { join, dirname, extname, resolve } from "path";
import deepmerge from "deepmerge";
import { existsSync, readdir, readFile, stat } from "fs";
import { promisify } from "util";
import { createRequire } from "module";
import requireOrImport from "./requireOrImport.mjs";
import { assert, ProloadError } from "../error.cjs";
export { ProloadError };
const toStats = promisify(stat);
const toRead = promisify(readdir);
const toReadFile = promisify(readFile);
const require = createRequire(import.meta.url);
let merge = deepmerge;
const defaultExtensions = ['js', 'cjs', 'mjs'];
const defaultFileNames = ['[name].config'];
const validNames = (namespace) => {
const extensionPlugins = load.plugins.filter(p => Array.isArray(p.extensions));
const fileNamePlugins = load.plugins.filter(p => Array.isArray(p.fileNames));
const validExtensions = [...defaultExtensions].concat(...extensionPlugins.map(p => p.extensions));
const validFileNames = [...defaultFileNames].concat(...fileNamePlugins.map(p => p.fileNames));
const result = validFileNames
.map(fileName => fileName.replace('[name]', namespace))
.reduce((acc, fileName) => {
return [...acc].concat(...validExtensions.map(ext => `${fileName}${ext ? '.' + ext.replace(/^\./, '') : ''}`))
}, []);
return result;
}
/**
* @param {any} val
* @returns {val is Record<any, any>}
*/
const isObject = (val) =>
val != null && typeof val === "object" && Array.isArray(val) === false;
const requireOrImportWithMiddleware = (filePath) => {
let registerPlugins = load.plugins.filter(
(plugin) => typeof plugin.register !== "undefined"
);
let transformPlugins = load.plugins.filter(
(plugin) => typeof plugin.transform !== "undefined"
);
return requireOrImport(filePath, { middleware: registerPlugins }).then(
async (mdl) => Promise.all(
transformPlugins.map((plugin) => {
return Promise.resolve(plugin.transform(mdl)).then((result) => {
if (result) mdl = result;
});
})
).then(() => mdl)
);
};
/**
*
* @param {string} namespace
* @param {{ filePath: string, extension: string }} opts
* @returns {Promise<{ filePath: string, value: string }>}
*/
async function resolveExtension(namespace, { filePath, extension }) {
let resolvedPath;
if (extension.startsWith("./") || extension.startsWith("../")) {
if (extname(extension) === "") {
resolvedPath = resolve(
dirname(filePath),
`${extension}${extname(filePath)}`
);
}
if (!existsSync(resolvedPath)) resolvedPath = null;
if (!resolvedPath) {
resolvedPath = resolve(dirname(filePath), extension);
}
if (!existsSync(resolvedPath)) resolvedPath = null;
}
if (!resolvedPath) {
const pkg = require.resolve(extension, {
cwd: dirname(filePath),
});
const accepted = validNames(namespace);
for (const config of accepted) {
try {
resolvedPath = `${pkg}/${config}`;
if (resolvedPath && existsSync(resolvedPath)) {
break;
} else {
resolvedPath = null
}
} catch (e) {}
}
}
if (!resolvedPath) {
resolvedPath = require.resolve(extension, { cwd: dirname(filePath) });
}
if (!resolvedPath) return
const value = await requireOrImportWithMiddleware(resolvedPath);
return { filePath: resolvedPath, value };
}
async function resolveExtensions(
namespace,
{ filePath, value: raw, context },
acc = {}
) {
let value = typeof raw === "function" ? await raw(context) : raw;
if (Array.isArray(value)) return value;
assert(
isObject(value),
`${namespace} configuration expects an "object" but encountered ${value}`
);
acc = merge(acc, value);
if (!("extends" in value)) return acc;
assert(
Array.isArray(value.extends),
`${namespace} "extends" must be an array`
);
const configs = await Promise.all(
value.extends.map((extension) =>
resolveExtension(namespace, { filePath, extension }).then((config) =>
resolveExtensions(namespace, { ...config, context }, acc)
)
)
);
for (const config of configs) {
acc = merge(acc, config);
}
delete acc.extends;
return acc;
}
/**
*
* @param {string} namespace
* @param {import('../index').LoadOptions} opts
*/
async function resolveConfig(namespace, opts = {}) {
const accepted = validNames(namespace);
const { context, accept } = opts;
const input = opts.cwd || process.cwd();
let mustExist = true;
if (typeof opts.mustExist !== "undefined") {
mustExist = opts.mustExist;
}
if (typeof opts.merge === "function") {
merge = opts.merge;
}
let filePath;
if (typeof opts.filePath === "string") {
const absPath = opts.filePath.startsWith(".")
? resolve(opts.filePath, input)
: opts.filePath;
if (existsSync(absPath)) {
filePath = absPath;
}
} else {
filePath = await escalade(input, async (dir, names) => {
if (accept) {
for (const n of names) {
if (accept(n, { directory: dir }) === true) return n;
}
}
for (const n of accepted) {
if (names.includes(n)) return n;
}
if (names.includes("config")) {
let d = join(dir, "config");
let _,
stats = await toStats(d);
let entries = [];
if (stats.isDirectory()) {
entries = await toRead(d);
for (const n of accepted) {
if (entries.includes(n)) return join("config", n);
}
}
}
if (names.includes("package.json")) {
let file = join(dir, "package.json");
let _,
contents = await toReadFile(file).then((r) =>
JSON.parse(r.toString())
);
if (contents[namespace]) return "package.json";
}
});
}
if (mustExist) {
assert(
!!filePath,
`Unable to resolve a ${namespace} configuration`,
"ERR_PROLOAD_NOT_FOUND"
);
} else if (!filePath) {
return;
}
return filePath;
}
/**
*
* @param {string} namespace
* @param {import('../index').LoadOptions} opts
*/
async function load(namespace, opts = {}) {
const { context } = opts;
let mustExist = true;
if (typeof opts.mustExist !== 'undefined') {
mustExist = opts.mustExist
}
const filePath = await resolveConfig(namespace, opts);
if (mustExist) {
assert(!!filePath, `Unable to resolve a ${namespace} configuration`, 'ERR_PROLOAD_NOT_FOUND');
} else if (!filePath) {
return;
}
let rawValue = await requireOrImportWithMiddleware(filePath);
if (filePath.endsWith('package.json')) rawValue = rawValue[namespace];
// Important: "empty" config files will be returned as `Module {}`
// We should handle them here
if (rawValue && !(rawValue instanceof Object)) {
if (mustExist) {
assert(
true,
`Resolved a ${namespace} configuration, but no configuration was exported`,
"ERR_PROLOAD_NOT_FOUND"
);
} else {
return;
}
}
const resolvedValue = await resolveExtensions(namespace, {
filePath,
value: rawValue,
context,
});
return {
filePath,
raw: rawValue,
value: resolvedValue,
};
}
const defaultPlugins = [
{
name: "@proload/extract-default",
transform(mdl) {
if (mdl.default && Object.keys(mdl).length === 1) {
return mdl.default;
};
return mdl;
},
},
];
/** @type import('../index').Plugin[] */
load.plugins = defaultPlugins;
load.use = (plugins) => {
load.plugins = [...load.plugins, ...plugins];
};
export default load;
export { resolveConfig as resolve };

30
node_modules/@proload/core/lib/esm/requireOrImport.mjs generated vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
import { createRequire } from 'module';
import { pathToFileURL } from 'url';
let require = createRequire(import.meta.url);
/**
*
* @param {string} filePath
*/
export default async function requireOrImport(filePath, { middleware = [] } = {}) {
await Promise.all(middleware.map(plugin => plugin.register(filePath)));
return new Promise(async (resolve, reject) => {
try {
let mdl = require(filePath);
resolve(mdl);
} catch (e) {
if (e.code === 'ERR_REQUIRE_ESM') {
const fileUrl = pathToFileURL(filePath).toString();
try {
const mdl = await import(fileUrl);
return resolve(mdl);
} catch (e) {
reject(e);
}
};
reject(e);
}
})
}

View File

@@ -0,0 +1 @@
export default function requireOrImport(filePath: string, opts?: { middleware: any[] }): Promise<any>;