mirror of
https://github.com/vega-org/vega-providers.git
synced 2026-04-17 15:41:45 +00:00
feat: integrate esbuild for bundling providers and update dependencies
This commit is contained in:
530
build-bundled.js
530
build-bundled.js
@@ -1,432 +1,172 @@
|
||||
const esbuild = require("esbuild");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { execSync } = require("child_process");
|
||||
const { minify } = require("terser");
|
||||
|
||||
// Build configuration
|
||||
const PROVIDERS_DIR = "./providers";
|
||||
const DIST_DIR = "./dist";
|
||||
const TEMP_DIR = "./temp-build";
|
||||
const SKIP_MINIFY = process.env.SKIP_MINIFY === "true";
|
||||
|
||||
// Colors for console output
|
||||
const colors = {
|
||||
reset: "\x1b[0m",
|
||||
bright: "\x1b[1m",
|
||||
green: "\x1b[32m",
|
||||
red: "\x1b[31m",
|
||||
yellow: "\x1b[33m",
|
||||
blue: "\x1b[34m",
|
||||
magenta: "\x1b[35m",
|
||||
cyan: "\x1b[36m",
|
||||
};
|
||||
// Find all provider directories
|
||||
const providersDir = path.join(__dirname, "providers");
|
||||
const providerDirs = fs
|
||||
.readdirSync(providersDir, { withFileTypes: true })
|
||||
.filter(
|
||||
(dirent) =>
|
||||
dirent.isDirectory() && !dirent.name.startsWith(".") && dirent.name !== "extractors",
|
||||
)
|
||||
.map((dirent) => dirent.name);
|
||||
|
||||
const log = {
|
||||
info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
|
||||
success: (msg) => console.log(`${colors.green}✅${colors.reset} ${msg}`),
|
||||
error: (msg) => console.log(`${colors.red}❌${colors.reset} ${msg}`),
|
||||
warning: (msg) => console.log(`${colors.yellow}⚠️${colors.reset} ${msg}`),
|
||||
build: (msg) => console.log(`${colors.magenta}🔨${colors.reset} ${msg}`),
|
||||
file: (msg) => console.log(`${colors.cyan}📄${colors.reset} ${msg}`),
|
||||
};
|
||||
console.log(`Found ${providerDirs.length} providers to build`);
|
||||
|
||||
/**
|
||||
* Bundled provider builder - creates self-contained JS files without imports
|
||||
*/
|
||||
class BundledProviderBuilder {
|
||||
constructor() {
|
||||
this.startTime = Date.now();
|
||||
this.providers = [];
|
||||
async function buildProvider(providerName) {
|
||||
const providerPath = path.join(providersDir, providerName);
|
||||
const distPath = path.join(__dirname, "dist", providerName);
|
||||
|
||||
// Create dist directory
|
||||
if (!fs.existsSync(distPath)) {
|
||||
fs.mkdirSync(distPath, { recursive: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the dist and temp directories
|
||||
*/
|
||||
cleanDirs() {
|
||||
if (fs.existsSync(DIST_DIR)) {
|
||||
fs.rmSync(DIST_DIR, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(DIST_DIR, { recursive: true });
|
||||
const modules = ["catalog", "posts", "meta", "stream", "episodes"];
|
||||
const results = [];
|
||||
|
||||
if (fs.existsSync(TEMP_DIR)) {
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
||||
}
|
||||
for (const moduleName of modules) {
|
||||
const modulePath = path.join(providerPath, `${moduleName}.ts`);
|
||||
|
||||
/**
|
||||
* Discover all provider directories (excluding extractors and utility files)
|
||||
*/
|
||||
discoverProviders() {
|
||||
const items = fs.readdirSync(PROVIDERS_DIR, { withFileTypes: true });
|
||||
const excludeDirs = ["extractors", "extractors copy"];
|
||||
|
||||
this.providers = items
|
||||
.filter((item) => item.isDirectory())
|
||||
.filter((item) => !item.name.startsWith("."))
|
||||
.filter((item) => !excludeDirs.includes(item.name))
|
||||
.map((item) => item.name);
|
||||
|
||||
log.info(
|
||||
`Found ${this.providers.length} providers: ${this.providers.join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile TypeScript to JavaScript first
|
||||
*/
|
||||
compileTypeScript() {
|
||||
log.build("Compiling TypeScript files...");
|
||||
|
||||
try {
|
||||
execSync("npx tsc", {
|
||||
stdio: "pipe",
|
||||
encoding: "utf8",
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
log.error("TypeScript compilation failed:");
|
||||
if (error.stdout) console.log(error.stdout);
|
||||
if (error.stderr) console.log(error.stderr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle each provider module to be self-contained
|
||||
* This inlines all imports from extractors into the provider files
|
||||
*/
|
||||
bundleProviders() {
|
||||
log.build("Bundling provider modules...");
|
||||
|
||||
for (const provider of this.providers) {
|
||||
const providerDistDir = path.join(DIST_DIR, provider);
|
||||
|
||||
if (!fs.existsSync(providerDistDir)) {
|
||||
if (!fs.existsSync(modulePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const files = [
|
||||
"stream.js",
|
||||
"catalog.js",
|
||||
"posts.js",
|
||||
"meta.js",
|
||||
"episodes.js",
|
||||
];
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(providerDistDir, file);
|
||||
if (fs.existsSync(filePath)) {
|
||||
this.bundleFile(filePath, provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle a single file by inlining all local imports
|
||||
*/
|
||||
bundleFile(filePath, provider) {
|
||||
let content = fs.readFileSync(filePath, "utf8");
|
||||
|
||||
// Find all require statements - both destructuring and non-destructuring patterns
|
||||
// Pattern 1: const { x, y } = require("path")
|
||||
const destructuringRegex =
|
||||
/(?:const|let|var)\s+\{([^}]+)\}\s*=\s*require\s*\(\s*["']([^"']+)["']\s*\);?/g;
|
||||
// Pattern 2: const hubcloud_1 = require("path")
|
||||
const simpleRequireRegex =
|
||||
/(?:const|let|var)\s+(\w+)\s*=\s*require\s*\(\s*["']([^"']+)["']\s*\);?/g;
|
||||
|
||||
const imports = [];
|
||||
let match;
|
||||
|
||||
while ((match = destructuringRegex.exec(content)) !== null) {
|
||||
imports.push({
|
||||
full: match[0],
|
||||
names: match[1],
|
||||
varName: null,
|
||||
path: match[2],
|
||||
isDestructuring: true,
|
||||
});
|
||||
}
|
||||
|
||||
while ((match = simpleRequireRegex.exec(content)) !== null) {
|
||||
// Skip if already matched by destructuring regex
|
||||
if (imports.some((i) => i.full === match[0])) continue;
|
||||
imports.push({
|
||||
full: match[0],
|
||||
names: null,
|
||||
varName: match[1],
|
||||
path: match[2],
|
||||
isDestructuring: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Process each import
|
||||
for (const imp of imports) {
|
||||
// Skip external modules (axios, cheerio, etc.) - they come from context
|
||||
if (!imp.path.startsWith(".") && !imp.path.startsWith("/")) {
|
||||
// Remove the require statement for external modules
|
||||
content = content.replace(imp.full, `// External: ${imp.path}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Resolve the import path
|
||||
const importDir = path.dirname(filePath);
|
||||
let resolvedPath = path.resolve(importDir, imp.path);
|
||||
|
||||
// Add .js extension if needed
|
||||
if (!resolvedPath.endsWith(".js")) {
|
||||
resolvedPath += ".js";
|
||||
}
|
||||
|
||||
if (fs.existsSync(resolvedPath)) {
|
||||
// Read the imported file
|
||||
let importedContent = fs.readFileSync(resolvedPath, "utf8");
|
||||
|
||||
// Remove exports.X = X pattern and just keep the functions
|
||||
importedContent = importedContent.replace(
|
||||
/exports\.\w+\s*=\s*\w+;?/g,
|
||||
"",
|
||||
);
|
||||
|
||||
// Remove Object.defineProperty exports
|
||||
importedContent = importedContent.replace(
|
||||
/Object\.defineProperty\(exports,\s*"__esModule"[^;]+;/g,
|
||||
"",
|
||||
);
|
||||
|
||||
// Remove require statements from imported file too (they use context)
|
||||
importedContent = importedContent.replace(
|
||||
/(?:const|let|var)\s+\{[^}]+\}\s*=\s*require\s*\(\s*["'][^"']+["']\s*\);?/g,
|
||||
"",
|
||||
);
|
||||
importedContent = importedContent.replace(
|
||||
/(?:const|let|var)\s+\w+\s*=\s*require\s*\(\s*["'][^"']+["']\s*\);?/g,
|
||||
"",
|
||||
);
|
||||
|
||||
// Clean up the content
|
||||
importedContent = importedContent.replace(/"use strict";?/g, "");
|
||||
|
||||
// Check if this is an extractor file
|
||||
if (
|
||||
imp.path.includes("extractor") ||
|
||||
resolvedPath.includes("extractor")
|
||||
) {
|
||||
// Insert the extractor function at the top of the file
|
||||
content = content.replace(
|
||||
imp.full,
|
||||
`// Inlined from: ${imp.path}\n${importedContent.trim()}`,
|
||||
);
|
||||
|
||||
// For non-destructuring imports, we need to replace function calls
|
||||
// TypeScript outputs: (0, hubcloud_1.hubcloudExtractor)(...)
|
||||
// We need to replace with just: hubcloudExtractor(...)
|
||||
if (!imp.isDestructuring && imp.varName) {
|
||||
// Find the exported function name - look for exports.funcName or function funcNameExtractor
|
||||
// The exports pattern looks like: exports.hubcloudExtractor = hubcloudExtractor;
|
||||
const exportsMatch = importedContent.match(
|
||||
/exports\.(\w+Extractor)\s*=/,
|
||||
);
|
||||
// Also try matching the function definition directly
|
||||
const funcDefMatch = importedContent.match(
|
||||
/function\s+(\w+Extractor)\s*\(/,
|
||||
);
|
||||
const funcName = exportsMatch?.[1] || funcDefMatch?.[1];
|
||||
|
||||
if (funcName) {
|
||||
// Replace (0, varName.funcName) or (0,varName.funcName) with just funcName
|
||||
const callPattern = new RegExp(
|
||||
`\\(0,\\s*${imp.varName}\\.${funcName}\\)`,
|
||||
"g",
|
||||
);
|
||||
content = content.replace(callPattern, funcName);
|
||||
// Also replace varName.funcName (without the (0, ) wrapper)
|
||||
const simpleCallPattern = new RegExp(
|
||||
`${imp.varName}\\.${funcName}`,
|
||||
"g",
|
||||
);
|
||||
content = content.replace(simpleCallPattern, funcName);
|
||||
}
|
||||
}
|
||||
} else if (imp.path.includes("types")) {
|
||||
// Types are not needed at runtime, just remove the import
|
||||
content = content.replace(imp.full, `// Types removed: ${imp.path}`);
|
||||
} else {
|
||||
// Other local imports - inline them
|
||||
content = content.replace(
|
||||
imp.full,
|
||||
`// Inlined from: ${imp.path}\n${importedContent.trim()}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// File doesn't exist, comment out the import
|
||||
content = content.replace(imp.full, `// Not found: ${imp.path}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the content
|
||||
content = content.replace(/"use strict";?/g, "");
|
||||
content = content.replace(
|
||||
/Object\.defineProperty\(exports,\s*"__esModule"[^;]+;/g,
|
||||
"",
|
||||
);
|
||||
|
||||
// Write the bundled file
|
||||
fs.writeFileSync(filePath, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify all JavaScript files
|
||||
*/
|
||||
async minifyFiles() {
|
||||
const keepConsole = process.env.KEEP_CONSOLE === "true";
|
||||
log.build(
|
||||
`Minifying JavaScript files... ${
|
||||
keepConsole ? "(keeping console logs)" : "(removing console logs)"
|
||||
}`,
|
||||
);
|
||||
|
||||
const minifyFile = async (filePath) => {
|
||||
try {
|
||||
const code = fs.readFileSync(filePath, "utf8");
|
||||
const result = await minify(code, {
|
||||
// Use esbuild to bundle the module
|
||||
const result = await esbuild.build({
|
||||
entryPoints: [modulePath],
|
||||
bundle: true,
|
||||
platform: "node",
|
||||
format: "cjs",
|
||||
target: "es2015",
|
||||
write: false,
|
||||
external: [], // Bundle everything
|
||||
minify: false, // We'll minify separately if needed
|
||||
keepNames: true,
|
||||
treeShaking: true,
|
||||
outfile: `${moduleName}.js`,
|
||||
});
|
||||
|
||||
let code = result.outputFiles[0].text;
|
||||
|
||||
// Post-process the code for React Native compatibility
|
||||
// Remove require statements for built-in modules that aren't available
|
||||
code = code.replace(/require\(['"]node:.*?['"]\)/g, "{}");
|
||||
|
||||
// Fix CommonJS exports for React Native's ProviderManager execution context
|
||||
// The ProviderManager only has `exports` object, not `module`
|
||||
|
||||
// Extract what's being exported by looking at the __export call
|
||||
// Pattern: __export(xxx_exports, { funcName: () => funcName, ... });
|
||||
const exportMatch = code.match(/__export\((\w+),\s*\{([^}]+)\}\);/);
|
||||
|
||||
if (exportMatch) {
|
||||
const exportsVar = exportMatch[1];
|
||||
const exportsContent = exportMatch[2];
|
||||
|
||||
// Parse the export entries like "funcName: () => funcName"
|
||||
const exportEntries = exportsContent
|
||||
.split(',')
|
||||
.map(entry => {
|
||||
const match = entry.trim().match(/(\w+):\s*\(\)\s*=>\s*(\w+)/);
|
||||
return match ? match[1] : null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
// Replace module.exports pattern
|
||||
code = code.replace(
|
||||
/module\.exports\s*=\s*__toCommonJS\((\w+)\);/g,
|
||||
''
|
||||
);
|
||||
|
||||
// Add direct exports assignments at the end
|
||||
const directExports = exportEntries
|
||||
.map(name => `exports.${name} = ${name};`)
|
||||
.join('\n');
|
||||
|
||||
// Add the exports before the final comment
|
||||
code = code.replace(
|
||||
/\/\/ Annotate the CommonJS export names for ESM import in node:/,
|
||||
`${directExports}\n// Annotate the CommonJS export names for ESM import in node:`
|
||||
);
|
||||
}
|
||||
|
||||
// Also handle the "0 && (module.exports = {...})" pattern at the end
|
||||
code = code.replace(/0\s*&&\s*\(module\.exports\s*=\s*\{[^}]*\}\);?/g, "");
|
||||
|
||||
// Minify if not skipped
|
||||
if (!SKIP_MINIFY) {
|
||||
const minified = await minify(code, {
|
||||
compress: {
|
||||
drop_console: !keepConsole,
|
||||
drop_debugger: true,
|
||||
pure_funcs: keepConsole
|
||||
? ["console.debug"]
|
||||
: [
|
||||
"console.debug",
|
||||
"console.log",
|
||||
"console.info",
|
||||
"console.warn",
|
||||
],
|
||||
drop_console: false,
|
||||
passes: 2,
|
||||
},
|
||||
mangle: {
|
||||
keep_fnames: false,
|
||||
},
|
||||
mangle: false,
|
||||
format: {
|
||||
comments: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.code) {
|
||||
fs.writeFileSync(filePath, result.code);
|
||||
return true;
|
||||
if (minified.code) {
|
||||
code = minified.code;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the output
|
||||
const outputPath = path.join(distPath, `${moduleName}.js`);
|
||||
fs.writeFileSync(outputPath, code);
|
||||
|
||||
results.push({
|
||||
moduleName,
|
||||
size: code.length,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`✓ ${providerName}/${moduleName}.js (${(code.length / 1024).toFixed(1)}kb)`,
|
||||
);
|
||||
} catch (error) {
|
||||
log.error(`Error minifying ${filePath}: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const findJsFiles = (dir) => {
|
||||
const files = [];
|
||||
if (!fs.existsSync(dir)) return files;
|
||||
|
||||
const items = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const item of items) {
|
||||
const fullPath = path.join(dir, item.name);
|
||||
if (item.isDirectory()) {
|
||||
files.push(...findJsFiles(fullPath));
|
||||
} else if (item.isFile() && item.name.endsWith(".js")) {
|
||||
files.push(fullPath);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
};
|
||||
|
||||
const jsFiles = findJsFiles(DIST_DIR);
|
||||
let minifiedCount = 0;
|
||||
let totalSizeBefore = 0;
|
||||
let totalSizeAfter = 0;
|
||||
|
||||
for (const filePath of jsFiles) {
|
||||
const statsBefore = fs.statSync(filePath);
|
||||
totalSizeBefore += statsBefore.size;
|
||||
|
||||
const success = await minifyFile(filePath);
|
||||
if (success) {
|
||||
const statsAfter = fs.statSync(filePath);
|
||||
totalSizeAfter += statsAfter.size;
|
||||
minifiedCount++;
|
||||
console.error(`✗ Error building ${providerName}/${moduleName}:`, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
const compressionRatio =
|
||||
totalSizeBefore > 0
|
||||
? (
|
||||
((totalSizeBefore - totalSizeAfter) / totalSizeBefore) *
|
||||
100
|
||||
).toFixed(1)
|
||||
: 0;
|
||||
return { providerName, modules: results };
|
||||
}
|
||||
|
||||
log.success(
|
||||
`Minified ${minifiedCount}/${jsFiles.length} files. ` +
|
||||
`Size reduced by ${compressionRatio}% (${totalSizeBefore} → ${totalSizeAfter} bytes)`,
|
||||
async function buildAll() {
|
||||
const startTime = Date.now();
|
||||
console.log(`Building providers${SKIP_MINIFY ? " (without minification)" : ""}...\n`);
|
||||
|
||||
// Clear dist directory
|
||||
const distDir = path.join(__dirname, "dist");
|
||||
if (fs.existsSync(distDir)) {
|
||||
fs.rmSync(distDir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(distDir, { recursive: true });
|
||||
|
||||
// Build all providers
|
||||
const results = await Promise.all(providerDirs.map(buildProvider));
|
||||
|
||||
const totalModules = results.reduce((sum, r) => sum + r.modules.length, 0);
|
||||
const totalSize = results.reduce(
|
||||
(sum, r) => sum + r.modules.reduce((s, m) => s + m.size, 0),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up temp directory
|
||||
*/
|
||||
cleanup() {
|
||||
if (fs.existsSync(TEMP_DIR)) {
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build everything
|
||||
*/
|
||||
async build() {
|
||||
const isWatchMode = process.env.NODE_ENV === "development";
|
||||
|
||||
if (isWatchMode) {
|
||||
const endTime = Date.now();
|
||||
console.log(
|
||||
`\n${colors.cyan}🔄 Auto-build triggered${colors.reset} ${new Date().toLocaleTimeString()}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`\n${colors.bright}🚀 Starting bundled provider build...${colors.reset}\n`,
|
||||
`\n✓ Built ${totalModules} modules from ${providerDirs.length} providers in ${((endTime - startTime) / 1000).toFixed(2)}s`,
|
||||
);
|
||||
console.log(` Total size: ${(totalSize / 1024).toFixed(1)}kb`);
|
||||
}
|
||||
|
||||
this.cleanDirs();
|
||||
this.discoverProviders();
|
||||
|
||||
const compiled = this.compileTypeScript();
|
||||
if (!compiled) {
|
||||
log.error("Build failed due to compilation errors");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
this.bundleProviders();
|
||||
|
||||
if (!process.env.SKIP_MINIFY) {
|
||||
await this.minifyFiles();
|
||||
} else {
|
||||
log.info("Skipping minification (SKIP_MINIFY=true)");
|
||||
}
|
||||
|
||||
this.cleanup();
|
||||
|
||||
const buildTime = Date.now() - this.startTime;
|
||||
log.success(`Build completed in ${buildTime}ms`);
|
||||
|
||||
if (isWatchMode) {
|
||||
console.log(`${colors.green}👀 Watching for changes...${colors.reset}\n`);
|
||||
} else {
|
||||
console.log(
|
||||
`${colors.bright}✨ Build completed successfully!${colors.reset}\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the build
|
||||
const builder = new BundledProviderBuilder();
|
||||
builder.build().catch((error) => {
|
||||
buildAll().catch((error) => {
|
||||
console.error("Build failed:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
485
package-lock.json
generated
485
package-lock.json
generated
@@ -21,6 +21,7 @@
|
||||
"concurrently": "^8.2.2",
|
||||
"cors": "^2.8.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild": "^0.27.2",
|
||||
"express": "^4.21.2",
|
||||
"nodemon": "^3.1.10",
|
||||
"terser": "^5.43.1",
|
||||
@@ -37,6 +38,448 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
|
||||
"integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
|
||||
"integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
|
||||
"integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
|
||||
"integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
|
||||
"integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
|
||||
"integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
|
||||
"integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
|
||||
"integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
|
||||
"integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openharmony-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
|
||||
"integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
|
||||
"integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
|
||||
"integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/balanced-match": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||
@@ -1024,6 +1467,48 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
|
||||
"integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.27.2",
|
||||
"@esbuild/android-arm": "0.27.2",
|
||||
"@esbuild/android-arm64": "0.27.2",
|
||||
"@esbuild/android-x64": "0.27.2",
|
||||
"@esbuild/darwin-arm64": "0.27.2",
|
||||
"@esbuild/darwin-x64": "0.27.2",
|
||||
"@esbuild/freebsd-arm64": "0.27.2",
|
||||
"@esbuild/freebsd-x64": "0.27.2",
|
||||
"@esbuild/linux-arm": "0.27.2",
|
||||
"@esbuild/linux-arm64": "0.27.2",
|
||||
"@esbuild/linux-ia32": "0.27.2",
|
||||
"@esbuild/linux-loong64": "0.27.2",
|
||||
"@esbuild/linux-mips64el": "0.27.2",
|
||||
"@esbuild/linux-ppc64": "0.27.2",
|
||||
"@esbuild/linux-riscv64": "0.27.2",
|
||||
"@esbuild/linux-s390x": "0.27.2",
|
||||
"@esbuild/linux-x64": "0.27.2",
|
||||
"@esbuild/netbsd-arm64": "0.27.2",
|
||||
"@esbuild/netbsd-x64": "0.27.2",
|
||||
"@esbuild/openbsd-arm64": "0.27.2",
|
||||
"@esbuild/openbsd-x64": "0.27.2",
|
||||
"@esbuild/openharmony-arm64": "0.27.2",
|
||||
"@esbuild/sunos-x64": "0.27.2",
|
||||
"@esbuild/win32-arm64": "0.27.2",
|
||||
"@esbuild/win32-ia32": "0.27.2",
|
||||
"@esbuild/win32-x64": "0.27.2"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"concurrently": "^8.2.2",
|
||||
"cors": "^2.8.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild": "^0.27.2",
|
||||
"express": "^4.21.2",
|
||||
"nodemon": "^3.1.10",
|
||||
"terser": "^5.43.1",
|
||||
|
||||
Reference in New Issue
Block a user