diff --git a/backend/src/build-system/__tests__/backend-gen.spec.ts b/backend/src/build-system/__tests__/backend-gen.spec.ts new file mode 100644 index 00000000..7f7eba04 --- /dev/null +++ b/backend/src/build-system/__tests__/backend-gen.spec.ts @@ -0,0 +1,78 @@ +import { isIntegrationTest } from 'src/common/utils'; +import { BuildSequence } from '../types'; +import { ProjectInitHandler } from '../handlers/project-init'; +import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; +import { UXSMDHandler } from '../handlers/ux/sitemap-document'; +import { DBRequirementHandler } from '../handlers/database/requirements-document'; +import { UXDMDHandler } from '../handlers/ux/datamap'; +import { BuilderContext } from '../context'; +import { DBSchemaHandler } from '../handlers/database/schemas/schemas'; +import { BackendRequirementHandler } from '../handlers/backend/requirements-document'; +import { BackendCodeHandler } from '../handlers/backend/code-generate'; + +(isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { + it('should execute build sequence successfully', async () => { + const sequence: BuildSequence = { + id: 'test-backend-sequence', + version: '1.0.0', + name: 'Wrtie a Cool personal website', + description: + 'A personal blog website. I am a cybersecurity engineer so i want it to show i am a really cool hacker, with cool terminal functionality', + databaseType: 'SQLite', + model: 'gpt-4o-mini', + projectSize: 'medium', // limit for fun + nodes: [ + { + handler: ProjectInitHandler, + name: 'Project Folders Setup', + }, + { + handler: PRDHandler, + name: 'Project Requirements Document Node', + }, + { + handler: UXSMDHandler, + name: 'UX Sitemap Document Node', + }, + { + handler: UXDMDHandler, + name: 'UX DataMap Document Node', + }, + { + handler: DBRequirementHandler, + name: 'Database Requirements Node', + // requires: ['op:UX:DATAMAP:DOC'], + }, + { + handler: DBSchemaHandler, + name: 'Database schema Node', + // requires: ['op:UX:DATAMAP:DOC'], + }, + { + handler: BackendRequirementHandler, + name: 'Backend Requirements Node', + // requires: ['op:DATABASE_REQ', 'op:UX:DATAMAP:DOC', 'op:UX:SMD'], + }, + // // { + // // handler: BackendFileStructureAndArchitectureHandler, + // // name: 'Backend File Structure and Architecture', + // // }, + { + handler: BackendCodeHandler, + name: 'Backend Code Generator Node', + }, + // { + // handler: BackendFileReviewHandler, + // name: 'Backend File review Node', + // }, + // { + // handler: FrontendCodeHandler, + // name: 'Frontend Code Generator Node', + // }, + ], + packages: [], + }; + const context = new BuilderContext(sequence, 'fullstack-code-gen'); + await context.execute(); + }, 2000000); +}); diff --git a/backend/src/build-system/__tests__/fullstack-gen.spec.ts b/backend/src/build-system/__tests__/fullstack-gen.spec.ts index d62758af..fa9650cc 100644 --- a/backend/src/build-system/__tests__/fullstack-gen.spec.ts +++ b/backend/src/build-system/__tests__/fullstack-gen.spec.ts @@ -3,13 +3,15 @@ import { BuildSequence } from '../types'; import { ProjectInitHandler } from '../handlers/project-init'; import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; import { UXSMDHandler } from '../handlers/ux/sitemap-document'; -import { UXSMSHandler } from '../handlers/ux/sitemap-structure'; import { DBRequirementHandler } from '../handlers/database/requirements-document'; import { UXDMDHandler } from '../handlers/ux/datamap'; import { BuilderContext } from '../context'; -import { FrontendCodeHandler } from '../handlers/frontend-code-generate'; -import { FileStructureAndArchitectureHandler } from '../handlers/file-manager/file-struct'; +import { DBSchemaHandler } from '../handlers/database/schemas/schemas'; import { BackendRequirementHandler } from '../handlers/backend/requirements-document'; +import { FileStructureAndArchitectureHandler } from '../handlers/file-manager/file-struct'; +import { UXSMSHandler } from '../handlers/ux/sitemap-structure'; +import { BackendCodeHandler } from '../handlers/backend/code-generate'; +import { FrontendCodeHandler } from '../handlers/frontend-code-generate'; (isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { it('should execute build sequence successfully', async () => { @@ -17,8 +19,7 @@ import { BackendRequirementHandler } from '../handlers/backend/requirements-docu id: 'test-backend-sequence', version: '1.0.0', name: 'Wrtie a Cool personal website', - description: - 'A personal blog website. I am a cybersecurity engineer so i want it to show i am a really cool hacker, with cool terminal functionality', + description: `A personal blog website. I am a cybersecurity engineer so i want it to show i am a really cool hacker, with cool terminal functionality`, databaseType: 'SQLite', model: 'gpt-4o-mini', projectSize: 'medium', // limit for fun @@ -38,7 +39,6 @@ import { BackendRequirementHandler } from '../handlers/backend/requirements-docu { handler: UXSMSHandler, name: 'UX Sitemap Structure Node', - // requires: ['op:UX:SMD'], }, { handler: UXDMDHandler, @@ -53,15 +53,33 @@ import { BackendRequirementHandler } from '../handlers/backend/requirements-docu name: 'Database Requirements Node', // requires: ['op:UX:DATAMAP:DOC'], }, + { + handler: DBSchemaHandler, + name: 'Database schema Node', + // requires: ['op:UX:DATAMAP:DOC'], + }, { handler: BackendRequirementHandler, name: 'Backend Requirements Node', // requires: ['op:DATABASE_REQ', 'op:UX:DATAMAP:DOC', 'op:UX:SMD'], }, + { + handler: BackendCodeHandler, + name: 'Backend Code Generator Node', + }, { handler: FrontendCodeHandler, name: 'Frontend Code Generator Node', }, + + // // { + // // handler: BackendFileStructureAndArchitectureHandler, + // // name: 'Backend File Structure and Architecture', + // // }, + // { + // handler: BackendFileReviewHandler, + // name: 'Backend File review Node', + // }, ], packages: [], }; diff --git a/backend/src/build-system/handlers/backend/code-generate/index.ts b/backend/src/build-system/handlers/backend/code-generate/index.ts index ddff2144..47742485 100644 --- a/backend/src/build-system/handlers/backend/code-generate/index.ts +++ b/backend/src/build-system/handlers/backend/code-generate/index.ts @@ -1,7 +1,6 @@ import { BuildHandler, BuildResult } from 'src/build-system/types'; import { BuilderContext } from 'src/build-system/context'; import { generateBackendCodePrompt } from './prompt'; -import { saveGeneratedCode } from 'src/build-system/utils/files'; import * as path from 'path'; import { formatResponse } from 'src/build-system/utils/strings'; import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; @@ -16,6 +15,13 @@ import { UXSMDHandler } from '../../ux/sitemap-document'; import { UXDMDHandler } from '../../ux/datamap'; import { DBSchemaHandler } from '../../database/schemas/schemas'; import { BackendRequirementHandler } from '../requirements-document'; +import { MessageInterface } from 'src/common/model-provider/types'; +import { + CodeQueueProcessor, + CodeTaskQueue, +} from '../../frontend-code-generate/CodeReview'; +import { Logger } from '@nestjs/common'; +import { CodeValidator } from '../../frontend-code-generate/CodeValidator'; /** * BackendCodeHandler is responsible for generating the backend codebase @@ -23,13 +29,10 @@ import { BackendRequirementHandler } from '../requirements-document'; */ @BuildNode() -@BuildNodeRequire([ - UXSMDHandler, - UXDMDHandler, - DBSchemaHandler, - BackendRequirementHandler, -]) +@BuildNodeRequire([UXDMDHandler, DBSchemaHandler, BackendRequirementHandler]) export class BackendCodeHandler implements BuildHandler { + readonly logger: Logger = new Logger('BackendCodeHandler'); + async run(context: BuilderContext): Promise> { const projectName = context.getGlobalContext('projectName') || 'Default Project Name'; @@ -40,7 +43,9 @@ export class BackendCodeHandler implements BuildHandler { const datamapDoc = context.getNodeData(UXDMDHandler); const databaseSchemas = context.getNodeData(DBSchemaHandler); const backendRequirementDoc = - context.getNodeData(BackendRequirementHandler)?.overview || ''; + context.getNodeData(BackendRequirementHandler) || ''; + const backendPath = context.getGlobalContext('backendPath'); + this.logger.log('backendPath: ' + backendPath); // Validate required data if (!sitemapDoc || !datamapDoc || !databaseSchemas) { @@ -55,38 +60,57 @@ export class BackendCodeHandler implements BuildHandler { ); } + const validator = new CodeValidator(backendPath, 'backend'); //TODO: make here dynamic + const queue = new CodeTaskQueue(); + const renameMap = new Map(); + const currentFile = 'index.js'; const dependencyFile = 'dependencies.json'; // Generate the prompt using the provided documents and project name const backendCodePrompt = generateBackendCodePrompt( projectName, - sitemapDoc, - datamapDoc, - backendRequirementDoc, databaseType, - databaseSchemas, currentFile, - 'javascript', // TODO: make sure this lang come from the context + 'Javascript', // TODO: make sure this lang come from the context dependencyFile, ); + const messages = [ + { + role: 'system' as const, + content: backendCodePrompt, + }, + { + role: 'user' as const, + content: `## Database Schema: + ${databaseSchemas} + `, + }, + { + role: 'user' as const, + content: `## Backend Requirement: + ${backendRequirementDoc} + `, + }, + { + role: 'user', + content: `Now you can provide the code, don't forget the tags. Do not be lazy.`, + }, + ] as MessageInterface[]; + let generatedCode: string; try { const modelResponse = await chatSyncWithClocker( context, { - model: 'gpt-4o-mini', - messages: [{ content: backendCodePrompt, role: 'system' }], + // model: 'gpt-4o-mini', + model: 'o3-mini-high', + messages: messages, }, 'generateBackendCode', BackendCodeHandler.name, ); - - generatedCode = formatResponse(modelResponse); - - const uuid = context.getGlobalContext('projectUUID'); - saveGeneratedCode(path.join(uuid, 'backend', currentFile), generatedCode); generatedCode = formatResponse(modelResponse); if (!generatedCode) { throw new ResponseParsingError('Response tag extraction failed.'); @@ -105,16 +129,307 @@ export class BackendCodeHandler implements BuildHandler { const savePath = path.join(uuid, 'backend', currentFile); try { - saveGeneratedCode(savePath, generatedCode); + // saveGeneratedCode(savePath, generatedCode); + queue.enqueue({ + filePath: currentFile, + fileContents: generatedCode, + dependenciesPath: '', + }); } catch (error) { throw new FileWriteError( `Failed to save backend code to ${savePath}: ${error.message}`, ); } + const queueProcessor = new CodeQueueProcessor( + validator, + queue, + context, + 'backend', //TODO: make here dynamic + backendPath, + renameMap, + ); + await queueProcessor.processAllTasks(); + return { success: true, data: generatedCode, }; } } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// import { BuildHandler, BuildResult } from 'src/build-system/types'; +// import { BuilderContext } from 'src/build-system/context'; +// import { generateBackendCodePrompt } from './prompt'; +// import { formatResponse } from 'src/build-system/utils/strings'; +// import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; +// import { +// FileWriteError, +// InvalidParameterError, +// MissingConfigurationError, +// ResponseParsingError, +// } from 'src/build-system/errors'; +// import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; +// import { UXSMDHandler } from '../../ux/sitemap-document'; +// import { UXDMDHandler } from '../../ux/datamap'; +// import { DBSchemaHandler } from '../../database/schemas/schemas'; +// import { BackendRequirementHandler } from '../requirements-document'; +// import { Logger } from '@nestjs/common'; +// import { VirtualDirectory } from 'src/build-system/virtual-dir'; +// import { generateFilesDependencyWithLayers } from 'src/build-system/utils/file_generator_util'; +// import { BackendFileStructureAndArchitectureHandler } from '../../file-manager/backend-file-struct'; +// import path from 'path'; +// import { +// createFileWithRetries, +// readFileWithRetries, +// } from 'src/build-system/utils/files'; +// import { MessageInterface } from 'src/common/model-provider/types'; +// import normalizePath from 'normalize-path'; + +// interface FileInfos { +// [fileName: string]: { +// dependsOn: string[]; +// }; +// } + +// /** +// * BackendCodeHandler is responsible for generating the backend codebase +// * based on the provided sitemap and data mapping documents. +// */ + +// @BuildNode() +// @BuildNodeRequire([ +// UXSMDHandler, +// UXDMDHandler, +// DBSchemaHandler, +// BackendRequirementHandler, +// BackendFileStructureAndArchitectureHandler, +// ]) +// export class BackendCodeHandler implements BuildHandler { +// readonly logger: Logger = new Logger('FrontendCodeHandler'); +// private virtualDir: VirtualDirectory; + +// async run(context: BuilderContext): Promise> { +// const projectName = +// context.getGlobalContext('projectName') || 'Default Project Name'; +// const databaseType = +// context.getGlobalContext('databaseType') || 'Default database type'; +// // Retrieve required documents +// const sitemapDoc = context.getNodeData(UXSMDHandler); +// const datamapDoc = context.getNodeData(UXDMDHandler); +// const databaseSchemas = context.getNodeData(DBSchemaHandler); +// const backendRequirementDoc = +// context.getNodeData(BackendRequirementHandler)?.overview || ''; + +// const fileArchDoc = context.getNodeData( +// BackendFileStructureAndArchitectureHandler, +// ); +// this.logger.log('fileArchDoc', fileArchDoc); + +// this.virtualDir = context.virtualDirectory; +// const backendPath = context.getGlobalContext('backendPath'); + +// // Validate required data +// if (!sitemapDoc || !datamapDoc || !databaseSchemas) { +// throw new MissingConfigurationError( +// `Missing required configuration: sitemapDoc, datamapDoc, or databaseSchemas: siteMapDoc: ${!!sitemapDoc}, datamapDoc: ${!!datamapDoc}, databaseSchemas: ${!!databaseSchemas}`, +// ); +// } + +// if (!databaseSchemas) { +// throw new InvalidParameterError( +// 'databaseSchemas should be a valid object.', +// ); +// } + +// const dependencyFile = 'dependencies.json'; + +// const { concurrencyLayers, fileInfos } = +// await generateFilesDependencyWithLayers(fileArchDoc, this.virtualDir); + +// // const validator = new FrontendCodeValidator(frontendPath); +// const generatedCode = ''; + +// for (const [layerIndex, layer] of concurrencyLayers.entries()) { +// this.logger.log( +// `\n==== Concurrency Layer #${layerIndex + 1} ====\nFiles: [${layer.join( +// ', ', +// )}]\n`, +// ); + +// // const queue = new CodeTaskQueue(); + +// const maxRetries = 3; // Maximum retry attempts per file +// const delayMs = 200; // Delay between retries for a file +// const remainingFiles = [...layer]; // Start with all files in the layer + +// for ( +// let attempt = 1; +// attempt <= maxRetries && remainingFiles.length > 0; +// attempt++ +// ) { +// const failedFiles: any[] = []; + +// await Promise.all( +// remainingFiles.map(async (file) => { +// this.logger.log( +// `Layer #${layerIndex + 1}, generating code for file: ${file}`, +// ); + +// const currentFullFilePath = path.resolve(backendPath, file); + +// // Generate the prompt using the provided documents and project name +// const backendCodePrompt = generateBackendCodePrompt( +// projectName, +// databaseType, +// currentFullFilePath, +// 'javascript', // TODO: make sure this lang come from the context +// dependencyFile, +// ); + +// // Ensure fileInfos[file] exists before modifying +// if (!fileInfos[file]) { +// fileInfos[file] = { +// filePath: file, // Assuming `file` is the correct path +// dependsOn: [], +// }; +// } + +// const directDepsPathString = fileInfos[file].dependsOn.join('\n'); + +// const dependenciesText = await this.gatherDependenciesForFile( +// file, +// fileInfos, +// backendPath, +// ); + +// const messages = [ +// { +// role: 'system' as const, +// content: backendCodePrompt, +// }, +// { +// role: 'user' as const, +// content: `## Database Schema: +// ${databaseSchemas} +// `, +// }, +// { +// role: 'user' as const, +// content: `## Backend Requirement: +// ${backendRequirementDoc} +// `, +// }, +// { +// role: 'assistant', +// content: +// "Good, now provider your dependencies, it's okay dependencies are empty, which means you don't have any dependencies", +// }, +// { +// role: 'user' as const, +// content: ` + +// ## Overview of The Internal Dependencies filess you may need +// ${directDepsPathString} + +// ## Detail about each Internal Dependencies: +// ${dependenciesText}\n +// `, +// }, +// { +// role: 'user', +// content: `Now you can provide the code, don't forget the tags. Do not be lazy.`, +// }, +// // { +// // role: 'assistant', +// // content: codeReviewPrompt, +// // }, +// ] as MessageInterface[]; + +// let generatedCode: string; +// try { +// const modelResponse = await chatSyncWithClocker( +// context, +// { +// model: 'gpt-4o-mini', +// messages: messages, +// }, +// 'generateBackendCode', +// BackendCodeHandler.name, +// ); + +// generatedCode = formatResponse(modelResponse); + +// if (!generatedCode) { +// throw new ResponseParsingError( +// 'Response tag extraction failed.', +// ); +// } +// } catch (error) { +// if (error instanceof ResponseParsingError) { +// throw error; +// } +// throw new ResponseParsingError( +// 'Error occurred while parsing the model response.', +// ); +// } + +// try { +// await createFileWithRetries(currentFullFilePath, generatedCode); +// } catch (error) { +// throw new FileWriteError( +// `Failed to save backend code to ${backendPath}: ${error.message}`, +// ); +// } +// }), +// ); +// } + +// // Now process the entire queue for this layer: +// // This writes each file, runs build, fixes if needed, etc. +// // const queueProcessor = new FrontendQueueProcessor( +// // validator, +// // queue, +// // context, +// // frontendPath, +// // renameMap, +// // ); +// // await queueProcessor.processAllTasks(); +// // this.logger.log( +// // `\n==== Finished concurrency layer #${layerIndex + 1} ====\n`, +// // ); +// } + +// return { +// success: true, +// data: generatedCode, +// }; +// } + +// // get the dependencies content and path +// private async gatherDependenciesForFile( +// file: string, +// fileInfos: FileInfos, +// frontendPath: string, +// ): Promise { +// const directDepsArray = fileInfos[file]?.dependsOn ?? []; +// let dependenciesText = ''; + +// for (const dep of directDepsArray) { +// try { +// const resolvedDepPath = normalizePath(path.resolve(frontendPath, dep)); +// const depContent = await readFileWithRetries(resolvedDepPath, 3, 200); +// dependenciesText += `\n\n File path: ${dep}\n\`\`\`typescript\n${depContent}\n\`\`\`\n`; +// } catch (err) { +// this.logger.warn( +// `Failed to read dependency "${dep}" for file "${file}"`, +// err, +// ); +// } +// } + +// return dependenciesText; +// } +// } diff --git a/backend/src/build-system/handlers/backend/code-generate/prompt.ts b/backend/src/build-system/handlers/backend/code-generate/prompt.ts index 1db5083d..533676e3 100644 --- a/backend/src/build-system/handlers/backend/code-generate/prompt.ts +++ b/backend/src/build-system/handlers/backend/code-generate/prompt.ts @@ -1,17 +1,14 @@ export const generateBackendCodePrompt = ( projectName: string, - sitemapDoc: string, - datamapDoc: string, - backendRequirementDoc: string, databaseType: string, - databaseSchemas: string, currentFile: string, - fileType: string = 'javascript', + fileType: string = 'Javascript', dependencyFile: string, ): string => { const defaultDependencies = { - sqlite3: '^5.1.6', - express: '^4.18.2', + sqlite3: '^5', + express: '^4', + jsonwebtoken: '^9', }; // Parse dependency file if provided, otherwise use defaults @@ -25,24 +22,16 @@ export const generateBackendCodePrompt = ( dependencies = defaultDependencies; } - return `You are an expert backend developer. - Your task is to generate a complete backend codebase within a single file for a project named "${projectName}". The code should be written using the Express framework with ES Module syntax (using \`import\` statements), and the database is ${databaseType}. The code must be written in \`${fileType}\`. The backend code should be scalable, maintainable, and adhere to best practices. - + return `Role: You are an expert backend developer. + Task: Your task is to generate a complete backend codebase within a single file for a project named "${projectName}". The code should be written using the Express framework with ES Module syntax (using \`import\` statements), and the database is ${databaseType}. The code must be written in \`${fileType}\`. The backend code should be scalable, maintainable, and adhere to best practices. + Current File: ${currentFile}. + ### Project Dependencies The project uses the following dependencies: \`\`\`json ${JSON.stringify(dependencies, null, 2)} \`\`\` - ### Based on the following input: - - - **Project Name:** ${projectName} - - **Sitemap Documentation:** ${sitemapDoc} - - **Data Analysis Document:** ${datamapDoc} - - **Backend Requirements:** ${backendRequirementDoc} - - **Database schemas:** These schemas are defined in \`./schema.sql\`. The code must read and execute this file during database initialization. - - **Current Implementation:** ${currentFile || 'No existing implementation'} - ### Backend Requirements Analysis: Based on the provided backend requirements document, ensure implementation of: - All specified API endpoints and their functionality @@ -59,9 +48,10 @@ export const generateBackendCodePrompt = ( **Include:** 1. **Server Setup:** - Initialize the server using the Express framework with ES Module syntax (use \`import\` instead of \`require\`). - - Configure middleware for JSON parsing and CORS. + - Configure middleware for JSON parsing and CORS example "app.use(cors()); " 2. **Database Connection and Initialization:** + Database schemas: These schemas are defined in \`./schema.sql\`. The code must read and execute this file during database initialization. For SQLite database initialization, you must include code to execute the ./schema.sql file. There are several approaches: 1. Using better-sqlite3: @@ -103,29 +93,29 @@ export const generateBackendCodePrompt = ( - Implement connection pooling if needed 3. **Implementation Guidelines for SQLite:** - 1. **Basic Database Operations:** - \`\`\`${fileType} - // Using sqlite3 - import sqlite3 from 'sqlite3'; - const db = new sqlite3.Database('./database.sqlite'); - - // Basic query example - db.all("SELECT * FROM users", [], (err, rows) => { - if (err) throw err; - console.log(rows); - }); - \`\`\` - - 2. **Performance-Critical Operations:** - \`\`\`${fileType} - // Using better-sqlite3 - import Database from 'better-sqlite3'; - const db = new Database('database.sqlite', { verbose: console.log }); - - // Prepared statement example - const stmt = db.prepare('SELECT * FROM users WHERE id = ?'); - const user = stmt.get(userId); - \`\`\` + 1. **Basic Database Operations:** + \`\`\`${fileType} + // Using sqlite3 + import sqlite3 from 'sqlite3'; + const db = new sqlite3.Database('./database.sqlite'); + + // Basic query example + db.all("SELECT * FROM users", [], (err, rows) => { + if (err) throw err; + console.log(rows); + }); + \`\`\` + + 2. **Performance-Critical Operations:** + \`\`\`${fileType} + // Using better-sqlite3 + import Database from 'better-sqlite3'; + const db = new Database('database.sqlite', { verbose: console.log }); + + // Prepared statement example + const stmt = db.prepare('SELECT * FROM users WHERE id = ?'); + const user = stmt.get(userId); + \`\`\` 4. **Route Definitions:** - Define RESTful API endpoints based on the sitemap documentation. @@ -148,7 +138,7 @@ export const generateBackendCodePrompt = ( 7. **Environment Configuration:** - Use dotenv or similar for environment variables. - Database configuration should be environment-based. - - Server port and other settings should be configurable. + - Server port is 3000 and other settings should be configurable. 8. **Comments and Documentation:** - Add comments explaining each section and key code blocks. @@ -163,10 +153,7 @@ export const generateBackendCodePrompt = ( - Hardcoded configuration values. **Special Requirements:** - - Use environment variables for database path and server settings. - - Implement proper statement preparation and parameter binding. - Ensure all database operations are wrapped in appropriate error handling. - - Use proper TypeScript types and interfaces. - Implement proper logging throughout the application. ### Ask Yourself: @@ -176,8 +163,73 @@ export const generateBackendCodePrompt = ( 4. Are transactions used appropriately for data consistency? 5. Is the schema.sql file properly loaded and executed? 6. Are all configurations properly externalized? - 7. Is the code properly typed with TypeScript? - 8. Is there adequate logging and error tracking? + 7. Is there adequate logging and error tracking? + + ### Output Format: + + Provide the backend code within \`\` tags as follows: + + + // Your generated backend code goes here + + `; +}; + +export const generateForMultiFileBackendCodePrompt = ( + projectName: string, + databaseType: string, + currentFile: string, + fileType: string = 'javascript', + dependencyFile: string, +): string => { + const defaultDependencies = { + sqlite3: '^5', + express: '^4', + }; + + // Parse dependency file if provided, otherwise use defaults + // TODO: get dependencies info from embedding model + let dependencies; + try { + dependencies = dependencyFile + ? JSON.parse(dependencyFile) + : defaultDependencies; + } catch (error) { + dependencies = defaultDependencies; + } + + return `Role: You are an expert backend developer. + Task: Your task is to generate a complete backend codebase using Express framework, database ${databaseType}, and language Javascript. The backend code should be scalable, maintainable, and adhere to best practices. + Current File: ${currentFile}. + + ## Project External Dependencies + The project uses the following dependencies: + \`\`\`json + ${JSON.stringify(dependencies, null, 2)} + \`\`\` + + + + ### Instructions and Rules: + 1. Implement Only One file: Implement only the file specified in "Current File" - do not generate code for multiple files. + 2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code with no TODOs or placeholders. + 3. ES Module Syntax: Use ES Module syntax (import/export) consistently throughout the code. + 4. File Structure and Dependencies: The current file might depend on other files in the project use the Project Internal Dependencies to help you. + 5. CAREFULLY CHECK: + - Before importing a file, verify that the file should logically exist + - Ensure that you haven't missed any internal dependencies import + 6. Error Handling: Implement comprehensive error handling for database operations, API calls, and all async operations. + 7. Database Specific: For ${databaseType}, ensure you're using appropriate connection methods and query formats. + 8. Configuration: Use environment variables for sensitive values and configuration (use process.env) + 9. RESTful Standards: When implementing controllers and routes, follow RESTful API standards. + 10. Documentation: Include JSDoc comments for functions and important code sections. + 11. Logging: Implement appropriate logging for errors and significant operations. + 12. Schema Init: For database files, ensure proper initialization of tables and schemas if needed. + + ### Ask Yourself: + 1. Are all configurations properly externalized? + 2. Is the code properly typed with TypeScript? + 3. Is there adequate logging and error tracking? ### Output Format: diff --git a/backend/src/build-system/handlers/backend/file-review/file-review.ts b/backend/src/build-system/handlers/backend/file-review/file-review.ts index b01ed099..10fc2f84 100644 --- a/backend/src/build-system/handlers/backend/file-review/file-review.ts +++ b/backend/src/build-system/handlers/backend/file-review/file-review.ts @@ -44,9 +44,7 @@ export class BackendFileReviewHandler implements BuildHandler { project description: ${description}, `; - const backendRequirement = context.getNodeData( - BackendRequirementHandler, - )?.overview; + const backendRequirement = context.getNodeData(BackendRequirementHandler); const backendCode = [context.getNodeData(BackendCodeHandler)]; if (!backendRequirement) { @@ -119,7 +117,7 @@ export class BackendFileReviewHandler implements BuildHandler { response = await chatSyncWithClocker( context, { - model: 'gpt-4o-mini', + model: 'o3-mini-high', messages: [{ content: modificationPrompt, role: 'system' }], }, 'generateBackendFile', diff --git a/backend/src/build-system/handlers/backend/requirements-document/index.ts b/backend/src/build-system/handlers/backend/requirements-document/index.ts index 50a077e8..5ca356bf 100644 --- a/backend/src/build-system/handlers/backend/requirements-document/index.ts +++ b/backend/src/build-system/handlers/backend/requirements-document/index.ts @@ -11,7 +11,8 @@ import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; import { DBRequirementHandler } from '../../database/requirements-document'; import { UXDMDHandler } from '../../ux/datamap'; -import { UXSMDHandler } from '../../ux/sitemap-document'; +import { DBSchemaHandler } from '../../database/schemas/schemas'; +import { MessageInterface } from 'src/common/model-provider/types'; type BackendRequirementResult = { overview: string; @@ -29,15 +30,11 @@ type BackendRequirementResult = { */ @BuildNode() -@BuildNodeRequire([DBRequirementHandler, UXDMDHandler, UXSMDHandler]) -export class BackendRequirementHandler - implements BuildHandler -{ +@BuildNodeRequire([DBRequirementHandler, UXDMDHandler, DBSchemaHandler]) +export class BackendRequirementHandler implements BuildHandler { private readonly logger: Logger = new Logger('BackendRequirementHandler'); - async run( - context: BuilderContext, - ): Promise> { + async run(context: BuilderContext): Promise> { this.logger.log('Generating Backend Requirements Document...'); const language = context.getGlobalContext('language') || 'javascript'; @@ -48,27 +45,55 @@ export class BackendRequirementHandler const dbRequirements = context.getNodeData(DBRequirementHandler); const datamapDoc = context.getNodeData(UXDMDHandler); - const sitemapDoc = context.getNodeData(UXSMDHandler); + const dbSchema = context.getNodeData(DBSchemaHandler); - if (!dbRequirements || !datamapDoc || !sitemapDoc) { + if (!dbRequirements || !datamapDoc || !dbSchema) { this.logger.error( - 'Missing required parameters: dbRequirements, datamapDoc, or sitemapDoc', + 'Missing required parameters: dbRequirements, datamapDoc, or dbSchema', ); throw new MissingConfigurationError( - 'Missing required parameters: dbRequirements, datamapDoc, or sitemapDoc.', + 'Missing required parameters: dbRequirements, datamapDoc, or dbSchema.', ); } const overviewPrompt = generateBackendOverviewPrompt( projectName, dbRequirements, + dbSchema, datamapDoc, - sitemapDoc, language, framework, packages, ); + const messages = [ + { + role: 'system' as const, + content: overviewPrompt, + }, + { + role: 'user' as const, + content: `## Database Requirements: + ${dbRequirements} + `, + }, + { + role: 'user' as const, + content: `## DataBase Schema: + ${dbSchema} + `, + }, + { + role: 'user' as const, + content: `## Frontend Data Requirements: + ${datamapDoc} `, + }, + { + role: 'user', + content: `Now you can provide the code, don't forget the tags. Do not be lazy.`, + }, + ] as MessageInterface[]; + let backendOverview: string; try { @@ -76,7 +101,7 @@ export class BackendRequirementHandler context, { model: 'gpt-4o-mini', - messages: [{ content: overviewPrompt, role: 'system' }], + messages: messages, }, 'generateBackendOverviewPrompt', BackendRequirementHandler.name, @@ -88,15 +113,7 @@ export class BackendRequirementHandler // Return generated data return { success: true, - data: { - overview: removeCodeBlockFences(backendOverview), - implementation: '', // Implementation generation skipped - config: { - language, - framework, - packages, - }, - }, + data: removeCodeBlockFences(backendOverview), }; } } diff --git a/backend/src/build-system/handlers/backend/requirements-document/prompt.ts b/backend/src/build-system/handlers/backend/requirements-document/prompt.ts index 7d5dc05d..6ed4303f 100644 --- a/backend/src/build-system/handlers/backend/requirements-document/prompt.ts +++ b/backend/src/build-system/handlers/backend/requirements-document/prompt.ts @@ -1,36 +1,25 @@ export const generateBackendOverviewPrompt = ( projectName: string, dbRequirements: string, + dbSchema: string, datamapDoc: string, - sitemapDoc: string, language: string, framework: string, packages: Record, ): string => { - return `You are a Senior Backend Architect specializing in backend systems. Generate the System Overview and API Endpoints specifications based on the following inputs. + const defaultDependencies = { + sqlite3: '^5', + express: '^4', + }; + return `Role: You are a Senior Backend Architect specializing in backend systems. Generate the System Overview and API Endpoints specifications based on the following inputs. -### Inputs +Task: Generate a Backend Overview Document following these guidelines: Project Name: ${projectName} ### Technology Stack - Language: ${language} - Framework: ${framework} -- Key Packages: -${Object.entries(packages) - .map(([pkg, version]) => ` - ${pkg}@${version}`) - .join('\n')} - -### Requirements Documentation -1. Database Requirements: -${dbRequirements} - -2. Frontend Data Requirements: -${datamapDoc} - -3. Site Structure: -${sitemapDoc} - -Generate a Backend Overview Document following these guidelines: +- Key Packages: ${JSON.stringify(defaultDependencies)} ### Instructions and Rules: 1. Design a clear system architecture based on the technology stack and requirements @@ -42,68 +31,37 @@ Generate a Backend Overview Document following these guidelines: 4. Consider: - Data flow between frontend pages - Required data transformations - - Real-time update requirements - - Caching strategies - - Authentication and authorization needs +5. IMPORTANT: Carefully differentiate between public and authenticated endpoints: + - Public endpoints (No Auth) +6. For authenticated endpoints only, include authentication in the headers section using "Authorization": "Bearer {token}" +7. Don't add authentication requirements to public-facing read operations (GET requests for viewing content) +8. Do not add login when no documentation mentioned. +9. It MUST be COMPLETE DO NOTE write TODO, and Future for api. -Your reply must start with: "\`\`\`BackendOverview" and end with "\`\`\`". +Your reply must start with: "" and end with "". Include these sections: - -#### 1. System Overview -- **Project Name**: ${projectName} -- **Technology Stack** - - Core technology choices - - Framework architecture - - Key dependencies and their purposes -- **Architecture Patterns** - - Framework-specific patterns - - Project structure - - Dependency management - - Configuration management - - Service organization -- **Data Flow Architecture** - - Frontend-Backend data interactions - - Caching strategy - - Real-time updates handling - - Data transformation layers - -#### 2. API Endpoints +## API Documentation Group endpoints by functional areas based on site structure. For each endpoint: \`\`\` -Route: /api/resource -Method: GET|POST|PUT|DELETE +Route: GET|POST|PUT|DELETE /api/resource Purpose: Functional description -Frontend Usage: Which pages/components use this endpoint Data Requirements: - Required data transformations - - Caching requirements - - Real-time update needs +Required Auth: No/Yes Request: - Headers: { - "Authorization": "Bearer {token}" - // Other headers - } - Params: { - // URL parameters - } - Query: { - // Query parameters - } - Body: { - // Request body schema - } +{ + "headers": {}, + "params": {}, + "query": {}, + "body": {} +} Response: - Success: { - // Success response schema - } - Errors: { - // Error response schemas - } -Required Auth: Yes/No -Rate Limiting: Specifications if needed -Cache Strategy: Caching rules if applicable +{ + "success": {}, + "errors": {} +} \`\`\``; }; diff --git a/backend/src/build-system/handlers/database/requirements-document/prompt.ts b/backend/src/build-system/handlers/database/requirements-document/prompt.ts index 4033bbfe..d492989a 100644 --- a/backend/src/build-system/handlers/database/requirements-document/prompt.ts +++ b/backend/src/build-system/handlers/database/requirements-document/prompt.ts @@ -10,11 +10,17 @@ export const prompts = { Follow these guidelines to generate the database requirements: ### Instructions and Rules: -1. Analyze all data elements mentioned in the UX Datamap -2. Identify entities and their relationships -3. Determine data types and constraints -4. Consider data persistence requirements -5. Plan for scalability and performance +1. IMPORTANT: Only include features and entities that are EXPLICITLY mentioned in the UX Datamap. +2. Analyze data elements mentioned in the UX Datamap. +3. DO NOT include any conditional or optional features (phrases containing "if", "optional", "may", "possible", or similar qualifiers). +4. Do not add User, login, authentication unless specifically mentioned in the UX Datamap. +5. Carefully distinguish between frontend state management and actual database storage needs +6. Only include entities and attributes that require persistent storage +7. For each feature in the UX Datamap, clearly determine if it needs database support or is purely frontend +8. Identify entities and their relationships +9. Determine data types and constraints +10. Consider data persistence requirements +11. Plan for scalability and performance ### Database Requirements Structure: --- @@ -53,10 +59,10 @@ For each entity: - Performance considerations #### 6. Security Requirements -- Access control -- Data privacy considerations -- Audit requirements -- Encryption needs +- Only include access control if user authentication is EXPLICITLY REQUIRED +- Only include data privacy considerations for sensitive data that is actually being stored +- Only include audit requirements if explicitly mentioned +- Only include encryption needs if sensitive data is being stored #### 7. Performance Requirements - Expected data volume @@ -90,8 +96,8 @@ Focus on creating practical, implementable database requirements that will effec - Partitioning needs 4. Security & Compliance: - - Access control - - Data encryption + - Only include access control if authentication is explicitly required + - Data encryption only if sensitive data is being stored - Audit requirements 5. Maintenance & Operations: diff --git a/backend/src/build-system/handlers/database/schemas/prompt.ts b/backend/src/build-system/handlers/database/schemas/prompt.ts index 524b5006..b2e46ea3 100644 --- a/backend/src/build-system/handlers/database/schemas/prompt.ts +++ b/backend/src/build-system/handlers/database/schemas/prompt.ts @@ -86,7 +86,7 @@ Here is dbAnalysis content: ${dbAnalysis} -Rules for generation: +Rules for schema generation: 1. Use ${databaseType}-specific data types and features. 2. Ensure all schema operations are idempotent. For example: - Use "CREATE TABLE IF NOT EXISTS" for table creation. @@ -96,6 +96,15 @@ Rules for generation: 4. Use standardized naming conventions. 5. Generate schema in the correct creation order for dependencies. +Rules for mock data generation: +1. After creating each table, add INSERT statements with 5-10 rows of realistic sample data. +2. Mock data should relate to the purpose of the appliaction. +3. Ensure referential integrity in the mock data (foreign keys reference valid primary keys). +4. Use realistic values appropriate for each column type and purpose. +5. For timestamp fields, use recent dates. +6. Include a variety of data scenarios to demonstrate different use cases. +7. Image Assets: If mock requires any images, you can use placeholder image URLs from https://picsum.photos//. Note that the width and height values (e.g., 500/300) are adjustable as needed. + Example output: CREATE TABLE IF NOT EXISTS users ( @@ -111,6 +120,12 @@ CREATE TABLE IF NOT EXISTS users ( CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); +-- Mock data for users +INSERT INTO users (email, username, password_hash, subscription_type) VALUES +('user1@example.com', 'user1', 'hash1', 'premium'), +('user2@example.com', 'user2', 'hash2', 'free'), +('user3@example.com', 'user3', 'hash3', 'premium'), + CREATE TABLE IF NOT EXISTS playlists ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, diff --git a/backend/src/build-system/handlers/database/schemas/schemas.ts b/backend/src/build-system/handlers/database/schemas/schemas.ts index fda7b701..3c93e8a2 100644 --- a/backend/src/build-system/handlers/database/schemas/schemas.ts +++ b/backend/src/build-system/handlers/database/schemas/schemas.ts @@ -8,13 +8,14 @@ import { isSupportedDatabaseType, } from '../../../utils/database-utils'; import { prompts } from './prompt'; -import { saveGeneratedCode } from 'src/build-system/utils/files'; -import * as path from 'path'; import { formatResponse } from 'src/build-system/utils/strings'; import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; import { FileWriteError, ModelUnavailableError } from 'src/build-system/errors'; import { DBRequirementHandler } from '../requirements-document'; import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; +import { CodeValidator } from 'src/build-system/handlers/frontend-code-generate/CodeValidator'; +import { saveGeneratedCode } from 'src/build-system/utils/files'; +import * as path from 'path'; @BuildNode() @BuildNodeRequire([DBRequirementHandler]) @@ -30,6 +31,7 @@ export class DBSchemaHandler implements BuildHandler { context.getGlobalContext('databaseType') || 'PostgreSQL'; const dbRequirements = context.getNodeData(DBRequirementHandler); const uuid = context.getGlobalContext('projectUUID'); + const backendPath = context.getGlobalContext('backendPath'); // 2. Validate database type if (!isSupportedDatabaseType(databaseType)) { @@ -82,7 +84,7 @@ export class DBSchemaHandler implements BuildHandler { databaseType, fileExtension, ); - let schemaContent: string; + let schemaContent = ''; try { const schemaResponse = await chatSyncWithClocker( context, @@ -101,49 +103,67 @@ export class DBSchemaHandler implements BuildHandler { } // Step 3: Validate generated schema - this.logger.debug('Validating generated schema...'); - const validationPrompt = prompts.validateDatabaseSchema( - schemaContent, - databaseType, - ); - try { - const validationResponse = await chatSyncWithClocker( - context, - { - model: 'gpt-4o-mini', - messages: [ - { content: validationPrompt, role: 'system' }, - { - role: 'user', - content: - 'help me fix my schema code if there is any failed validation, generate full validated version schemas for me, with xml tag', - }, - ], - }, - 'validateDatabaseSchema', - DBSchemaHandler.name, - ); - schemaContent = formatResponse(validationResponse); - } catch (error) { - throw new ModelUnavailableError( - `Model unavailable during validation: ${error}`, + const maxFixAttempts = 2; + const schemaValidator = new CodeValidator(backendPath, 'sqlite3'); + for (let attempt = 1; attempt <= maxFixAttempts; attempt++) { + this.logger.debug('Validating generated schema...'); + + // Write schema to file + const schemaFileName = `schema.${fileExtension}`; + + try { + await saveGeneratedCode( + path.join(uuid, 'backend', schemaFileName), + schemaContent, + ); + this.logger.log( + `Schema file (${schemaFileName}) written successfully.`, + ); + } catch (error) { + throw new FileWriteError( + `Failed to write schema file: ${error.message}`, + ); + } + + const validationResult = await schemaValidator.validate(); + + if (validationResult.success) { + this.logger.log( + `Sqlite3 Schema build succeeded on attempt #${attempt}.`, + ); + break; // done, move on + } + this.logger.warn( + `Build failed on attempt #${attempt} for file Sqlite3 Schema.`, ); - } - // Write schema to file - const schemaFileName = `schema.${fileExtension}`; - try { - saveGeneratedCode( - path.join(uuid, 'backend', schemaFileName), + const validationPrompt = prompts.validateDatabaseSchema( schemaContent, + databaseType, ); - this.logger.log( - `Schema file (${schemaFileName}) written successfully.`, - ); - } catch (error) { - throw new FileWriteError( - `Failed to write schema file: ${error.message}`, - ); + try { + const validationResponse = await chatSyncWithClocker( + context, + { + model: 'o3-mini-high', + messages: [ + { content: validationPrompt, role: 'system' }, + { + role: 'user', + content: `This is the error ${validationResult.error} + Help me fix my schema code if there is any failed validation, generate full validated version schemas for me, with xml tag`, + }, + ], + }, + 'validateDatabaseSchema', + DBSchemaHandler.name, + ); + schemaContent = formatResponse(validationResponse); + } catch (error) { + throw new ModelUnavailableError( + `Model unavailable during validation: ${error}`, + ); + } } return { diff --git a/backend/src/build-system/handlers/file-manager/backend-file-struct/index.ts b/backend/src/build-system/handlers/file-manager/backend-file-struct/index.ts new file mode 100644 index 00000000..14c40b50 --- /dev/null +++ b/backend/src/build-system/handlers/file-manager/backend-file-struct/index.ts @@ -0,0 +1,532 @@ +import { BuildHandler, BuildOpts, BuildResult } from 'src/build-system/types'; +import { BuilderContext } from 'src/build-system/context'; +import { Logger } from '@nestjs/common'; +import { + parseGenerateTag, + removeCodeBlockFences, + extractJsonFromText, + formatResponse, +} from 'src/build-system/utils/strings'; +import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; +import { + ResponseParsingError, + MissingConfigurationError, + InvalidParameterError, + ModelUnavailableError, +} from 'src/build-system/errors'; +import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; +import { VirtualDirectory } from 'src/build-system/virtual-dir'; +import { + buildDependencyGraph, + validateAgainstVirtualDirectory, +} from 'src/build-system/utils/file_generator_util'; +import { BackendRequirementHandler } from '../../backend/requirements-document'; +import { DBSchemaHandler } from '../../database/schemas/schemas'; + +export const prompts = { + convertTreeToJsonPrompt: (): string => { + return `You are a highly skilled developer. Your task is to convert the previous file and folder structure, currently represented in an ASCII tree format, into a JSON structure. The JSON structure must: + + - Represent all file paths in a flat list under the "Paths" array. + - Each file path must be a relative path that begins exactly with "src/" (do not include any leading "/" or absolute paths). + - Directories should not be included—only file paths. + + Output Format: + Return a JSON object in the following format: + Surround the JSON object with tags. + + + { + "Paths": [ + "src/full/path/to/file1.ext", + "src/full/path/to/file2.ext", + "src/another/path/to/file3.ext" + ] + } + + + Additional Rules: + + - Maintain the original directory structure but only return files in the JSON output. + - Keep file names and paths exactly as they appear in the ASCII tree. + - **Important**: Ensure that all file paths are relative and begin exactly with "src/". Do not output any paths that start with a leading "/". + - Do not include comments or extra fields besides "Paths". + - Return only the JSON structure (no explanations, no additional comments). This JSON will be used directly in the application. + `; + }, + + generateCommonFileStructurePrompt: ( + projectName: string, + DBSchema: string, + BackendRequirementDoc: string, + framework: string, + projectPart: string, + projectSize: string, + ): string => { + let roleDescription = ''; + let includeSections = ''; + let excludeSections = ''; + let fileNamingGuidelines = ''; + let projectSizeNote = ''; + + // Set project size note + switch (projectSize.toLowerCase()) { + case 'small': + projectSizeNote = `* Note: For a small project, generate a minimal backend structure that only includes the essential files and folders.`; + break; + case 'medium': + projectSizeNote = `* Note: For a medium project, generate a backend structure that covers all necessary endpoints and models with moderate detail.`; + break; + case 'large': + projectSizeNote = `* Note: For a large project, generate a comprehensive backend structure including all routes, controllers, models, and utilities.`; + break; + default: + projectSizeNote = `* Note: The project size is unspecified. Please use a balanced approach.`; + } + + // Backend-specific configuration + roleDescription = 'an expert backend developer'; + + // Default backend structure for all project sizes + includeSections = ` + Folder Structure: + src/ + controllers/ - Handle incoming requests and return responses + models/ - Define data schemas and interact with the database + route.ts - Define API endpoints and route requests to controllers + `; + + excludeSections = ` + Do Not Include: + - Frontend-specific folders (e.g., components, pages, contexts) + - Asset folders (e.g., images, icons, fonts) + - Test folders or files (tests will be generated separately) + `; + + fileNamingGuidelines = ` + File Naming Guidelines: + - Use meaningful and descriptive file names + - Controllers should be named after their resource (e.g., userController.ts) + - Models should represent data entities (e.g., User.ts) + - Use consistent naming conventions (camelCase) throughout the project + - Match model names to the database schema entities + `; + + return `You are ${roleDescription}. Your task is to generate a complete folder and file structure for the backend of a project named "${projectName}". Include all necessary files and folders to cover the essential aspects while ensuring scalability and maintainability. + + Based on the following input: + + - Project name: ${projectName} + - Database Schema (provided below) + - Backend Requirements Doc (provided below) + - Framework: ${framework} + + ${projectSizeNote} + + ### Instructions and Rules: + + Include: + ${includeSections} + + ${fileNamingGuidelines} + + ${excludeSections} + + File Comments: + Include comments describing the purpose of each file or folder to improve readability. + + Consider the following when generating the structure: + 1. Analyze the backend requirements to identify all required API endpoints + 2. Use the database schema to identify all required models + 3. For each endpoint in the requirements, ensure there's a corresponding controller method + 4. Create appropriate model files for each entity in the database schema + 5. Ensure proper separation of concerns with controllers handling request/response and business logic in the appropriate location + + This final result must be 100% complete and ready for direct use in production. + + Output Format: + + Start with: "\`\`\`FolderStructure" + Tree format: + Include folder names with placeholder files inside. + Add comments to describe the purpose of each file/folder. + End with: "\`\`\`" + `; + }, + + generateFileArchPrompt: (): string => { + return `Your task is to analyze the given project directory structure and create a detailed JSON object mapping file dependencies. The output JSON must be precisely formatted and wrapped in tags. + +### Instructions + +1. **Analyze the directory structure** to identify all files and their relationships in this Express backend application. + - Identify direct dependencies for each file by considering typical imports based on roles, naming conventions, and the provided analysis. + - Understand the MVC pattern used in Express.js applications (Models, Controllers, Routes) + - Do not assume any additional files or paths. The structure must be based exclusively on the given list. + +2. **Generate File Dependency JSON**: + - Each file must be represented using its full path starting from src/. + - Ensure dependencies are strictly limited to files in the "Paths" array. + - Use absolute file paths from "Paths" for all "dependsOn" values. + Do not use relative paths (./, ../). + Every dependency must match exactly one of the files in "Paths". + - Any file without dependencies should have "dependsOn": []. + - For each file, list its direct dependencies as an array of relative paths in the \`dependsOn\` field. + - Organize the output in a \`files\` object where keys are file paths, and values are their dependency objects. + +3. **Output Requirements**: + - The JSON object must strictly follow this structure: + \`\`\`json + + { + "files": { + "src/path/to/file1": { + "dependsOn": ["src/path/to/dependency1", "src/path/to/dependency2"] + }, + "src/path/to/file2": { + "dependsOn": [] + } + } + } + + \`\`\` + - Keys: Every file must be represented with its full path, starting from src/. + - Dependency Rules: + All dependencies must exist in the "Paths" array. + No inferred or assumed files should be added. + - Wrap the JSON output with \`\` tags. +### Notes +- The \`dependsOn\` field should reflect logical dependencies inferred from both the directory structure and the page-by-page analysis. +- Include all files in the output, even if they have no dependencies. +- For database models, consider entity relationships when determining dependencies. +- The route file should depend on controllers, not directly on models. +- Controllers should depend on the models they interact with. + +### Output +Return only the JSON object wrapped in \`\` tags. +`; + }, +}; + +@BuildNode() +@BuildNodeRequire([DBSchemaHandler, BackendRequirementHandler]) +export class BackendFileStructureAndArchitectureHandler + implements BuildHandler +{ + readonly id = 'op:FILE:STRUCT_AND_ARCH'; + private readonly logger: Logger = new Logger( + 'FileStructureAndArchitectureHandler', + ); + private virtualDir: VirtualDirectory; + + async run( + context: BuilderContext, + opts?: BuildOpts, + ): Promise> { + this.logger.log('Generating File Structure Document...'); + + const projectName = + context.getGlobalContext('projectName') || 'Default Project Name'; + const backendRequirementDoc = context.getNodeData( + BackendRequirementHandler, + ); + const dbSchema = context.getNodeData(DBSchemaHandler); + const projectPart = opts?.projectPart ?? 'backend'; + const framework = context.getGlobalContext('framework') ?? 'Express'; + const projectSize = context.getGlobalContext('projectSize') || 'small'; + + try { + this.validateInputs( + backendRequirementDoc.overview, + dbSchema, + framework, + projectPart, + ); + } catch (error) { + return { + success: false, + error, + }; + } + + const fileStructPrompt = prompts.generateCommonFileStructurePrompt( + projectName, + dbSchema, + backendRequirementDoc.overview, + framework, + projectPart, + projectSize, + ); + const convertToJsonPrompt = prompts.convertTreeToJsonPrompt(); + + const fileStructMessages = [ + { + role: 'system' as const, + content: fileStructPrompt, + }, + { + role: 'user' as const, + content: ` + **Backend Requirement Documentation** + ${backendRequirementDoc} + `, + }, + { + role: 'user' as const, + content: ` + **DataBase Schema** + ${dbSchema} + + Now please generate tree folder structure. + `, + }, + { + role: 'system' as const, + content: convertToJsonPrompt, + }, + { + role: 'user' as const, + content: `**Final Check:** + Before returning the output, ensure the following: + - The JSON structure is correctly formatted and wrapped in tags. + - File extensions and paths match those in the Directory Structure. + - All files and dependencies are included, with relative paths used wherever possible.`, + }, + ]; + + let fileStructureContent: string; + try { + fileStructureContent = await chatSyncWithClocker( + context, + { + model: context.defaultModel || 'gpt-4o-mini', + messages: fileStructMessages, + }, + 'generateCommonFileStructure', + this.id, + ); + this.logger.debug('fileStructureContent', fileStructureContent); + + if (!fileStructureContent || fileStructureContent.trim() === '') { + throw new ResponseParsingError( + `Generated content is empty during op:FILE:STRUCT_AND_ARCH.`, + ); + } + } catch (error) { + this.logger.error( + `Failed to generate file structure: ${error.message}`, + error.stack, + ); + return { + success: false, + error: new ResponseParsingError( + `File structure generation failed. ${error.message}`, + ), + }; + } + + let fileStructureJsonContent = ''; + try { + fileStructureJsonContent = parseGenerateTag(fileStructureContent); + } catch (error) { + return { + success: false, + error: new ResponseParsingError( + `Failed to parse file Structure Json Content. ${error.message}`, + ), + }; + } + + this.logger.log('Building virtual directory from file structure...'); + try { + const successBuild = context.buildVirtualDirectory( + fileStructureJsonContent, + ); + if (!successBuild) { + this.logger.error( + 'Failed to build virtual directory.' + fileStructureJsonContent, + ); + throw new ResponseParsingError('Failed to build virtual directory.'); + } + } catch (error) { + return { + success: false, + error: new ResponseParsingError( + `Failed to build virtual directory. ${error.message}`, + ), + }; + } + + context.virtualDirectory.getAllFiles().forEach((file) => { + this.logger.log(file); + }); + + this.logger.log('File Structure Document generated successfully.'); + + this.logger.log('Generating File Architecture Document...'); + + this.virtualDir = context.virtualDirectory; + const fileStructure = removeCodeBlockFences(fileStructureContent); + if (!fileStructure) { + return { + success: false, + error: new InvalidParameterError( + `Missing required parameters: fileStructure, current fileStructure: ${!!fileStructure}`, + ), + }; + } + + const fileArchPrompt = prompts.generateFileArchPrompt(); + + let invalidFiles = 'none'; + let fileArchContent: string; + + while (invalidFiles) { + const fileArchMessages = [ + { + role: 'system' as const, + content: fileArchPrompt, + }, + { + role: 'user' as const, + content: ` + **Page-by-Page Analysis** + The following is a detailed analysis of each page. Use this information to understand specific roles, interactions, and dependencies. + + ${backendRequirementDoc} + + Next, I will provide the **Directory Structure** to help you understand the full project architecture.`, + }, + { + role: 'user' as const, + content: ` + **Directory Structure**: + The following is the project's directory structure. Use this to identify files and folders. + + ${fileStructure} + + Based on this structure and the analysis provided earlier, please generate the File Architecture JSON object. Ensure the output adheres to all rules and guidelines specified in the system prompt. + `, + }, + { + role: 'user' as const, + content: `**Final Check** + Before returning the output, ensure the following: + - The JSON structure is correctly formatted and wrapped in tags. + - File extensions and paths match those in the Directory Structure. + - All files and dependencies are included. + `, + }, + { + role: 'user' as const, + content: + "here is the invalid file, trying to fix it, if it's none, then you can ignore it: " + + invalidFiles, + }, + ]; + + try { + fileArchContent = await chatSyncWithClocker( + context, + { + model: context.defaultModel || 'gpt-4o-mini', + messages: fileArchMessages, + }, + 'generateFileArch', + this.id, + ); + } catch (error) { + this.logger.error('Model is unavailable:' + error); + return { + success: false, + error: new ModelUnavailableError('Model is unavailable:' + error), + }; + } + + const tagContent = parseGenerateTag(fileArchContent); + const jsonData = extractJsonFromText(tagContent); + + if (!jsonData) { + this.logger.error('Failed to extract JSON from text'); + throw new ResponseParsingError('Failed to extract JSON from text.'); + } + + if (!this.validateJsonData(jsonData)) { + this.logger.error('File architecture JSON validation failed.'); + throw new ResponseParsingError( + 'File architecture JSON validation failed.', + ); + } + + const { nodes } = buildDependencyGraph(jsonData); + invalidFiles = validateAgainstVirtualDirectory(nodes, this.virtualDir); + if (invalidFiles) { + this.logger.warn('arch json content', fileArchContent); + this.logger.warn( + 'Validation against virtual directory failed. here is the invalid file, trying to fix it', + invalidFiles, + ); + } + } + + this.logger.log('File architecture document generated successfully.'); + return { + success: true, + data: formatResponse(fileArchContent), + }; + } + + private validateInputs( + dbSchema: any, + backendRequirementDoc: any, + framework: string, + projectPart: string, + ): void { + if (!backendRequirementDoc || typeof backendRequirementDoc !== 'string') { + throw new MissingConfigurationError( + 'Missing or invalid backendRequirementDoc.', + ); + } + if (!dbSchema || typeof dbSchema !== 'string') { + throw new MissingConfigurationError('Missing or invalid dbSchema.'); + } + if (!framework || typeof framework !== 'string') { + throw new MissingConfigurationError('Missing or invalid framework.'); + } + if (!['frontend', 'backend'].includes(projectPart)) { + throw new MissingConfigurationError( + 'Invalid projectPart. Must be either "frontend" or "backend".', + ); + } + } + + private validateJsonData(jsonData: { + files: Record; + }): boolean { + const validPathRegex = /^[a-zA-Z0-9_\-/.]+$/; + + for (const [file, details] of Object.entries(jsonData.files)) { + if (!validPathRegex.test(file)) { + this.logger.error(`Invalid file path: ${file}`); + return false; + } + + for (const dependency of details.dependsOn) { + if (!validPathRegex.test(dependency)) { + this.logger.error( + `Invalid dependency path "${dependency}" in file "${file}".`, + ); + return false; + } + + if (dependency.includes('//') || dependency.endsWith('/')) { + this.logger.error( + `Malformed dependency path "${dependency}" in file "${file}".`, + ); + return false; + } + } + } + return true; + } +} diff --git a/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts b/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts index 3b5035ec..e1df0c1a 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts @@ -7,12 +7,11 @@ * 2) The `CodeTaskQueue` class, a simple FIFO queue for tasks. * 3) The `FrontendQueueProcessor` class, which orchestrates: * - Writing files - * - Validating builds via `FrontendCodeValidator` + * - Validating builds via `CodeValidator` * - Attempting fixes (via LLM) if builds fail */ import { Logger } from '@nestjs/common'; -import { FrontendCodeValidator } from './CodeValidator'; import { readFileSync } from 'fs'; import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; import { createFileWithRetries } from 'src/build-system/utils/files'; @@ -26,6 +25,7 @@ import { FileOperationManager } from './FileOperationManager'; import normalizePath from 'normalize-path'; import path from 'path'; +import { CodeValidator } from './CodeValidator'; /** * Describes a single file task that the queue will process. @@ -57,23 +57,24 @@ export class CodeTaskQueue { } /** - * FrontendQueueProcessor + * QueueProcessor * * This class orchestrates how each `FileTask` is handled: * 1. Writes the file content to disk. - * 2. Runs a build/validation step (via `FrontendCodeValidator`). + * 2. Runs a build/validation step (via `CodeValidator`). * 3. If there is a build error, attempts to fix the file by * invoking an LLM and performing the suggested operations. * 4. Repeats until build succeeds or max attempts are reached. */ -export class FrontendQueueProcessor { - private logger = new Logger('FrontendQueueProcessor'); +export class CodeQueueProcessor { + private logger = new Logger('CodeQueueProcessor'); constructor( - private validator: FrontendCodeValidator, // Path to your frontend project + private validator: CodeValidator, // Path to your frontend project private queue: CodeTaskQueue, // The queue of files to process private context: BuilderContext, - private frontendPath: string, + private projectPart: string, + private projectPath: string, private renameMap: Map, ) {} @@ -105,7 +106,7 @@ export class FrontendQueueProcessor { this.logger.log(`Processing file task: ${task.filePath}`); let currentFullFilePath = normalizePath( - path.resolve(this.frontendPath, task.filePath), + path.resolve(this.projectPath, task.filePath), ); // 1. Write the file to disk @@ -137,7 +138,7 @@ export class FrontendQueueProcessor { if (newFilePath !== null) { task.filePath = newFilePath; currentFullFilePath = normalizePath( - path.resolve(this.frontendPath, newFilePath), + path.resolve(this.projectPath, newFilePath), ); } } catch (error) { @@ -185,7 +186,7 @@ export class FrontendQueueProcessor { const commonIssuePrompt = generateCommonErrorPrompt(); const fileOperationManager = new FileOperationManager( - this.frontendPath, + this.projectPath, this.renameMap, ); @@ -232,7 +233,7 @@ export class FrontendQueueProcessor { ], }, 'fix code (generic)', - 'FrontendQueueProcessor', + 'CodeQueueProcessor', ); this.logger.debug('Fix Response: ' + fixResponse); @@ -254,7 +255,7 @@ export class FrontendQueueProcessor { if (op.action === 'read' && op.originalPath) { try { op.code = readFileSync( - path.resolve(this.frontendPath, op.originalPath), + path.resolve(this.projectPath, op.originalPath), 'utf-8', ); this.logger.log(`Read file: ${op.originalPath}`); @@ -266,6 +267,10 @@ export class FrontendQueueProcessor { } } + this.logger.log( + this.projectPart === 'frontend' ? commonIssuePrompt : '', + ); + // **Second Attempt: Retry fix with additional file content** fixResponse = await chatSyncWithClocker( this.context, @@ -298,7 +303,7 @@ export class FrontendQueueProcessor { role: 'assistant', content: `Let me analysis the current file. Why error message occour This time I shouldn't use the read tool because previous context already use it. - Let me check some common issue to make sure my thinking is correct ${commonIssuePrompt}. + Let me check some common issue to make sure my thinking is correct ${this.projectPart === 'frontend' ? commonIssuePrompt : ''}. I must follow the output format`, }, { @@ -312,7 +317,7 @@ export class FrontendQueueProcessor { ], }, 'fix code (generic)', - 'FrontendQueueProcessor', + 'CodeQueueProcessor', ); this.logger.debug( 'Updated Fix Response with extra context: ' + fixResponse, @@ -330,6 +335,7 @@ export class FrontendQueueProcessor { this.logger.log(`Generic fix applied to file: ${task.filePath}`); if (newFilePath) { + this.logger.log(`File renamed to: ${newFilePath}`); return newFilePath; } diff --git a/backend/src/build-system/handlers/frontend-code-generate/CodeValidator.ts b/backend/src/build-system/handlers/frontend-code-generate/CodeValidator.ts index a15f7e6f..2638db0e 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/CodeValidator.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/CodeValidator.ts @@ -7,20 +7,25 @@ export interface ValidationResult { } /** - * FrontendCodeValidator is responsible for checking the correctness of the generated frontend code. + * CodeValidator is responsible for checking the correctness of the generated frontend code. * It runs an npm build command (or any custom build script) in the given project directory (frontendPath) * and captures any errors produced during the build process. */ -export class FrontendCodeValidator { - private readonly logger = new Logger('FrontendCodeValidator'); +export class CodeValidator { + private readonly logger = new Logger('CodeValidator'); /** - * @param frontendPath - The absolute path to the generated frontend project. + * @param projectPath - The absolute path to the generated project. */ - constructor(private readonly frontendPath: string) {} + constructor( + private readonly projectPath: string, + private readonly projectPart?: string, + ) { + this.projectPart = projectPart || 'frontend'; + } /** - * Runs the build command (npm run build) inside the frontend project directory. + * Runs the build command (npm run build) inside the project directory. * This method returns a promise that resolves with a ValidationResult, indicating whether * the build succeeded or failed along with any error messages. * @@ -29,14 +34,28 @@ export class FrontendCodeValidator { public async validate(): Promise { await this.installDependencies(); return new Promise((resolve, reject) => { - this.logger.log('Starting frontend code validation...'); - // Spawn the npm build process in the provided frontend project path. - const npmProcess = spawn('npm', ['run', 'build'], { - cwd: this.frontendPath, - shell: true, - }); - - this.logger.log('Running npm build command in', this.frontendPath); + this.logger.log(`Starting ${this.projectPart} code validation...`); + // Spawn the npm build process in the provided project path. + let npmProcess; + if (this.projectPart === 'frontend') { + npmProcess = spawn('npm', ['run', 'build'], { + cwd: this.projectPath, + shell: true, + }); + } else if (this.projectPart === 'backend') { + npmProcess = spawn('npm', ['run', 'check'], { + cwd: this.projectPath, + shell: true, + }); + } else if (this.projectPart === 'sqlite3') { + // Run SQLite in-memory check on the schema file + npmProcess = spawn('sqlite3', [':memory:', '".read schema.sql"'], { + cwd: this.projectPath, + shell: true, + }); + } + + this.logger.log('Running npm build command in', this.projectPath); let stdoutBuffer = ''; let stderrBuffer = ''; @@ -65,7 +84,9 @@ export class FrontendCodeValidator { }); } else { // Build succeeded - this.logger.log('Build process completed successfully.'); + this.logger.log( + `Build process ${this.projectPart} completed successfully.`, + ); resolve({ success: true, }); @@ -80,10 +101,10 @@ export class FrontendCodeValidator { public async installDependencies(): Promise { return new Promise((resolve, reject) => { - this.logger.log('Starting npm install in', this.frontendPath); + this.logger.log('Starting npm install in', this.projectPath); const npmInstall = spawn('npm', ['install'], { - cwd: this.frontendPath, + cwd: this.projectPath, shell: true, }); diff --git a/backend/src/build-system/handlers/frontend-code-generate/index.ts b/backend/src/build-system/handlers/frontend-code-generate/index.ts index 8a13f3ee..592b6a71 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/index.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/index.ts @@ -17,10 +17,9 @@ import { formatResponse } from 'src/build-system/utils/strings'; import { writeFileSync } from 'fs'; import { MessageInterface } from 'src/common/model-provider/types'; -import { FrontendCodeValidator } from './CodeValidator'; -import { FrontendQueueProcessor, CodeTaskQueue } from './CodeReview'; -// import { FileFAHandler } from '../file-manager/file-arch'; +import { CodeQueueProcessor, CodeTaskQueue } from './CodeReview'; import { FileStructureAndArchitectureHandler } from '../file-manager/file-struct'; +import { CodeValidator } from './CodeValidator'; interface FileInfos { [fileName: string]: { @@ -86,7 +85,7 @@ export class FrontendCodeHandler implements BuildHandler { const { concurrencyLayers, fileInfos } = await generateFilesDependencyWithLayers(fileArchDoc, this.virtualDir); - const validator = new FrontendCodeValidator(frontendPath); + const validator = new CodeValidator(frontendPath); // validator.installDependencies(); // 4. Process each "layer" in sequence; files in a layer in parallel @@ -161,7 +160,7 @@ export class FrontendCodeHandler implements BuildHandler { dependenciesText, directDepsPathString, sitemapStruct, - uxDataMapDoc, + backendRequirementDoc, failedFiles, ); } @@ -198,10 +197,11 @@ export class FrontendCodeHandler implements BuildHandler { } // Now process the entire queue for this layer: // This writes each file, runs build, fixes if needed, etc. - const queueProcessor = new FrontendQueueProcessor( + const queueProcessor = new CodeQueueProcessor( validator, queue, context, + 'frontend', frontendPath, renameMap, ); @@ -250,7 +250,7 @@ export class FrontendCodeHandler implements BuildHandler { dependenciesText: string, directDepsPathString: string, sitemapStruct: string, - uxDataMapDoc: string, + backendRequirementDoc: string, failedFiles: any[], ): Promise { let generatedCode = ''; @@ -294,13 +294,16 @@ export class FrontendCodeHandler implements BuildHandler { // Next will provide UX Datamap Documentation.`, // }, - // { - // role: 'user' as const, - // content: `This is the Backend Requirement Documentation: - // ${backendRequirementDoc} - - // Next will provide Backend Requirement Documentation.`, - // }, + { + role: 'assistant', + content: + "Good, now provider your API Documentation, it's okay API Documentation are empty, which means I don't need use API", + }, + { + role: 'user' as const, + content: `This is the API Documentation: + ${backendRequirementDoc}`, + }, { role: 'assistant', content: diff --git a/backend/src/build-system/handlers/frontend-code-generate/prompt.ts b/backend/src/build-system/handlers/frontend-code-generate/prompt.ts index f023a926..49e1dad1 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/prompt.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/prompt.ts @@ -26,6 +26,10 @@ ${theme} 10. Mock the response if the API returns an empty or undefined value, and you don't need to explicitly show that it is mock data. 11. Write EVERY CODE DETAIL, DON'T LEAVE TODO. 12. Image Assets: If your implementation requires any images except some button logo, you can use placeholder image URLs from https://picsum.photos//. Note that the width and height values (e.g., 500/300) are adjustable as needed. + 13. API Documentation: + If user provided, read carfully details in Api Document remeber to use correct request format then use the api. + Use the correct method (GET, POST, PUT, DELETE) and endpoint. Do not use Options. + The backend address is "localhost:3000". ## Library: "react-router": "^6", diff --git a/backend/src/build-system/handlers/ux/datamap/prompt.ts b/backend/src/build-system/handlers/ux/datamap/prompt.ts index b4670757..ef38a0a0 100644 --- a/backend/src/build-system/handlers/ux/datamap/prompt.ts +++ b/backend/src/build-system/handlers/ux/datamap/prompt.ts @@ -83,50 +83,6 @@ For each page in sitemap: - How data changes based on user actions - What feedback is needed - When/how data updates - -Example for Login Page: - -##### Login Page -**Purpose**: Allow users to authenticate and access their account - -**User Goals**: -- Sign into their account -- Recover forgotten password -- Stay signed in for convenience - -**Required Data Elements**: - -*Input Data*: -- Username/Email - - Purpose: Identify the user account - - User expectation: Email format or username rules - - Should be remembered if user chooses -- Password - - Purpose: Authenticate the user - - Should be masked for security - - Should support paste functionality -- "Remember Me" option - - Purpose: Convenience for returning users - - Optional selection - -*Display Data*: -- Login form status -- Authentication feedback -- Password requirements (if needed) -- Account recovery options - -*Feedback & States*: -- Loading state during authentication -- Success feedback and redirect -- Error messages for invalid credentials -- Password recovery confirmation - -**User Interactions**: -- Form validation feedback -- Login button state changes -- Immediate feedback on input errors -- Clear path to password recovery - --- Your reply must start with: "\`\`\`UXDataMap" and end with "\`\`\`". diff --git a/backend/template/template-backend/database_config.js b/backend/template/template-backend/database_config.js new file mode 100644 index 00000000..fa41c956 --- /dev/null +++ b/backend/template/template-backend/database_config.js @@ -0,0 +1,33 @@ +import sqlite3 from 'sqlite3'; +import { open } from 'sqlite'; +import { logger } from './logger'; +import path from 'path'; +import fs from 'fs'; + +const dbPath = path.join(__dirname, '../database.sqlite'); + +export const initializeDatabase = async () => { + try { + // Ensure directory exists + const dbDir = path.dirname(dbPath); + logger.info(dbDir); + if (!fs.existsSync(dbDir)) { + fs.mkdirSync(dbDir, { recursive: true }); + } + + // Open the database + const db = await open({ + filename: dbPath, + driver: sqlite3.Database, + }); + + // Enable foreign keys + await db.exec('PRAGMA foreign_keys = ON'); + + logger.info('Database initialized successfully'); + return db; + } catch (error) { + logger.error('Database initialization failed', error); + throw error; + } +}; diff --git a/backend/template/template-backend/index.js b/backend/template/template-backend/index.js new file mode 100644 index 00000000..aa5f133f --- /dev/null +++ b/backend/template/template-backend/index.js @@ -0,0 +1,11 @@ +import express from 'express'; +const app = express(); +const port = 3000; + +app.get('/', (req, res) => { + res.send('Hello World!'); +}); + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`); +}); diff --git a/backend/template/template-backend/logger.js b/backend/template/template-backend/logger.js new file mode 100644 index 00000000..92295de2 --- /dev/null +++ b/backend/template/template-backend/logger.js @@ -0,0 +1,22 @@ +// /** +// * Simple logger utility for application logging +// */ +// export const logger = { +// info: (message: string) => { +// console.log(`[INFO] ${new Date().toISOString()}: ${message}`); +// }, +// error: (message: string, error?: any) => { +// console.error(`[ERROR] ${new Date().toISOString()}: ${message}`); +// if (error) { +// console.error(error); +// } +// }, +// warn: (message: string) => { +// console.warn(`[WARN] ${new Date().toISOString()}: ${message}`); +// }, +// debug: (message: string) => { +// if (process.env.NODE_ENV !== 'production') { +// console.debug(`[DEBUG] ${new Date().toISOString()}: ${message}`); +// } +// }, +// }; diff --git a/backend/template/template-backend/package-lock.json b/backend/template/template-backend/package-lock.json new file mode 100644 index 00000000..6ed25e3b --- /dev/null +++ b/backend/template/template-backend/package-lock.json @@ -0,0 +1,2426 @@ +{ + "name": "temp-name", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "temp-name", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "body-parser": "^1.20.3", + "cors": "^2.8.5", + "dotenv": "^16.4.7", + "jsonwebtoken": "^9.0.2", + "sqlite": "^5.1.1", + "sqlite3": "^5.1.7", + "uuid": "^11.0.3" + }, + "devDependencies": { + "@types/body-parser": "^1.19.5", + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/node": "^22.13.5", + "@types/uuid": "^10.0.0", + "express": "^4.21.2" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "optional": true + }, + "node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "optional": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "optional": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", + "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/qs": { + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "optional": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "optional": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "optional": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "optional": true + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "optional": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "optional": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "optional": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "optional": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "optional": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "optional": true + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "optional": true + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "optional": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "optional": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "devOptional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-abi": { + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", + "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" + }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "optional": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "optional": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "optional": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "optional": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "optional": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true + }, + "node_modules/sqlite": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz", + "integrity": "sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==" + }, + "node_modules/sqlite3": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", + "tar": "^6.1.11" + }, + "optionalDependencies": { + "node-gyp": "8.x" + }, + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "optional": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "optional": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "optional": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/backend/template/template-backend/package.json b/backend/template/template-backend/package.json index a4c65f7e..8a63a133 100644 --- a/backend/template/template-backend/package.json +++ b/backend/template/template-backend/package.json @@ -1,13 +1,13 @@ { + "type": "module", "name": "temp-name", "version": "1.0.0", "description": "", - "main": "dist/index.js", - "type": "module", + "main": "index.js", "scripts": { - "start": "node dist/index.js", - "build": "tsc", - "dev": "node index.js" + "start": "node index.js", + "dev": "nodemon index.js", + "check": "node --input-type=module -e \"try { await import('./index.js').then(() => { console.log('Syntax check passed'); process.exit(0); }).catch(e => { console.error('Syntax error:', e); process.exit(1); }); } catch(e) { console.error('Syntax error:', e); process.exit(1); }\"" }, "keywords": [], "author": "", @@ -15,17 +15,14 @@ "dependencies": { "body-parser": "^1.20.3", "cors": "^2.8.5", + "dotenv": "^16.4.7", "express": "^4.21.2", + "jsonwebtoken": "^9.0.2", "sqlite": "^5.1.1", "sqlite3": "^5.1.7", "uuid": "^11.0.3" }, "devDependencies": { - "@types/body-parser": "^1.19.5", - "@types/cors": "^2.8.17", - "@types/express": "^5.0.0", - "@types/uuid": "^10.0.0", - "ts-node": "^10.9.2", - "typescript": "^5.7.2" + "nodemon": "^3.1.0" } } diff --git a/backend/template/template-backend/tsconfig.json b/backend/template/template-backend/tsconfig.json deleted file mode 100644 index d652c461..00000000 --- a/backend/template/template-backend/tsconfig.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs" /* Specify what module code is generated. */, - "rootDir": "./" /* Specify the root folder within your source files. */, - "outDir": "./dist" /* Specify an output folder for all emitted files. */, - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. */, - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - "sourceMap": true /* Create source map files for emitted JavaScript files. */, - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "removeComments": true, /* Disable emitting comments. */ - - /* Interop Constraints */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */, - "strict": true /* Enable all strict type-checking options. */ - - /* Type Checking */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - }, - "exclude": [ - "node_modules", - "dist" - ] /* Exclude 'node_modules' and 'dist' directories. */ -}