MDL-87759 js: integrate esbuild with Grunt for React
Introduces the tooling to discover, build, and watch TypeScript/TSX React
source files across Moodle core and plugin components.
Build pipeline (.esbuild/)
- build.mjs: entry point; generates TS path aliases then runs all component
builds; accepts --dev flag for development mode; throws on build failure
- generate-aliases.mjs: scans component metadata to produce
tsconfig.aliases.json (@moodle/lms/<component>/* paths); skips rewrite
when content is unchanged
- plugin/plugincomponents.mjs: single source of all React build logic:
- buildPluginComponents(isDev): discovers and builds all components in
parallel via a single glob (public/**/js/react/src/**/*.{ts,tsx});
throws on any failure
- watchComponents(isDev, onRebuild): starts esbuild in native watch mode
using a shared incremental context; calls onRebuild with rebuilt source
paths after each change so callers can run follow-up tasks (e.g. lint)
- createBuildConfig(isDev): shared esbuild options (bundle, esm,
jsx:automatic, minify/sourcemap/jsxDev per mode); define derived
internally from isDev
- resolveComponentPaths(entry): exported src->build path mapping so both
full and single-file builders use the same resolution logic
- React, ReactDOM and @moodle/lms/* marked external via inline array;
no custom esbuild plugin needed
Grunt integration (.grunt/)
- tasks/react.js: single react task with three modes:
- grunt react — production build
- grunt react:dev — development build (sourcemaps, no minification)
- grunt react:watch — esbuild native watch; uses esbuild's own
context.watch() rather than grunt-contrib-watch so the incremental
build graph is preserved across rebuilds; ESLint runs in check-only
mode after each change to avoid re-triggering esbuild
- tasks/javascript.js: loads react.js and includes react in the js task
chain alongside amd and yui; all JS pipeline orchestration in one place
- tasks/startup.js: includes js/react/src/** in the startup file glob
- tasks/eslint.js: adds react ESLint target (fix: true) for source linting
- components.js: adds getReactTsSrcGlobList() for watch file patterns
- Gruntfile.js: exposes reactSrc glob and inReact flag in moodleEnv;
react task is not loaded directly — javascript.js owns that
Config / deps
- tsconfig.json: base TypeScript config; extends tsconfig.aliases.json
- tsconfig.aliases.json: initial generated @moodle/lms/* path mappings
- .eslintrc: adds react ESLint overrides for TypeScript/TSX files
- package.json: adds esbuild and @typescript-eslint/parser
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generates tsconfig.aliases.json for cross-component TypeScript imports.
|
||||
*
|
||||
* Moodle ESM source files can import from other components using the alias
|
||||
* scheme @moodle/lms/<component>/* (e.g. @moodle/lms/core/SomeUtil). This
|
||||
* file reads the Moodle component registry (.grunt/components.js), finds every
|
||||
* component that has a js/esm/src/ directory, and writes the corresponding
|
||||
* TypeScript path mappings to tsconfig.aliases.json.
|
||||
*
|
||||
* tsconfig.json extends tsconfig.aliases.json, so TypeScript picks up the
|
||||
* mappings automatically. The file is skipped if its content is unchanged, to
|
||||
* avoid unnecessary rebuilds.
|
||||
*
|
||||
* This must run before esbuild compilation. The Grunt `react` task calls
|
||||
* generateAliases() as its first step.
|
||||
*
|
||||
* @copyright 2026 Adrian Greeve <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { createRequire } from "module";
|
||||
|
||||
const rootDir = process.cwd();
|
||||
|
||||
const tsconfigOut = path.join(rootDir, "tsconfig.aliases.json");
|
||||
const TS_ALIASES_WARNING =
|
||||
"// WARNING: Do not edit this file manually. It is generated by `grunt react`.\n";
|
||||
|
||||
/**
|
||||
* Load Moodle component paths from `.grunt/components.js`.
|
||||
*
|
||||
* @returns {Record<string, string>} Map of component paths to component names.
|
||||
*/
|
||||
function loadComponentPathMap() {
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
// Load Moodle's components data from .grunt/components.js.
|
||||
const { fetchComponentData } = require(
|
||||
path.join(process.cwd(), ".grunt", "components.js")
|
||||
);
|
||||
|
||||
// Format: `{ components: { "public/lib": "core", ... } }`.
|
||||
const componentsData = fetchComponentData().components;
|
||||
|
||||
// Expected:
|
||||
// `{ "public/lib": "core", "public/ai": "core_ai", ... }`.
|
||||
return componentsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a directory contains at least one TypeScript source file recursively.
|
||||
*
|
||||
* @param {string} dir Directory path to inspect.
|
||||
* @returns {boolean} True when at least one .ts or .tsx file is found.
|
||||
*/
|
||||
function hasTypeScriptSource(dir) {
|
||||
if (!fs.existsSync(dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const full = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
if (hasTypeScriptSource(full)) {
|
||||
return true;
|
||||
}
|
||||
} else if (entry.isFile()) {
|
||||
if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two TypeScript `paths` maps for exact equality.
|
||||
*
|
||||
* @param {Record<string, string[]>} a First paths map.
|
||||
* @param {Record<string, string[]>} b Second paths map.
|
||||
* @returns {boolean} True when keys and values match in order.
|
||||
*/
|
||||
function pathsEqual(a, b) {
|
||||
const aKeys = Object.keys(a);
|
||||
const bKeys = Object.keys(b);
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const key of aKeys) {
|
||||
if (!Object.prototype.hasOwnProperty.call(b, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const aArr = a[key] ?? [];
|
||||
const bArr = b[key] ?? [];
|
||||
if (aArr.length !== bArr.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < aArr.length; i++) {
|
||||
if (aArr[i] !== bArr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON content and tolerate line comments.
|
||||
*
|
||||
* @param {string} content Raw JSON/JSONC file content.
|
||||
* @returns {unknown}
|
||||
*/
|
||||
function parseJsonWithComments(content) {
|
||||
const stripped = content
|
||||
.replace(/^\uFEFF/, "")
|
||||
.replace(/^\s*\/\/.*$/gm, "");
|
||||
|
||||
return JSON.parse(stripped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert JSON output so single-value arrays are rendered on one line.
|
||||
*
|
||||
* @param {unknown} obj Data to stringify.
|
||||
* @returns {string} JSON string with flattened single-value arrays.
|
||||
*/
|
||||
function stringifyFlatArrays(obj) {
|
||||
const json = JSON.stringify(obj, null, 2);
|
||||
return TS_ALIASES_WARNING + json.replace(/\[\s+\"(.*?)\"\s+\]/g, '["$1"]') + "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate `tsconfig.aliases.json` from Moodle component metadata.
|
||||
*
|
||||
* Includes core aliases, discovers plugin React source aliases, and skips
|
||||
* rewriting when aliases have not changed.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function generateAliases() {
|
||||
const componentPathMap = loadComponentPathMap();
|
||||
|
||||
// Build TS paths for tsconfig.aliases.json
|
||||
/** @type {Record<string, string[]>} */
|
||||
const tsPaths = {};
|
||||
tsPaths["@moodle/lms/core/*"] = ["./public/lib/js/esm/src/*"]; // Always include core alias.
|
||||
|
||||
for (const [componentPath, componentName] of Object.entries(componentPathMap)) {
|
||||
const reactSrcDir = path.join(rootDir, componentPath, "js", "esm", "src");
|
||||
|
||||
if (!hasTypeScriptSource(reactSrcDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const runtimeAliasKey = `@moodle/lms/${componentName}/*`;
|
||||
const targetPattern = `./${path
|
||||
.join(componentPath, "js", "esm", "src", "*")
|
||||
.replace(/\\/g, "/")}`;
|
||||
|
||||
tsPaths[runtimeAliasKey] = [targetPattern];
|
||||
}
|
||||
|
||||
const tsconfig = {
|
||||
compilerOptions: { paths: tsPaths },
|
||||
};
|
||||
|
||||
// If tsconfig paths didn't change, skip regeneration
|
||||
let previousPaths = null;
|
||||
let hasWarningHeader = false;
|
||||
if (fs.existsSync(tsconfigOut)) {
|
||||
try {
|
||||
const previousContent = fs.readFileSync(tsconfigOut, "utf8");
|
||||
hasWarningHeader = previousContent.startsWith(TS_ALIASES_WARNING);
|
||||
const previousTsconfig = /** @type {{compilerOptions?: {paths?: Record<string, string[]>}}} */ (
|
||||
parseJsonWithComments(previousContent)
|
||||
);
|
||||
previousPaths = previousTsconfig.compilerOptions?.paths ?? {};
|
||||
} catch {
|
||||
// ignore parse errors and treat as "no previous cache"
|
||||
previousPaths = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousPaths && hasWarningHeader && pathsEqual(previousPaths, tsPaths)) {
|
||||
console.log("No alias changes detected, skipping tsconfig.aliases.json regeneration.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write tsconfig.aliases.json
|
||||
fs.writeFileSync(tsconfigOut, stringifyFlatArrays(tsconfig));
|
||||
console.log("Generated TS alias file:", tsconfigOut);
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Core esbuild library for Moodle ESM components.
|
||||
*
|
||||
* This is the single source of all build logic. The Grunt tasks
|
||||
* (.grunt/tasks/react.js) import from here rather than duplicating
|
||||
* configuration or build steps.
|
||||
*
|
||||
* Source layout convention:
|
||||
* <component>/js/esm/src/**\/*.{ts,tsx} → <component>/js/esm/build/**\/*.js
|
||||
*
|
||||
* Exports:
|
||||
* createBuildConfig(isDev) esbuild config object; pass isDev=true
|
||||
* to disable minification / add sourcemaps.
|
||||
* buildPluginComponents(isDev) Glob for every js/esm/src tree across
|
||||
* core and plugins, compile all in parallel.
|
||||
* buildSingleFile(filePath, isDev) Compile one source file; used by the
|
||||
* Grunt watch task on incremental changes.
|
||||
* watchComponents(isDev) Start esbuild's native watch mode so the
|
||||
* compiler rebuilds affected files on save.
|
||||
* resolveComponentPaths(entry) Map an absolute source path to its
|
||||
* relative input path and output path.
|
||||
*
|
||||
* @copyright 2026 Adrian Greeve <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import esbuild from "esbuild";
|
||||
import { glob } from "glob";
|
||||
import chalk from "chalk";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
const projectRoot = process.cwd();
|
||||
|
||||
/**
|
||||
* Resolve a path from the current project root.
|
||||
*
|
||||
* @param {...string} segments Path segments to resolve.
|
||||
* @returns {string} Absolute path from project root.
|
||||
*/
|
||||
const fromRoot = (...segments) => path.resolve(projectRoot, ...segments);
|
||||
|
||||
/**
|
||||
* Create an incremental dot progress indicator.
|
||||
* Prints one dot per completed build and wraps lines for readability.
|
||||
*
|
||||
* @param {number} total Total number of items to build.
|
||||
* @returns {{ start: () => void, tick: () => void, succeed: (msg: string) => void, fail: (msg: string) => void }}
|
||||
*/
|
||||
function createDotProgress(total) {
|
||||
const dotsPerLine = 60;
|
||||
let printed = 0;
|
||||
|
||||
return {
|
||||
start: () => {
|
||||
process.stdout.write(`${chalk.cyan("Building")} `);
|
||||
},
|
||||
tick: () => {
|
||||
printed++;
|
||||
process.stdout.write(chalk.cyan("."));
|
||||
if (printed % dotsPerLine === 0 && printed < total) {
|
||||
process.stdout.write(` ${chalk.dim(`[${printed}/${total}]`)}\n`);
|
||||
}
|
||||
},
|
||||
succeed: (msg) => {
|
||||
process.stdout.write(` ${chalk.dim(`[${printed}/${total}]`)}\n`);
|
||||
process.stdout.write(`${chalk.green("✓")} ${msg}\n`);
|
||||
},
|
||||
fail: (msg) => {
|
||||
process.stdout.write(` ${chalk.dim(`[${printed}/${total}]`)}\n`);
|
||||
process.stdout.write(`${chalk.red("✗")} ${msg}\n`);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a single React component entry file.
|
||||
*
|
||||
* @param {string} entry Absolute entry file path.
|
||||
* @param {import('esbuild').BuildOptions} buildConfig Shared esbuild configuration.
|
||||
* @returns {Promise<{file: string, output?: string, error: Error|null}>}
|
||||
*/
|
||||
async function buildComponent(entry, buildConfig) {
|
||||
const resolved = resolveComponentPaths(entry);
|
||||
if (!resolved) {
|
||||
return { file: entry, error: new Error(`Unknown path pattern: ${entry}`) };
|
||||
}
|
||||
|
||||
const { file, output } = resolved;
|
||||
fs.mkdirSync(path.dirname(output), { recursive: true });
|
||||
|
||||
try {
|
||||
await esbuild.build({
|
||||
...buildConfig,
|
||||
entryPoints: [entry],
|
||||
outfile: output,
|
||||
});
|
||||
|
||||
return { file, output, error: null };
|
||||
} catch (error) {
|
||||
return { file, error: error instanceof Error ? error : new Error(String(error)) };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve source and output paths for a component entry.
|
||||
*
|
||||
* @param {string} entry Absolute component source path.
|
||||
* @returns {{file: string, output: string} | null} Relative file info and output path, or null for unsupported paths.
|
||||
*/
|
||||
export function resolveComponentPaths(entry) {
|
||||
const rel = path.relative(projectRoot, entry);
|
||||
|
||||
if (rel.includes(path.join('esm', 'src'))) {
|
||||
|
||||
const [part, rawFile] = rel.split(path.join('esm', 'src'));
|
||||
const file = rawFile.replace(/^[\/\\]/, '');
|
||||
|
||||
return {
|
||||
file,
|
||||
output: fromRoot(part, 'esm', 'build', file.replace(/\.(ts|tsx)$/, '.js')),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all builds in parallel, showing incremental dot progress.
|
||||
*
|
||||
* @param {string[]} entryPoints Absolute entry file paths.
|
||||
* @param {import('esbuild').BuildOptions} buildConfig Shared esbuild configuration.
|
||||
* @returns {Promise<{errors: {file: string, output?: string, error: Error|null}[]}>}
|
||||
*/
|
||||
async function runParallelBuilds(entryPoints, buildConfig) {
|
||||
const total = entryPoints.length;
|
||||
/** @type {{file: string, output?: string, error: Error|null}[]} */
|
||||
const errors = [];
|
||||
const startTime = Date.now();
|
||||
|
||||
const progress = createDotProgress(total);
|
||||
progress.start();
|
||||
|
||||
await Promise.all(entryPoints.map(async (entry) => {
|
||||
const result = await buildComponent(entry, buildConfig);
|
||||
if (result.error) {
|
||||
errors.push(result);
|
||||
}
|
||||
progress.tick();
|
||||
}));
|
||||
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||
const succeeded = total - errors.length;
|
||||
|
||||
if (errors.length > 0) {
|
||||
progress.fail(`${succeeded}/${total} built · ${elapsed}s`);
|
||||
for (const e of errors) {
|
||||
console.error(chalk.red(` ✗ ${e.file}: ${e.error?.message ?? ''}`));
|
||||
}
|
||||
} else {
|
||||
progress.succeed(chalk.bold(`${total} components built`) + chalk.dim(` · ${elapsed}s`));
|
||||
}
|
||||
|
||||
return { errors };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the shared esbuild build configuration.
|
||||
*
|
||||
* @param {boolean} isDev Whether development mode is enabled.
|
||||
* @returns {import('esbuild').BuildOptions} esbuild configuration object.
|
||||
*/
|
||||
export function createBuildConfig(isDev) {
|
||||
return {
|
||||
bundle: true,
|
||||
format: "esm",
|
||||
external: ["react", "react/*", "react-dom", "react-dom/*", "@moodlehq/design-system", "@moodlehq/design-system/*", "@moodle/lms", "@moodle/lms/*"],
|
||||
jsx: "automatic",
|
||||
minify: !isDev,
|
||||
sourcemap: isDev ? 'inline' : false,
|
||||
jsxDev: isDev,
|
||||
keepNames: isDev,
|
||||
treeShaking: !isDev,
|
||||
define: { 'process.env.NODE_ENV': isDev ? '"development"' : '"production"' },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build all plugin and core React components.
|
||||
*
|
||||
* @param {boolean} isDev Whether development mode is enabled.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function buildPluginComponents(isDev) {
|
||||
console.log(chalk.green('> Building components...'));
|
||||
|
||||
const entryPoints = glob.sync("**/js/esm/src/**/*.{ts,tsx}", {
|
||||
cwd: projectRoot,
|
||||
absolute: true,
|
||||
ignore: [
|
||||
`${process.cwd()}/node_modules/**`,
|
||||
`${process.cwd()}/vendor/**`,
|
||||
],
|
||||
});
|
||||
|
||||
const buildConfig = createBuildConfig(isDev);
|
||||
|
||||
const { errors } = await runParallelBuilds(entryPoints, buildConfig);
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw new Error(`React build failed: ${errors.length} component(s) could not be built`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start esbuild in native watch mode over all React components.
|
||||
*
|
||||
* Creates a single incremental build context for all entry points so that
|
||||
* esbuild can reuse its internal graph between rebuilds instead of starting
|
||||
* from scratch on every file change.
|
||||
*
|
||||
* @param {boolean} isDev Whether to build in development mode.
|
||||
* @param {((srcFiles: string[]) => void) | undefined} [onRebuild] Called with the rebuilt entry source
|
||||
* files (relative to project root) after each non-initial successful rebuild. Use this to run
|
||||
* follow-up tasks such as linting without coupling them to this module.
|
||||
* @returns {Promise<import('esbuild').BuildContext|null>} The active context, or null if no source files exist.
|
||||
*/
|
||||
export async function watchComponents(isDev, onRebuild) {
|
||||
const entryPoints = glob.sync("**/js/esm/src/**/*.{ts,tsx}", {
|
||||
cwd: projectRoot,
|
||||
absolute: true,
|
||||
ignore: [
|
||||
`${process.cwd()}/node_modules/**`,
|
||||
`${process.cwd()}/vendor/**`,
|
||||
],
|
||||
});
|
||||
|
||||
if (entryPoints.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const buildConfig = createBuildConfig(isDev);
|
||||
|
||||
// Map each source file to an {in, out} pair so esbuild can write each
|
||||
// component to its custom output directory while sharing a single context.
|
||||
// The 'out' path is relative to outdir (projectRoot) and has no extension —
|
||||
// esbuild appends the appropriate extension automatically.
|
||||
// Build entry pairs and ensure output directories exist in a single pass.
|
||||
const entryPairs = entryPoints.flatMap(entry => {
|
||||
const resolved = resolveComponentPaths(entry);
|
||||
if (!resolved) {
|
||||
return [];
|
||||
}
|
||||
fs.mkdirSync(path.dirname(resolved.output), { recursive: true });
|
||||
return [{ in: entry, out: path.relative(projectRoot, resolved.output).replace(/\.js$/, '') }];
|
||||
});
|
||||
|
||||
// Report build results to the terminal after every build (initial and on each change).
|
||||
// metafile: true populates result.metafile.outputs so we know which files were written.
|
||||
// On a rebuild only the affected outputs appear, so it effectively names the changed file.
|
||||
/** @type {import('esbuild').Plugin} */
|
||||
const watchReporter = {
|
||||
name: 'watch-reporter',
|
||||
setup(build) {
|
||||
let isInitial = true;
|
||||
let startTime = 0;
|
||||
|
||||
build.onStart(() => {
|
||||
startTime = Date.now();
|
||||
});
|
||||
|
||||
build.onEnd(result => {
|
||||
const now = new Date().toLocaleTimeString();
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
console.error(chalk.red(`[${now}] ✗ Build failed (${result.errors.length} error(s))`) + chalk.dim(` · ${elapsed}s`));
|
||||
return;
|
||||
}
|
||||
|
||||
const outputs = Object.keys(result.metafile?.outputs ?? {});
|
||||
|
||||
console.log(chalk.green(`[${now}] ✓ ${outputs.length} component(s) built`) + chalk.dim(` · ${elapsed}s`));
|
||||
|
||||
if (isInitial) {
|
||||
isInitial = false;
|
||||
} else if (onRebuild) {
|
||||
// entryPoint is the source file (relative to projectRoot) that triggered
|
||||
// this rebuild. Pass it to the caller so they can run follow-up tasks
|
||||
// (e.g. linting) without this module needing to know about them.
|
||||
const srcFiles = Object.values(result.metafile?.outputs ?? {})
|
||||
.map(output => output.entryPoint)
|
||||
.filter(/** @param {string|undefined} f */ f => !!f);
|
||||
onRebuild(/** @type {string[]} */ (srcFiles));
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const ctx = await esbuild.context({
|
||||
...buildConfig,
|
||||
entryPoints: entryPairs,
|
||||
outdir: projectRoot,
|
||||
metafile: true,
|
||||
plugins: [watchReporter],
|
||||
});
|
||||
|
||||
await ctx.watch();
|
||||
return ctx;
|
||||
}
|
||||
@@ -244,6 +244,22 @@
|
||||
'sourceType': 'module',
|
||||
'requireConfigFile': false
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/*.ts", "**/*.tsx"],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// promise/no-native crashes on TypeScript ASTs (same reason it is
|
||||
// disabled for AMD files above). Native Promises are standard in TS.
|
||||
'promise/no-native': 'off',
|
||||
'promise/avoid-new': 'off',
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -60,3 +60,4 @@ phpcs.xml
|
||||
jsconfig.json
|
||||
UPGRADING-CURRENT.md
|
||||
.phpunit.cache
|
||||
tsconfig.aliases.json
|
||||
|
||||
@@ -385,6 +385,23 @@ const getThirdPartyLibsUpgradable = async() => {
|
||||
return (await Promise.all(upgradableLibraries)).filter((library) => !!library);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to build react sources.
|
||||
*
|
||||
* @param {string} relativeTo
|
||||
* @returns {string[]}
|
||||
*/
|
||||
const getReactTsSrcGlobList = (relativeTo = '') => {
|
||||
const globList = [];
|
||||
fetchComponentData().pathList.forEach(componentPath => {
|
||||
const relativeComponentPath = componentPath.replace(relativeTo, '');
|
||||
globList.push(`${relativeComponentPath}/js/esm/src/**/*.ts`);
|
||||
globList.push(`${relativeComponentPath}/js/esm/src/**/*.tsx`);
|
||||
});
|
||||
|
||||
return globList.map(componentPath => componentPath.replace(/\\/g, '/'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of thirdparty libraries.
|
||||
*
|
||||
@@ -432,4 +449,5 @@ module.exports = {
|
||||
getThirdPartyLibsList,
|
||||
getThirdPartyPaths,
|
||||
getThirdPartyLibsUpgradable,
|
||||
getReactTsSrcGlobList,
|
||||
};
|
||||
|
||||
@@ -41,6 +41,14 @@ module.exports = grunt => {
|
||||
|
||||
// Check YUI module source files.
|
||||
yui: {src: files ? files : grunt.moodleEnv.yuiSrc},
|
||||
|
||||
// Check React source files.
|
||||
'react': {
|
||||
options: {
|
||||
fix: true,
|
||||
},
|
||||
src: files ? files : grunt.moodleEnv.reactSrc,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ const babelRename = function(destPath, srcPath) {
|
||||
};
|
||||
|
||||
module.exports = grunt => {
|
||||
// Load the React build tasks.
|
||||
require('./react')(grunt);
|
||||
|
||||
// Load the Ignorefiles tasks.
|
||||
require('./ignorefiles')(grunt);
|
||||
|
||||
@@ -57,7 +60,7 @@ module.exports = grunt => {
|
||||
// Register JS tasks.
|
||||
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
|
||||
grunt.registerTask('amd', ['ignorefiles', 'eslint:amd', 'rollup']);
|
||||
grunt.registerTask('js', ['amd', 'yui']);
|
||||
grunt.registerTask('js', ['amd', 'yui', 'react']);
|
||||
|
||||
// Register NPM tasks.
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
|
||||
Vendored
+106
@@ -0,0 +1,106 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* jshint node: true, browser: false */
|
||||
/* eslint-env node */
|
||||
// @ts-nocheck
|
||||
|
||||
/**
|
||||
* Grunt tasks for building React components.
|
||||
*
|
||||
* @copyright Meirza <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
module.exports = grunt => {
|
||||
/**
|
||||
* Register react task — build or watch React components.
|
||||
*
|
||||
* Modes:
|
||||
* grunt react — production build
|
||||
* grunt react:dev — development build (sourcemaps, no minification)
|
||||
* grunt react:watch — esbuild native watch (dev mode, incremental context)
|
||||
*
|
||||
* Note: react:watch uses esbuild's own context.watch() and is intentionally
|
||||
* separate from grunt-contrib-watch. This keeps esbuild's incremental build
|
||||
* graph alive between rebuilds rather than restarting from scratch on each change.
|
||||
*/
|
||||
grunt.registerTask('react', 'Build all React components', function(mode) {
|
||||
const done = this.async();
|
||||
const isWatch = mode === 'watch';
|
||||
const isDev = isWatch || mode === 'dev';
|
||||
|
||||
if (isWatch) {
|
||||
const path = require('path');
|
||||
const {spawn} = require('child_process');
|
||||
|
||||
// Run ESLint on the rebuilt source files in check-only mode (no --fix)
|
||||
// to avoid writing changes that would re-trigger esbuild.
|
||||
const eslintBin = path.join(grunt.moodleEnv.gruntFilePath, 'node_modules', '.bin', 'eslint');
|
||||
const onRebuild = (srcFiles) => {
|
||||
if (srcFiles.length === 0) {
|
||||
return;
|
||||
}
|
||||
const absSrcFiles = srcFiles.map(f => path.join(grunt.moodleEnv.gruntFilePath, f));
|
||||
spawn(eslintBin, absSrcFiles, {stdio: 'inherit'})
|
||||
.on('error', err => grunt.log.error(`ESLint: ${err.message}`));
|
||||
};
|
||||
|
||||
(async() => {
|
||||
try {
|
||||
const {watchComponents} = await import('../../.esbuild/plugin/plugincomponents.mjs');
|
||||
|
||||
const ctx = await watchComponents(true, onRebuild);
|
||||
|
||||
if (!ctx) {
|
||||
grunt.log.warn('No React source files found. Nothing to watch.');
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
grunt.log.ok('esbuild is watching for React changes. Press Ctrl+C to stop.');
|
||||
|
||||
// Keep the process alive until the user interrupts. done() is intentionally
|
||||
// not called here — grunt's async mechanism holds the process open.
|
||||
process.on('SIGINT', async() => {
|
||||
await ctx.dispose();
|
||||
done();
|
||||
});
|
||||
} catch (err) {
|
||||
grunt.log.error(err.message);
|
||||
done(false);
|
||||
}
|
||||
})();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
grunt.log.writeln(`Building React components in ${isDev ? 'DEVELOPMENT' : 'PRODUCTION'} mode...`);
|
||||
|
||||
(async() => {
|
||||
try {
|
||||
const {generateAliases} = await import('../../.esbuild/generate-aliases.mjs');
|
||||
const {buildPluginComponents} = await import('../../.esbuild/plugin/plugincomponents.mjs');
|
||||
|
||||
generateAliases();
|
||||
await buildPluginComponents(isDev);
|
||||
done();
|
||||
} catch (err) {
|
||||
grunt.log.error(err.message);
|
||||
done(false);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
};
|
||||
@@ -33,6 +33,9 @@ module.exports = grunt => {
|
||||
// Are we in an AMD directory?
|
||||
} else if (grunt.moodleEnv.inAMD) {
|
||||
grunt.task.run('amd');
|
||||
// Are we in an ESM source directory?
|
||||
} else if (grunt.moodleEnv.inEsm) {
|
||||
grunt.task.run('react');
|
||||
} else {
|
||||
// Run all of the requested startup tasks.
|
||||
grunt.moodleEnv.startupTasks.forEach(taskName => grunt.task.run(taskName));
|
||||
|
||||
@@ -140,6 +140,17 @@ const setupMoodleEnvironment = grunt => {
|
||||
return cwd;
|
||||
};
|
||||
|
||||
const getReactTsConfiguration = () => {
|
||||
// Globbing pattern for matching all react source files.
|
||||
if (inComponent) {
|
||||
return [
|
||||
`${componentDirectory}/js/esm/src/**/*.ts`,
|
||||
`${componentDirectory}/js/esm/src/**/*.tsx`,
|
||||
];
|
||||
}
|
||||
return ComponentList.getReactTsSrcGlobList(`${gruntFilePath}/`);
|
||||
};
|
||||
|
||||
// Detect directories:
|
||||
// * gruntFilePath The real path on disk to this Gruntfile.js
|
||||
// * cwd The current working directory, which can be overridden by the `root` option
|
||||
@@ -153,12 +164,14 @@ const setupMoodleEnvironment = grunt => {
|
||||
const relativeCwd = path.relative(gruntFilePath, cwd);
|
||||
const componentDirectory = ComponentList.getOwningComponentDirectory(relativeCwd);
|
||||
const inComponent = !!componentDirectory;
|
||||
const inEsm = !!componentDirectory && !path.relative(`${componentDirectory}/js/esm/src`, cwd).startsWith('..');
|
||||
const inTheme = !!componentDirectory && componentDirectory.startsWith('public/theme/');
|
||||
const runDir = inComponent ? componentDirectory : relativeCwd;
|
||||
const fullRunDir = fs.realpathSync(gruntFilePath + path.sep + runDir);
|
||||
const {inAMD, amdSrc} = getAmdConfiguration();
|
||||
const {yuiSrc} = getYuiConfiguration();
|
||||
const {cssSrc, scssSrc} = getStyleConfiguration();
|
||||
const reactSrc = getReactTsConfiguration();
|
||||
|
||||
let files = null;
|
||||
if (grunt.option('files')) {
|
||||
@@ -195,11 +208,13 @@ const setupMoodleEnvironment = grunt => {
|
||||
gruntFilePath,
|
||||
inAMD,
|
||||
inComponent,
|
||||
inEsm,
|
||||
inTheme,
|
||||
relativeCwd,
|
||||
runDir,
|
||||
scssSrc,
|
||||
yuiSrc,
|
||||
reactSrc,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Generated
+806
-27
@@ -10,6 +10,7 @@
|
||||
"@babel/eslint-parser": "^7.21.3",
|
||||
"@babel/eslint-plugin": "7.19.1",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@typescript-eslint/parser": "^8.53.1",
|
||||
"@xmldom/xmldom": "^0.8.7",
|
||||
"ajv": "^8.12.0",
|
||||
"async": "^3.2.5",
|
||||
@@ -20,6 +21,7 @@
|
||||
"commander": "^12.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"docdash": "^2.0.2",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-jsdoc": "^48.0.4",
|
||||
"eslint-plugin-promise": "6.0.0",
|
||||
@@ -1876,6 +1878,448 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
|
||||
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
|
||||
"integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
|
||||
"integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
|
||||
"integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
|
||||
"integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
|
||||
"integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
|
||||
"integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
|
||||
"integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
|
||||
"integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openharmony-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
|
||||
"integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -1997,21 +2441,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.56.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
|
||||
"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
|
||||
"version": "8.57.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
|
||||
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
|
||||
"integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
|
||||
"deprecated": "Use @eslint/config-array instead",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
"@humanwhocodes/object-schema": "^2.0.3",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.0.5"
|
||||
},
|
||||
@@ -2020,10 +2467,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@@ -2045,10 +2493,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/object-schema": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||
"dev": true
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"deprecated": "Use @eslint/object-schema instead",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
@@ -2328,6 +2778,213 @@
|
||||
"integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz",
|
||||
"integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.56.1",
|
||||
"@typescript-eslint/types": "8.56.1",
|
||||
"@typescript-eslint/typescript-estree": "8.56.1",
|
||||
"@typescript-eslint/visitor-keys": "8.56.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/project-service": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz",
|
||||
"integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/tsconfig-utils": "^8.56.1",
|
||||
"@typescript-eslint/types": "^8.56.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz",
|
||||
"integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.56.1",
|
||||
"@typescript-eslint/visitor-keys": "8.56.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz",
|
||||
"integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz",
|
||||
"integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz",
|
||||
"integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/project-service": "8.56.1",
|
||||
"@typescript-eslint/tsconfig-utils": "8.56.1",
|
||||
"@typescript-eslint/types": "8.56.1",
|
||||
"@typescript-eslint/visitor-keys": "8.56.1",
|
||||
"debug": "^4.4.3",
|
||||
"minimatch": "^10.2.2",
|
||||
"semver": "^7.7.3",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"ts-api-utils": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
|
||||
"integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "10.2.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
|
||||
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.56.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz",
|
||||
"integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.56.1",
|
||||
"eslint-visitor-keys": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
|
||||
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@ungap/structured-clone": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
||||
@@ -4150,12 +4807,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@@ -4673,6 +5331,48 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
|
||||
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.25.12",
|
||||
"@esbuild/android-arm": "0.25.12",
|
||||
"@esbuild/android-arm64": "0.25.12",
|
||||
"@esbuild/android-x64": "0.25.12",
|
||||
"@esbuild/darwin-arm64": "0.25.12",
|
||||
"@esbuild/darwin-x64": "0.25.12",
|
||||
"@esbuild/freebsd-arm64": "0.25.12",
|
||||
"@esbuild/freebsd-x64": "0.25.12",
|
||||
"@esbuild/linux-arm": "0.25.12",
|
||||
"@esbuild/linux-arm64": "0.25.12",
|
||||
"@esbuild/linux-ia32": "0.25.12",
|
||||
"@esbuild/linux-loong64": "0.25.12",
|
||||
"@esbuild/linux-mips64el": "0.25.12",
|
||||
"@esbuild/linux-ppc64": "0.25.12",
|
||||
"@esbuild/linux-riscv64": "0.25.12",
|
||||
"@esbuild/linux-s390x": "0.25.12",
|
||||
"@esbuild/linux-x64": "0.25.12",
|
||||
"@esbuild/netbsd-arm64": "0.25.12",
|
||||
"@esbuild/netbsd-x64": "0.25.12",
|
||||
"@esbuild/openbsd-arm64": "0.25.12",
|
||||
"@esbuild/openbsd-x64": "0.25.12",
|
||||
"@esbuild/openharmony-arm64": "0.25.12",
|
||||
"@esbuild/sunos-x64": "0.25.12",
|
||||
"@esbuild/win32-arm64": "0.25.12",
|
||||
"@esbuild/win32-ia32": "0.25.12",
|
||||
"@esbuild/win32-x64": "0.25.12"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
@@ -4749,16 +5449,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.56.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
|
||||
"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
|
||||
"version": "8.57.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
|
||||
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
||||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
"@eslint/eslintrc": "^2.1.4",
|
||||
"@eslint/js": "8.56.0",
|
||||
"@humanwhocodes/config-array": "^0.11.13",
|
||||
"@eslint/js": "8.57.1",
|
||||
"@humanwhocodes/config-array": "^0.13.0",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"@ungap/structured-clone": "^1.2.0",
|
||||
@@ -9546,10 +10248,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mute-stream": {
|
||||
"version": "1.0.0",
|
||||
@@ -12480,6 +13183,54 @@
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fdir": "^6.5.0",
|
||||
"picomatch": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby/node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
@@ -12572,6 +13323,19 @@
|
||||
"node": ">= 14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
@@ -12614,6 +13378,21 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/typical": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"@babel/core": "7.17.5",
|
||||
"@babel/eslint-parser": "^7.21.3",
|
||||
"@babel/eslint-plugin": "7.19.1",
|
||||
"@typescript-eslint/parser": "^8.53.1",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@xmldom/xmldom": "^0.8.7",
|
||||
"ajv": "^8.12.0",
|
||||
@@ -21,6 +22,7 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"docdash": "^2.0.2",
|
||||
"eslint": "^8.56.0",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint-plugin-jsdoc": "^48.0.4",
|
||||
"eslint-plugin-promise": "6.0.0",
|
||||
"fb-watchman": "^2.0.2",
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./tsconfig.aliases.json", // Added to extend the generated aliases.
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"jsx": "react",
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["public/**/esm/src/**/*"]
|
||||
}
|
||||
Reference in New Issue
Block a user