diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 078bc693c..edf61f55a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,67 +1,92 @@ -name: Security - CodeQL +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: 'CodeQL' on: + push: + branches: ['main', 'dev', 'release/*'] pull_request: - branches: - - main - - dev - - release/* + branches: ['main', 'dev', 'release/*'] schedule: - - cron: '0 0 * * 1' - -permissions: - contents: read + - cron: '25 0 * * 6' jobs: analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories actions: read contents: read - security-events: write - name: Analyze - runs-on: ubuntu-latest strategy: fail-fast: false matrix: - language: ['javascript', 'typescript'] - # CodeQL supports [ $supported-codeql-languages ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - + include: + - language: javascript-typescript + build-mode: none + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - - name: Harden Runner - uses: step-security/harden-runner@v2.6.1 - with: - egress-policy: audit - - name: Checkout repository - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2.22.12 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2.22.12 + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh + - if: matrix.build-mode == 'manual' + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2.22.12 + uses: github/codeql-action/analyze@v3 with: category: '/language:${{matrix.language}}' diff --git a/README.md b/README.md index a2160c3a1..620056619 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ The following diagram gives a high-level architecture overview of ZenStack. - [SvelteKit](https://zenstack.dev/docs/reference/server-adapters/sveltekit) - [Fastify](https://zenstack.dev/docs/reference/server-adapters/fastify) - [ExpressJS](https://zenstack.dev/docs/reference/server-adapters/express) +- [NestJS](https://zenstack.dev/docs/reference/server-adapters/nestjs) - 🙋đŸģ [Request for an adapter](https://discord.gg/Ykhr738dUe) ### Prisma schema extensions diff --git a/package.json b/package.json index a6379cc95..d1bf2332d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.0.1", + "version": "2.0.2", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index e2814464f..97ffc7ee3 100644 --- a/packages/ide/jetbrains/build.gradle.kts +++ b/packages/ide/jetbrains/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.zenstack" -version = "2.0.1" +version = "2.0.2" repositories { mavenCentral() diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index 30cc3ab5c..e0fce18cb 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.0.1", + "version": "2.0.2", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index 2895cc720..c1f73e9f7 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.0.1", + "version": "2.0.2", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index 6598da234..a1b0bb1b2 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/redwood", "displayName": "ZenStack RedwoodJS Integration", - "version": "2.0.1", + "version": "2.0.2", "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", "repository": { "type": "git", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 1a5225d58..3f95a0636 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index fcd1ac52f..5a1f84ec8 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index 7624ca49f..d00ba182b 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 98d87e47c..4a59f4e4b 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 8f418ab7e..2d65f7790 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.0.1", + "version": "2.0.2", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", diff --git a/packages/schema/package.json b/packages/schema/package.json index c61261d7b..e0ca565b6 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database", - "version": "2.0.1", + "version": "2.0.2", "author": { "name": "ZenStack Team" }, diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index 680bf11dd..0425b76d0 100644 --- a/packages/schema/src/plugins/enhancer/enhance/index.ts +++ b/packages/schema/src/plugins/enhancer/enhance/index.ts @@ -5,6 +5,7 @@ import { getAttributeArg, getAuthModel, getDataModels, + getLiteral, isDelegateModel, type PluginOptions, } from '@zenstackhq/sdk'; @@ -14,12 +15,14 @@ import { ReferenceExpr, isArrayExpr, isDataModel, + isGeneratorDecl, isReferenceExpr, type Model, } from '@zenstackhq/sdk/ast'; -import { getDMMF, getPrismaClientImportSpec, type DMMF } from '@zenstackhq/sdk/prisma'; +import { getDMMF, getPrismaClientImportSpec, getPrismaVersion, type DMMF } from '@zenstackhq/sdk/prisma'; import fs from 'fs'; import path from 'path'; +import semver from 'semver'; import { FunctionDeclarationStructure, InterfaceDeclaration, @@ -42,6 +45,8 @@ import { generateAuthType } from './auth-type-generator'; // information of delegate models and their sub models type DelegateInfo = [DataModel, DataModel[]][]; +const LOGICAL_CLIENT_GENERATION_PATH = './.logical-prisma-client'; + export class EnhancerGenerator { constructor( private readonly model: Model, @@ -60,7 +65,7 @@ export class EnhancerGenerator { // schema contains delegate models, need to generate a logical prisma schema const result = await this.generateLogicalPrisma(); - logicalPrismaClientDir = './.logical-prisma-client'; + logicalPrismaClientDir = LOGICAL_CLIENT_GENERATION_PATH; dmmf = result.dmmf; // create a reexport of the logical prisma client @@ -190,40 +195,76 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara private async generateLogicalPrisma() { const prismaGenerator = new PrismaSchemaGenerator(this.model); - const prismaClientOutDir = './.logical-prisma-client'; - const logicalPrismaFile = path.join(this.outDir, 'logical.prisma'); - await prismaGenerator.generate({ - provider: '@internal', // doesn't matter - schemaPath: this.options.schemaPath, - output: logicalPrismaFile, - overrideClientGenerationPath: prismaClientOutDir, - mode: 'logical', - }); - // generate the prisma client - const generateCmd = `prisma generate --schema "${logicalPrismaFile}" --no-engine`; + // dir of the zmodel file + const zmodelDir = path.dirname(this.options.schemaPath); + + // generate a temp logical prisma schema in zmodel's dir + const logicalPrismaFile = path.join(zmodelDir, `logical-${Date.now()}.prisma`); + + // calculate a relative output path to output the logical prisma client into enhancer's output dir + const prismaClientOutDir = path.join(path.relative(zmodelDir, this.outDir), LOGICAL_CLIENT_GENERATION_PATH); try { - // run 'prisma generate' - await execPackage(generateCmd, { stdio: 'ignore' }); - } catch { - await trackPrismaSchemaError(logicalPrismaFile); + await prismaGenerator.generate({ + provider: '@internal', // doesn't matter + schemaPath: this.options.schemaPath, + output: logicalPrismaFile, + overrideClientGenerationPath: prismaClientOutDir, + mode: 'logical', + }); + + // generate the prisma client + + // only run prisma client generator for the logical schema + const prismaClientGeneratorName = this.getPrismaClientGeneratorName(this.model); + let generateCmd = `prisma generate --schema "${logicalPrismaFile}" --generator=${prismaClientGeneratorName}`; + + const prismaVersion = getPrismaVersion(); + if (!prismaVersion || semver.gte(prismaVersion, '5.2.0')) { + // add --no-engine to reduce generation size if the prisma version supports + generateCmd += ' --no-engine'; + } + try { - // run 'prisma generate' again with output to the console - await execPackage(generateCmd); + // run 'prisma generate' + await execPackage(generateCmd, { stdio: 'ignore' }); } catch { - // noop + await trackPrismaSchemaError(logicalPrismaFile); + try { + // run 'prisma generate' again with output to the console + await execPackage(generateCmd); + } catch { + // noop + } + throw new PluginError(name, `Failed to run "prisma generate" on logical schema: ${logicalPrismaFile}`); } - throw new PluginError(name, `Failed to run "prisma generate" on logical schema: ${logicalPrismaFile}`); - } - // make a bunch of typing fixes to the generated prisma client - await this.processClientTypes(path.join(this.outDir, prismaClientOutDir)); + // make a bunch of typing fixes to the generated prisma client + await this.processClientTypes(path.join(this.outDir, LOGICAL_CLIENT_GENERATION_PATH)); + + return { + prismaSchema: logicalPrismaFile, + // load the dmmf of the logical prisma schema + dmmf: await getDMMF({ datamodel: fs.readFileSync(logicalPrismaFile, { encoding: 'utf-8' }) }), + }; + } finally { + if (fs.existsSync(logicalPrismaFile)) { + fs.rmSync(logicalPrismaFile); + } + } + } - return { - prismaSchema: logicalPrismaFile, - // load the dmmf of the logical prisma schema - dmmf: await getDMMF({ datamodel: fs.readFileSync(logicalPrismaFile, { encoding: 'utf-8' }) }), - }; + private getPrismaClientGeneratorName(model: Model) { + for (const generator of model.declarations.filter(isGeneratorDecl)) { + if ( + generator.fields.some( + (f) => f.name === 'provider' && getLiteral(f.value) === 'prisma-client-js' + ) + ) { + return generator.name; + } + } + throw new PluginError(name, `Cannot find prisma-client-js generator in the schema`); } private async processClientTypes(prismaClientDir: string) { diff --git a/packages/schema/src/plugins/enhancer/index.ts b/packages/schema/src/plugins/enhancer/index.ts index 0c82acfba..79e8fd6e6 100644 --- a/packages/schema/src/plugins/enhancer/index.ts +++ b/packages/schema/src/plugins/enhancer/index.ts @@ -1,4 +1,4 @@ -import { PluginError, createProject, resolvePath, type PluginFunction } from '@zenstackhq/sdk'; +import { PluginError, RUNTIME_PACKAGE, createProject, resolvePath, type PluginFunction } from '@zenstackhq/sdk'; import path from 'path'; import { getDefaultOutputFolder } from '../plugin-utils'; import { EnhancerGenerator } from './enhance'; @@ -31,7 +31,7 @@ const run: PluginFunction = async (model, options, _dmmf, globalOptions) => { // resolve it relative to the schema path prismaClientPath = path.relative(path.dirname(options.schemaPath), prismaClientPathAbs); } else { - prismaClientPath = `.zenstack/models`; + prismaClientPath = `${RUNTIME_PACKAGE}/models`; } } diff --git a/packages/schema/src/plugins/prisma/schema-generator.ts b/packages/schema/src/plugins/prisma/schema-generator.ts index d7e7f5b9a..5440e03cf 100644 --- a/packages/schema/src/plugins/prisma/schema-generator.ts +++ b/packages/schema/src/plugins/prisma/schema-generator.ts @@ -738,7 +738,7 @@ export class PrismaSchemaGenerator { const nonPrismaAttributes = field.attributes.filter((attr) => attr.decl.ref && !this.isPrismaAttribute(attr)); const documentations = nonPrismaAttributes.map((attr) => '/// ' + this.zModelGenerator.generate(attr)); - _enum.addField(field.name, attributes, documentations); + _enum.addField(field.name, attributes, documentations.concat(field.comments)); } } diff --git a/packages/schema/src/plugins/zod/generator.ts b/packages/schema/src/plugins/zod/generator.ts index f2f628b30..a9b963d30 100644 --- a/packages/schema/src/plugins/zod/generator.ts +++ b/packages/schema/src/plugins/zod/generator.ts @@ -1,6 +1,7 @@ import { PluginGlobalOptions, PluginOptions, + RUNTIME_PACKAGE, ensureEmptyDir, getDataModels, hasAttribute, @@ -279,7 +280,7 @@ export class ZodSchemaGenerator { } } if (importEnums.size > 0) { - const prismaImport = getPrismaClientImportSpec(path.join(output, 'models'), this.options); + const prismaImport = computePrismaClientImport(path.join(output, 'models'), this.options); writer.writeLine(`import { ${[...importEnums].join(', ')} } from '${prismaImport}';`); } @@ -581,3 +582,14 @@ export const ${upperCaseFirst(model.name)}UpdateSchema = ${updateSchema}; return `${schema}.passthrough()`; } } + +export function computePrismaClientImport(importingFrom: string, options: PluginOptions) { + let importPath = getPrismaClientImportSpec(importingFrom, options); + if (importPath.startsWith(RUNTIME_PACKAGE) && !options.output) { + // default import from `@zenstackhq/runtime` and this plugin is generating + // into default location, we should correct the prisma client import into a + // importing from `.zenstack` to avoid cyclic dependencies with runtime + importPath = importPath.replace(RUNTIME_PACKAGE, '.zenstack'); + } + return importPath; +} diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index 86829f1ca..4fb04cdcc 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -1,10 +1,11 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { indentString, type PluginOptions } from '@zenstackhq/sdk'; import { checkModelHasModelRelation, findModelByName, isAggregateInputType } from '@zenstackhq/sdk/dmmf-helpers'; -import { getPrismaClientImportSpec, type DMMF as PrismaDMMF } from '@zenstackhq/sdk/prisma'; +import { type DMMF as PrismaDMMF } from '@zenstackhq/sdk/prisma'; import path from 'path'; import type { Project, SourceFile } from 'ts-morph'; import { upperCaseFirst } from 'upper-case-first'; +import { computePrismaClientImport } from './generator'; import { AggregateOperationSupport, TransformerParams } from './types'; export default class Transformer { @@ -290,7 +291,7 @@ export const ${this.name}ObjectSchema: SchemaType = ${schema} as SchemaType;`; } generateImportPrismaStatement(options: PluginOptions) { - const prismaClientImportPath = getPrismaClientImportSpec( + const prismaClientImportPath = computePrismaClientImport( path.resolve(Transformer.outputPath, './objects'), options ); diff --git a/packages/schema/tests/generator/prisma-generator.test.ts b/packages/schema/tests/generator/prisma-generator.test.ts index c91034d1d..6eaf06399 100644 --- a/packages/schema/tests/generator/prisma-generator.test.ts +++ b/packages/schema/tests/generator/prisma-generator.test.ts @@ -223,6 +223,8 @@ describe('Prisma generator test', () => { } enum Role { + /// Admin role documentation line 1 + /// Admin role documentation line 2 ADMIN @map('admin') CUSTOMER @map('customer') @@map('_Role') @@ -251,6 +253,9 @@ describe('Prisma generator test', () => { expect(content).toContain(`@@map("_Role")`); expect(content).toContain(`@map("admin")`); expect(content).toContain(`@map("customer")`); + expect(content).toContain('/// Admin role documentation line 1\n' + + ' /// Admin role documentation line 2\n' + + ' ADMIN'); }); it('attribute passthrough', async () => { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 4dd88be1a..e7ea5a0fd 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index dce7c8a08..75711d009 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.0.1", + "version": "2.0.2", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", @@ -48,7 +48,7 @@ "@zenstackhq/testtools": "workspace:*", "body-parser": "^1.20.2", "decimal.js": "^10.4.2", - "express": "^4.18.2", + "express": "^4.19.2", "fastify": "^4.14.1", "fastify-plugin": "^4.5.0", "h3": "^1.8.2", diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 1d97794b6..3e69e9409 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.0.1", + "version": "2.0.2", "description": "ZenStack Test Tools", "main": "index.js", "private": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d08baac14..5ce4ac030 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -711,8 +711,8 @@ importers: specifier: ^10.4.2 version: 10.4.2 express: - specifier: ^4.18.2 - version: 4.18.2 + specifier: ^4.19.2 + version: 4.19.2 fastify: specifier: ^4.14.1 version: 4.14.1 @@ -6054,26 +6054,6 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - 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.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -8137,45 +8117,6 @@ packages: jest-util: 29.7.0 dev: true - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: true - /express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} @@ -12667,16 +12608,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: true - /raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'}