From 31927beea44a6f5dad6c4c159fd5b7688a37d3c3 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 22 Jan 2025 21:02:09 -0700 Subject: [PATCH 01/23] WIP make the CDS extractor platform independent Adds .cmd script equivalents for autobuild.sh, index-files.sh, and pre-finalize.sh scripts -- with the (unverified) intention being that the CDS extractor should be able to run on Linux, Mac, or Windows. Migrates most of the `index-files` script logic from shell script to javascript. Adds a `package.json` file to assist with managing dependencies for the new `extractors/cds/tools/index-files.js` script. --- extractors/cds/tools/autobuild.cmd | 12 ++ extractors/cds/tools/autobuild.sh | 7 +- extractors/cds/tools/index-files.cmd | 33 ++++++ extractors/cds/tools/index-files.js | 88 ++++++++++++++ extractors/cds/tools/index-files.sh | 116 +++++-------------- extractors/cds/tools/package.json | 12 ++ extractors/javascript/tools/pre-finalize.cmd | 14 +++ extractors/javascript/tools/pre-finalize.sh | 13 ++- 8 files changed, 197 insertions(+), 98 deletions(-) create mode 100644 extractors/cds/tools/autobuild.cmd create mode 100644 extractors/cds/tools/index-files.cmd create mode 100644 extractors/cds/tools/index-files.js create mode 100644 extractors/cds/tools/package.json create mode 100644 extractors/javascript/tools/pre-finalize.cmd diff --git a/extractors/cds/tools/autobuild.cmd b/extractors/cds/tools/autobuild.cmd new file mode 100644 index 000000000..c048d8b57 --- /dev/null +++ b/extractors/cds/tools/autobuild.cmd @@ -0,0 +1,12 @@ +@echo off + +type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_CDS_WIP_DATABASE%" + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index 5396796d6..22712c917 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -eu @@ -9,9 +9,10 @@ set -eu # Any changes should be synchronized between these three places. exec "${CODEQL_DIST}/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" \ No newline at end of file diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd new file mode 100644 index 000000000..1b6816aab --- /dev/null +++ b/extractors/cds/tools/index-files.cmd @@ -0,0 +1,33 @@ +@echo off + +if "%~1"=="" ( + echo Usage: %0 ^ + exit /b 1 +) + +where node >nul 2>nul +if %ERRORLEVEL% neq 0 ( + echo node executable is required (in PATH) to run the 'index-files.js' script. Please install Node.js and try again. + exit /b 2 +) + +where npm >nul 2>nul +if %ERRORLEVEL% neq 0 ( + echo npm executable is required (in PATH) to install the dependencies for the 'index-files.js' script. + exit /b 3 +) + +set "_response_file_path=%~1" + +echo Checking response file for CDS files to index + +if not exist "%_response_file_path%" ( + echo 'codeql database index-files --language cds' command terminated early as response file '%_response_file_path%' does not exist or is empty. This is because no CDS files were selected or found. + exit /b 0 +) + +echo Installing node package dependencies and running the 'index-files.js' script +npm install --quiet --no-audit --no-fund --no-package-json && ^ +node "%~dp0index-files.js" "%_response_file_path%" + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js new file mode 100644 index 000000000..24579a608 --- /dev/null +++ b/extractors/cds/tools/index-files.js @@ -0,0 +1,88 @@ +const { existsSync, readFileSync, statSync } = require('fs'); +const { execSync, spawnSync } = require('child_process'); +const { dirname, join, resolve } = require('path'); + +console.log('Indexing CDS files'); + +const responseFile = process.argv[2]; + +const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; + +if (!existsSync(responseFile)) { + console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); + process.exit(0); +} + +if (statSync(responseFile).size === 0) { + console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); + process.exit(0); +} + +let cdsCommand = 'cds'; +try { + execSync('cds --version', { stdio: 'ignore' }); +} catch { + console.log('Pre-installing cds compiler'); + const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); + const packageJsonDirs = new Set(); + + responseFiles.forEach(file => { + let dir = dirname(file); + while (dir !== resolve(dir, '..')) { + if (existsSync(join(dir, 'package.json')) && readFileSync(join(dir, 'package.json'), 'utf-8').includes('@sap/cds')) { + packageJsonDirs.add(dir); + break; + } + dir = resolve(dir, '..'); + } + }); + + packageJsonDirs.forEach(dir => { + console.log(`Installing @sap/cds-dk into ${dir} to enable CDS compilation.`); + execSync(`${npmInstallCmdWithArgs} @sap/cds-dk`, { cwd: dir }); + execSync(npmInstallCmdWithArgs, { cwd: dir }); + }); + + cdsCommand = 'npx -y --package @sap/cds-dk cds'; +} + +console.log('Processing CDS files to JSON'); + +const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +responseFiles.forEach(cdsFile => { + const cdsJsonFile = `${cdsFile}.json`; + console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); + const result = spawnSync(cdsCommand, ['compile', cdsFile, '-2', 'json', '-o', cdsJsonFile, '--locations'], { shell: true }); + if (result.error || result.status !== 0) { + const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); + const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + console.log(errorMessage); + execSync(`${process.env.CODEQL_DIST}/codeql database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "${errorMessage}" --file-path "${cdsFile}" "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + } +}); + +if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${process.env.CODEQL_DIST}/codeql resolve extractor --language=javascript`).toString().trim(); + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; +} + +let excludeFilters = ''; +if (process.env.LGTM_INDEX_FILTERS) { + console.log(`Found $LGTM_INDEX_FILTERS already set to:\n${process.env.LGTM_INDEX_FILTERS}`); + excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS.split('\n').filter(line => line.startsWith('exclude') && !['exclude:**/*', 'exclude:**/*.*'].includes(line)).join('\n'); +} + +process.env.LGTM_INDEX_FILTERS = `exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*${excludeFilters}`; +console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); +process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; +process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; +delete process.env.LGTM_INDEX_INCLUDE; + +console.log('Extracting the cds.json files'); + +execSync(`${process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh`, { stdio: 'inherit' }); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 092d126a9..5761a3651 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -1,104 +1,40 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu -echo "Indexing CDS files" - -# Check if the list of files is empty -response_file="$1" - -# If the response_file doesn't exist, terminate: -if [ ! -f "$response_file" ]; then - echo "codeql database index-files --language cds terminated early as response file '$response_file' does not exist. This is because no CDS files were selected or found." - exit 0 +if [ $# -ne 1 ] +then + echo "Usage: $0 " + exit 1 fi -# If the response_file is empty, terminate -if [ ! -s "$response_file" ]; then - echo "codeql database index-files --language cds terminated early as response file '$response_file' is empty. This is because no CDS files were selected or found." - exit 0 +if ! command -v node > /dev/null +then + echo "node executable is required (in PATH) to run the 'index-files.js' script. Please install Node.js and try again." + exit 2 fi -# Determine if we have the cds command available, and if not, install the cds development kit -# in the appropriate directories -if ! command -v cds &> /dev/null +if ! command -v npm > /dev/null then - echo "Pre-installing cds compiler" - - # Find all the directories containing a package.json with a dependency on @sap/cds, where - # the directory contains at least one of the files listed in the response file (e.g. the - # cds files we want to extract). - # - # We then install the cds development kit (@sap/cds-dk) in each directory, which makes the - # `cds` command usable from the npx command within that directory. - # - # Nested package.json files simply cause the package to be installed in the parent node_modules - # directory. - # - # We also ensure we skip node_modules, as we can end up in a recursive loop - find . -type d -name node_modules -prune -false -o -type f \( -iname 'package.json' \) -exec grep -ql '@sap/cds' {} \; -execdir bash -c "grep -q \"^\$(pwd)\(/\|$\)\" \"$response_file\"" \; -execdir bash -c "echo \"Installing @sap/cds-dk into \$(pwd) to enable CDS compilation.\"" \; -execdir npm install --silent @sap/cds-dk \; -execdir npm install --silent \; - - # Use the npx command to dynamically install the cds development kit (@sap/cds-dk) package if necessary, - # which then provides the cds command line tool in directories which are not covered by the package.json - # install command approach above - cds_command="npx -y --package @sap/cds-dk cds" -else - cds_command="cds" + echo "npm executable is required (in PATH) to install the dependencies for the 'index-files.js' script." + exit 3 fi -echo "Processing CDS files to JSON" +_response_file_path="$1" -# Run the cds compile command on each file in the response file, outputting the compiled JSON to a file with -# the same name -while IFS= read -r cds_file; do - echo "Processing CDS file $cds_file to:" - if ! $cds_command compile "$cds_file" -2 json -o "$cds_file.json" --locations 2> "$cds_file.err"; then - stderr_truncated=`grep "^\[ERROR\]" "$cds_file.err" | tail -n 4` - error_message=$'Could not compile the file '"$cds_file"$'.\nReported error(s):\n```\n'"$stderr_truncated"$'\n```' - echo "$error_message" - # Log an error diagnostic which appears on the status page - "$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "$error_message" --file-path "$cds_file" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" - fi -done < "$response_file" +echo "Checking response file for CDS files to index" -# Check if the JS extractor variables are set, and set them if not -if [ -z "${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT:-}" ]; then - # Find the JavaScript extractor location - export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$("$CODEQL_DIST/codeql" resolve extractor --language=javascript)" - - # Set the JAVASCRIPT extractor environment variables to the same as the CDS extractor environment variables - # so that the JS extractor will write to the CDS database - export CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" - export CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="$CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR="$CODEQL_EXTRACTOR_CDS_LOG_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR="$CODEQL_EXTRACTOR_CDS_SCRATCH_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="$CODEQL_EXTRACTOR_CDS_TRAP_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="$CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR" -fi - -# Check if LGTM_INDEX_FILTERS is already set -# This typically happens if "paths" or "paths-ignore" are set in the LGTM.yml file -if [ -z "${LGTM_INDEX_FILTERS:-}" ]; then - exclude_filters="" -else - echo $'Found \$LGTM_INDEX_FILTERS already set to:\n'"$LGTM_INDEX_FILTERS" - # If it is set, we will try to honour the paths-ignore filter - # Split by \n and find all the entries that start with exclude, excluding "exclude:**/*" and "exclude:**/*.*" - # and then join them back together with \n - exclude_filters=$'\n'"$(echo "$LGTM_INDEX_FILTERS" | grep '^exclude' | grep -v 'exclude:\*\*/\*\|exclude:\*\*/\*\.\*')" +# Terminate early if the _response_file_path doesn't exist or is empty, +# which indicates that no CDS files were selected or found. +if [ ! -f "$_response_file_path" ] || [ ! -s "$_response_file_path" ] +then + echo "'codeql database index-files --language cds' command terminated early as response file '$_response_file_path' does not exist or is empty. This is because no CDS files were selected or found." + # Exit without error to avoid failing any calling (javascript) + # extractor, and llow the tool the report the lack of coverage + # for CDS files. + exit 0 fi -# Enable extraction of the cds.json files only -export LGTM_INDEX_FILTERS=$'exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*'"$exclude_filters" -echo "Setting \$LGTM_INDEX_FILTERS to:\n$LGTM_INDEX_FILTERS" -export LGTM_INDEX_TYPESCRIPT="NONE" -# Configure to copy over the CDS files as well, by pretending they are JSON -export LGTM_INDEX_FILETYPES=".cds:JSON" -# Ignore the LGTM_INDEX_INCLUDE variable for this purpose, as it may -# refer explicitly to .ts or .js files -unset LGTM_INDEX_INCLUDE - -echo "Extracting the cds.json files" - -# Invoke the JavaScript autobuilder to index the .cds.json files only -"$CODEQL_EXTRACTOR_JAVASCRIPT_ROOT"/tools/autobuild.sh \ No newline at end of file +echo "Installing node package dependencies and running the 'index-files.js' script" +npm install --quiet --no-audit --no-fund --no-package-json && \ +node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json new file mode 100644 index 000000000..6503344a9 --- /dev/null +++ b/extractors/cds/tools/package.json @@ -0,0 +1,12 @@ +{ + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "description": "CodeQL extractor for DB indexing of .cds.json files produced by the 'cds' compiler.", + "main": "index-files.js", + "dependencies": { + "@sap/cds-dk": "^4.0.0", + "child_process": "^1.0.2", + "fs": "^0.0.1-security", + "path": "^0.12.7" + } +} diff --git a/extractors/javascript/tools/pre-finalize.cmd b/extractors/javascript/tools/pre-finalize.cmd new file mode 100644 index 000000000..1f698488f --- /dev/null +++ b/extractors/javascript/tools/pre-finalize.cmd @@ -0,0 +1,14 @@ +@echo off + +if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( + type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE%" +) + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/javascript/tools/pre-finalize.sh b/extractors/javascript/tools/pre-finalize.sh index ad7b28f2f..770312831 100755 --- a/extractors/javascript/tools/pre-finalize.sh +++ b/extractors/javascript/tools/pre-finalize.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu @@ -8,14 +8,17 @@ set -eu # - extractors/javascript/tools/pre-finalize.sh (here) # Any changes should be synchronized between these three places. -# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION environment variable is set +# Do not extract CDS files if the +# CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor - "$CODEQL_DIST/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ + "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE" fi \ No newline at end of file From 54938b63338040e8b5264e9ce40c7855d1b8643c Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Mon, 27 Jan 2025 17:46:46 -0700 Subject: [PATCH 02/23] Improve extractor script comments and file paths Adds comments in index-files.js to better reflect the documented intentions from the old version of index-files.sh script. Better explains the script magic, in places. Attempts to make the index-files.js (JavaScript) script more useful as a multi-platform solution by normalizing file paths using the path.join() function. --- extractors/cds/tools/index-files.cmd | 9 +- extractors/cds/tools/index-files.js | 89 +- extractors/cds/tools/index-files.sh | 8 +- extractors/cds/tools/package-lock.json | 3552 ++++++++++++++++++++++++ extractors/cds/tools/package.json | 1 + 5 files changed, 3646 insertions(+), 13 deletions(-) create mode 100644 extractors/cds/tools/package-lock.json diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd index 1b6816aab..93db0625c 100644 --- a/extractors/cds/tools/index-files.cmd +++ b/extractors/cds/tools/index-files.cmd @@ -18,6 +18,7 @@ if %ERRORLEVEL% neq 0 ( ) set "_response_file_path=%~1" +set "_script_dir=%~dp0" echo Checking response file for CDS files to index @@ -26,8 +27,12 @@ if not exist "%_response_file_path%" ( exit /b 0 ) -echo Installing node package dependencies and running the 'index-files.js' script +REM Change to the directory of this script to ensure that npm looks up +REM the package.json file in the correct directory and installs the +REM dependencies (i.e. node_modules) relative to this directory. +cd /d "%_script_dir%" && ^ +echo Installing node package dependencies and running the 'index-files.js' script && ^ npm install --quiet --no-audit --no-fund --no-package-json && ^ -node "%~dp0index-files.js" "%_response_file_path%" +node "%_script_dir%index-files.js" "%_response_file_path%" exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 24579a608..5542cc7b4 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,31 +1,57 @@ -const { existsSync, readFileSync, statSync } = require('fs'); const { execSync, spawnSync } = require('child_process'); +const { existsSync, readFileSync, statSync } = require('fs'); +const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); console.log('Indexing CDS files'); const responseFile = process.argv[2]; +const osPlatform = platform(); +const osPlatformArch = arch(); +console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); +const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; +const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; +const codeqlExePath = join(process.env.CODEQL_DIST, codeqlExe); const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; +// If the response file does not exist, terminate. if (!existsSync(responseFile)) { console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); process.exit(0); } -if (statSync(responseFile).size === 0) { +const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +// If the response file is empty, terminate. +if (statSync(responseFile).size === 0 || !responseFiles) { console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); process.exit(0); } +// Determine if we have the cds commands available. If not, install the cds develpment kit +// (cds-dk) in the appropriate directories and use npx to run the cds command from there. let cdsCommand = 'cds'; try { execSync('cds --version', { stdio: 'ignore' }); } catch { console.log('Pre-installing cds compiler'); - const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); - const packageJsonDirs = new Set(); + /** + * Find all the directories containing a package.json with a dependency on `@sap/cds`, + * where the directory contains at least one of the files listed in the response file + * (e.g. the cds files we want to extract). + * + * We then install the CDS development kit (`@sap/cds-dk`) in each directory, which + * makes the `cds` command usable from the npx command within that directory. + * + * Nested package.json files simply cause the package to be installed in the parent + * node_modules directory. + * + * TODO : fix implementation or change ^comment^ to reflect the actual implementation. + * + * We also ensure we skip node_modules, as we can end up in a recursive loop. + */ + const packageJsonDirs = new Set(); responseFiles.forEach(file => { let dir = dirname(file); while (dir !== resolve(dir, '..')) { @@ -43,12 +69,20 @@ try { execSync(npmInstallCmdWithArgs, { cwd: dir }); }); + /** + * Use the `npx` command to dynamically install the CDS development kit (`@sap/cds-dk`) + * package if necessary, which then provides the `cds` command line tool in directories + * which are not covered by the package.json install command approach above. + */ cdsCommand = 'npx -y --package @sap/cds-dk cds'; } console.log('Processing CDS files to JSON'); -const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +/** + * Run the cds compile command on each file in the response files list, outputting the + * compiled JSON to a file with the same name but with a .json extension appended. + */ responseFiles.forEach(cdsFile => { const cdsJsonFile = `${cdsFile}.json`; console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); @@ -57,12 +91,17 @@ responseFiles.forEach(cdsFile => { const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); - execSync(`${process.env.CODEQL_DIST}/codeql database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "${errorMessage}" --file-path "${cdsFile}" "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + execSync(`${codeqlExePath} database add-diagnostic --extractor-name cds --ready-for-status-page --source-id=cds/compilation-failure --source-name="Failure to compile one or more SAP CAP CDS files" --severity=error --markdown-message="${errorMessage}" --file-path="${cdsFile}" -- "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); } }); +// Check if the (JavaScript) JS extractor variables are set, and set them if not. if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${process.env.CODEQL_DIST}/codeql resolve extractor --language=javascript`).toString().trim(); + // Find the JS extractor location. + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${codeqlExePath} resolve extractor --language=javascript`).toString().trim(); + // Set the JAVASCRIPT extractor environment variables to the same as the CDS + // extractor environment variables so that the JS extractor will write to the + // CDS database. process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; @@ -72,17 +111,47 @@ if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { } let excludeFilters = ''; +/** + * Check if LGTM_INDEX_FILTERS is already set. This tyically happens if either + * "paths" and/or "paths-ignore" is set in the lgtm.yml file. + */ if (process.env.LGTM_INDEX_FILTERS) { console.log(`Found $LGTM_INDEX_FILTERS already set to:\n${process.env.LGTM_INDEX_FILTERS}`); - excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS.split('\n').filter(line => line.startsWith('exclude') && !['exclude:**/*', 'exclude:**/*.*'].includes(line)).join('\n'); + const allowedExcludePatterns = [ + join('exclude:**', '*'), + join('exclude:**', '*.*'), + ]; + /** + * If it is set, we will try to honor the paths-ignore filter. + * + * Split by `\n` and find all the entries that start with exclude, with some + * exclusions allowed for supported glob patterns, and then join them back + * together with `\n`. + */ + excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS + .split('\n') + .filter(line => + line.startsWith('exclude') + && + !allowedExcludePatterns.includes(line) + ).join('\n'); } -process.env.LGTM_INDEX_FILTERS = `exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*${excludeFilters}`; +// Enable extraction of the .cds.json files only. +const lgtmIndexFiltersPatterns = join( + 'exclude:**', '*.*\ninclude:**', '*.cds.json\ninclude:**', '*.cds\nexclude:**', 'node_modules', '**', '*.*' +); +process.env.LGTM_INDEX_FILTERS = `${lgtmIndexFiltersPatterns}${excludeFilters}`; console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; +// Configure to copy over the .cds files as well, by pretending they are JSON. process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; +// Ignore the LGTM_INDEX_INCLUDE variable for this purpose as it may explicitly +// refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; console.log('Extracting the cds.json files'); -execSync(`${process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh`, { stdio: 'inherit' }); +// Invoke the JS autobuilder to index the .cds.json files only. +const autobuildScriptPath = join(process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName); +execSync(autobuildScriptPath, { stdio: 'inherit' }); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 5761a3651..c20e9532c 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -21,6 +21,7 @@ then fi _response_file_path="$1" +_script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) echo "Checking response file for CDS files to index" @@ -35,6 +36,11 @@ then exit 0 fi -echo "Installing node package dependencies and running the 'index-files.js' script" +# Change to the directory of this script to ensure that npm looks up +# the package.json file in the correct directory and installs the +# dependencies (i.e. node_modules) relative to this directory. +cd "$_script_dir" && \ +echo "Installing node package dependencies" && \ npm install --quiet --no-audit --no-fund --no-package-json && \ +echo "Running the 'index-files.js' script" && \ node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file diff --git a/extractors/cds/tools/package-lock.json b/extractors/cds/tools/package-lock.json new file mode 100644 index 000000000..a3edf5331 --- /dev/null +++ b/extractors/cds/tools/package-lock.json @@ -0,0 +1,3552 @@ +{ + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "dependencies": { + "@sap/cds-dk": "^4.0.0", + "child_process": "^1.0.2", + "fs": "^0.0.1-security", + "os": "^0.1.2", + "path": "^0.12.7" + } + }, + "node_modules/@sap/cds-dk": { + "version": "4.9.7", + "resolved": "https://registry.npmjs.org/@sap/cds-dk/-/cds-dk-4.9.7.tgz", + "integrity": "sha512-o44qREvZYiNPJRey2dCFdQPqcc0S/S8Sh4Zde9u9Ehyf4WF844oYZjiIgeCXDK6JxzksCDCfcXnpUp51eG1fSg==", + "hasShrinkwrap": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@sap/cds": "^5.9.2", + "@sap/cds-foss": "^3", + "@sap/eslint-plugin-cds": "^2.3.3", + "axios": ">=0.21", + "connect-livereload": "^0.6.1", + "eslint": "^8", + "express": "^4.17.1", + "htmlparser2": "^7.2.0", + "livereload-js": "^3.3.1", + "md5": "^2.3.0", + "mustache": "^4.0.1", + "node-watch": ">=0.7", + "pluralize": "^8.0.0", + "ws": "^8.4.2", + "xml-js": "^1.6.11" + }, + "bin": { + "cds": "bin/cds.js", + "cds-ts": "bin/cds-ts.js" + }, + "optionalDependencies": { + "sqlite3": "npm:@mendix/sqlite3@^5.0.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@colors/colors": { + "version": "1.5.0", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@sap/cds-dk/node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@eslint/eslintrc": { + "version": "1.3.0", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "node_modules/@sap/cds-dk/node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/analytics": { + "version": "1.54.2", + "integrity": "sha512-CUoyVJ2HjPGJKwhV7EnUWR9n7c/uYpDyygy8ROzpgdT1qDVyMNWjtaaCbR4a15afIpRvJ5soLDFFLWyK6CV40g==", + "deprecated": "1.x is no longer maintained.", + "dependencies": { + "@sap-cloud-sdk/util": "^1.54.2", + "axios": "^0.26.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/analytics/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/core": { + "version": "1.54.2", + "integrity": "sha512-oF1nMYo9qAk4BDAypuAfhofxxeNKTqIroMfZAqgOb8vXxwtsZjS+bK03mptxE3cPnDhwUV0LaOeNy5foIv9oCw==", + "deprecated": "Version 1 of SAP Cloud SDK is no longer maintained. Check the upgrade guide for switching to version 2: https://sap.github.io/cloud-sdk/docs/js/guides/upgrade-to-version-2.", + "dependencies": { + "@sap-cloud-sdk/analytics": "^1.54.2", + "@sap-cloud-sdk/util": "^1.54.2", + "@sap/xsenv": "^3.0.0", + "@sap/xssec": "^3.2.7", + "@types/jsonwebtoken": "^8.3.8", + "axios": "^0.26.0", + "bignumber.js": "^9.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "jsonwebtoken": "^8.5.1", + "moment": "^2.29.0", + "opossum": "^6.0.0", + "uuid": "^8.2.0", + "voca": "^1.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/core/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/util": { + "version": "1.54.2", + "integrity": "sha512-ZC70YlHG6c2zH4OjzTtbb4s9eNJdMJEQm3KRL+u7/kN/vRJr7IrQZmidSa8RO86nnx2GZPn4zH3GTsnwAQEHuA==", + "deprecated": "1.x is no longer maintained.", + "dependencies": { + "axios": "^0.26.0", + "chalk": "^4.1.0", + "logform": "^2.2.0", + "promise.allsettled": "^1.0.4", + "voca": "^1.4.0", + "winston": "^3.3.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/util/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds": { + "version": "5.9.6", + "integrity": "sha512-zzDoRrgAbRXUQ2n+BrDErtAyylMgcJxgWhsiJvjiZVMxAucJMPp9V+WlRsaGwSm8O6STC6NHcv9PWQ7500y9EQ==", + "dependencies": { + "@sap-cloud-sdk/core": "^1.41", + "@sap-cloud-sdk/util": "^1.41", + "@sap/cds-compiler": "^2.13.0", + "@sap/cds-foss": "^3" + }, + "bin": { + "cds": "bin/cds.js" + }, + "engines": { + "node": ">=12.18" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-compiler": { + "version": "2.15.2", + "integrity": "sha512-i4MmceDSsKX+6DieGBf3zo6EGjELNEVQLo7Wl0K2vP8gXJrtveFJQxHW6dsp/Cro7qh0C28WbBNTlPiHPjyygg==", + "hasInstallScript": true, + "dependencies": { + "antlr4": "4.8.0" + }, + "bin": { + "cdsc": "bin/cdsc.js", + "cdshi": "bin/cdshi.js", + "cdsse": "bin/cdsse.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss": { + "version": "3.1.1", + "integrity": "sha512-U4DF1VdPiqqCYmV7w9mLgRaM3F98cuJaCBRsrSp9rUCt3yAXeUnHflQhGDHmFnQRCGDStxFNx7oskDfpkD5lWw==", + "hasShrinkwrap": true, + "dependencies": { + "big.js": "6.1.1", + "fs-extra": "10.0.1", + "generic-pool": "3.8.2", + "uuid": "8.3.2", + "xmlbuilder": "15.1.1", + "yaml": "1.10.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/big.js": { + "version": "6.1.1", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/fs-extra": { + "version": "10.0.1", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/generic-pool": { + "version": "3.8.2", + "integrity": "sha1-qrTygK21Iv373F5bZNcY02g/BOk=", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/graceful-fs": { + "version": "4.2.6", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "license": "ISC" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/jsonfile": { + "version": "6.1.0", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/universalify": { + "version": "2.0.0", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/uuid": { + "version": "8.3.2", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/xmlbuilder": { + "version": "15.1.1", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/yaml": { + "version": "1.10.2", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/eslint-plugin-cds": { + "version": "2.3.5", + "integrity": "sha512-wbCqc+Vwiqg8svvPB/ms5r/z5VS7ckkSPBKTPY83jftUtvMGKVWvC3yMctAaGItlE32eK5FjHKCmgNZu4qG9Tg==", + "dependencies": { + "@sap/cds": "^5.6.0", + "semver": "^7.3.4" + }, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv": { + "version": "3.3.1", + "integrity": "sha512-ESsfrlGBRZ7AF1ud+ZZ3CVfGgifPx2lo0djOpqHgzPzSkjv3h3hIGXF5ErW6gKcrwSKCPNA6j3STfbdSK5zqwA==", + "hasShrinkwrap": true, + "dependencies": { + "debug": "4.3.3", + "node-cache": "^5.1.0", + "verror": "1.10.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || ^14.0.0 || ^16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/assert-plus": { + "version": "1.0.0" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/clone": { + "version": "2.1.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/core-util-is": { + "version": "1.0.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/debug": { + "version": "4.3.3", + "dependencies": { + "ms": "2.1.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/extsprintf": { + "version": "1.4.1" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/ms": { + "version": "2.1.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/node-cache": { + "version": "5.1.2", + "dependencies": { + "clone": "2.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/verror": { + "version": "1.10.0", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xssec": { + "version": "3.2.13", + "integrity": "sha512-F/hFDDf00y/n1ngbnHS9yTcyZqN88q3tMWbG2/AmJYz0PvBGgfmkgkcKxVq+D+aIQmtBJpWZ43H9Pu53MOcJfQ==", + "dependencies": { + "axios": "^0.26.0", + "debug": "4.3.2", + "jsonwebtoken": "^8.5.1", + "lru-cache": "6.0.0", + "node-rsa": "^1.1.1", + "valid-url": "1.0.9" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xssec/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@tootallnate/once": { + "version": "2.0.0", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sap/cds-dk/node_modules/@types/jsonwebtoken": { + "version": "8.5.8", + "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/@types/node": { + "version": "17.0.41", + "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==" + }, + "node_modules/@sap/cds-dk/node_modules/abbrev": { + "version": "1.1.1", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/accepts": { + "version": "1.3.8", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/acorn": { + "version": "8.7.1", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/acorn-jsx": { + "version": "5.3.2", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/agent-base": { + "version": "6.0.2", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ajv": { + "version": "6.12.6", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@sap/cds-dk/node_modules/ansi-regex": { + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/ansi-styles": { + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/antlr4": { + "version": "4.8.0", + "integrity": "sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==" + }, + "node_modules/@sap/cds-dk/node_modules/aproba": { + "version": "2.0.0", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/are-we-there-yet": { + "version": "2.0.0", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/argparse": { + "version": "2.0.1", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@sap/cds-dk/node_modules/array-flatten": { + "version": "1.1.1", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/@sap/cds-dk/node_modules/array.prototype.map": { + "version": "1.0.4", + "integrity": "sha512-Qds9QnX7A0qISY7JT5WuJO0NJPE9CMlC6JzHQfhpqAAQQzufVRoeH7EzUY5GcPTx72voG8LV/5eo+b8Qi8hmhA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/asn1": { + "version": "0.2.6", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/assert-plus": { + "version": "1.0.0", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/async": { + "version": "3.2.4", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/@sap/cds-dk/node_modules/asynckit": { + "version": "0.4.0", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/@sap/cds-dk/node_modules/aws-sign2": { + "version": "0.7.0", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/aws4": { + "version": "1.11.0", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/axios": { + "version": "0.27.2", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/balanced-match": { + "version": "1.0.2", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/@sap/cds-dk/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/bignumber.js": { + "version": "9.0.2", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser": { + "version": "1.20.0", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "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.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/brace-expansion": { + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/@sap/cds-dk/node_modules/bytes": { + "version": "3.1.2", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/call-bind": { + "version": "1.0.2", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/callsites": { + "version": "3.1.0", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/caseless": { + "version": "0.12.0", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/charenc": { + "version": "0.0.2", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/chownr": { + "version": "2.0.0", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/code-point-at": { + "version": "1.1.0", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color": { + "version": "3.2.1", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-convert": { + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-name": { + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@sap/cds-dk/node_modules/color-string": { + "version": "1.9.1", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-support": { + "version": "1.1.3", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@sap/cds-dk/node_modules/colorspace": { + "version": "1.1.4", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/combined-stream": { + "version": "1.0.8", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/concat-map": { + "version": "0.0.1", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/@sap/cds-dk/node_modules/connect-livereload": { + "version": "0.6.1", + "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/console-control-strings": { + "version": "1.1.0", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/content-disposition": { + "version": "0.5.4", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/content-type": { + "version": "1.0.4", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/cookie": { + "version": "0.5.0", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/cookie-signature": { + "version": "1.0.6", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/@sap/cds-dk/node_modules/core-util-is": { + "version": "1.0.2", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/cross-spawn": { + "version": "7.0.3", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/crypt": { + "version": "0.0.2", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/dashdash": { + "version": "1.14.1", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/debug": { + "version": "4.3.2", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/deep-is": { + "version": "0.1.4", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/@sap/cds-dk/node_modules/define-properties": { + "version": "1.1.4", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/delayed-stream": { + "version": "1.0.0", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/delegates": { + "version": "1.0.0", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/depd": { + "version": "2.0.0", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/destroy": { + "version": "1.2.0", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/@sap/cds-dk/node_modules/detect-libc": { + "version": "2.0.1", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/doctrine": { + "version": "3.0.0", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/dom-serializer": { + "version": "1.4.1", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/domelementtype": { + "version": "2.3.0", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/@sap/cds-dk/node_modules/domhandler": { + "version": "4.3.1", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/domutils": { + "version": "2.8.0", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/ecc-jsbn": { + "version": "0.1.2", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/ee-first": { + "version": "1.1.1", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/@sap/cds-dk/node_modules/emoji-regex": { + "version": "8.0.0", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/enabled": { + "version": "2.0.0", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "node_modules/@sap/cds-dk/node_modules/encodeurl": { + "version": "1.0.2", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/entities": { + "version": "3.0.1", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/env-paths": { + "version": "2.2.1", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-abstract": { + "version": "1.20.1", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/@sap/cds-dk/node_modules/es-get-iterator": { + "version": "1.1.2", + "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-to-primitive": { + "version": "1.2.1", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/escape-html": { + "version": "1.0.3", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/@sap/cds-dk/node_modules/escape-string-regexp": { + "version": "4.0.0", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint": { + "version": "8.17.0", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "dependencies": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-scope": { + "version": "7.1.1", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-utils": { + "version": "3.0.0", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/espree": { + "version": "9.3.2", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dependencies": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/esquery": { + "version": "1.4.0", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/esrecurse": { + "version": "4.3.0", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/estraverse": { + "version": "5.3.0", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/esutils": { + "version": "2.0.3", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/etag": { + "version": "1.8.1", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/express": { + "version": "4.18.1", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "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.10.3", + "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" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/extend": { + "version": "3.0.2", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/extsprintf": { + "version": "1.3.0", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/fast-deep-equal": { + "version": "3.1.3", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/@sap/cds-dk/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/@sap/cds-dk/node_modules/fast-levenshtein": { + "version": "2.0.6", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/@sap/cds-dk/node_modules/fecha": { + "version": "4.2.3", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "node_modules/@sap/cds-dk/node_modules/file-entry-cache": { + "version": "6.0.1", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/finalhandler": { + "version": "1.2.0", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "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/@sap/cds-dk/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/flat-cache": { + "version": "3.0.4", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/flatted": { + "version": "3.2.5", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + }, + "node_modules/@sap/cds-dk/node_modules/fn.name": { + "version": "1.1.0", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "node_modules/@sap/cds-dk/node_modules/follow-redirects": { + "version": "1.15.1", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/forever-agent": { + "version": "0.6.1", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/form-data": { + "version": "4.0.0", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/forwarded": { + "version": "0.2.0", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/fresh": { + "version": "0.5.2", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/fs-minipass": { + "version": "2.1.0", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/fs.realpath": { + "version": "1.0.0", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/@sap/cds-dk/node_modules/function-bind": { + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/@sap/cds-dk/node_modules/function.prototype.name": { + "version": "1.1.5", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/functional-red-black-tree": { + "version": "1.0.1", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, + "node_modules/@sap/cds-dk/node_modules/functions-have-names": { + "version": "1.2.3", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/gauge": { + "version": "3.0.2", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/get-intrinsic": { + "version": "1.1.1", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/get-symbol-description": { + "version": "1.0.0", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/getpass": { + "version": "0.1.7", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/glob": { + "version": "7.2.3", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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/@sap/cds-dk/node_modules/glob-parent": { + "version": "6.0.2", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/globals": { + "version": "13.15.0", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/graceful-fs": { + "version": "4.2.10", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/har-schema": { + "version": "2.0.0", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/har-validator": { + "version": "5.1.5", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "optional": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/has": { + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-bigints": { + "version": "1.0.2", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-flag": { + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-property-descriptors": { + "version": "1.0.0", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-symbols": { + "version": "1.0.3", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-tostringtag": { + "version": "1.0.0", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-unicode": { + "version": "2.0.1", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/htmlparser2": { + "version": "7.2.0", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/http-errors": { + "version": "2.0.0", + "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/@sap/cds-dk/node_modules/http-proxy-agent": { + "version": "5.0.0", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/http-signature": { + "version": "1.2.0", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/@sap/cds-dk/node_modules/https-proxy-agent": { + "version": "5.0.1", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ignore": { + "version": "5.2.0", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/import-fresh": { + "version": "3.3.0", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/imurmurhash": { + "version": "0.1.4", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/@sap/cds-dk/node_modules/inflight": { + "version": "1.0.6", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/@sap/cds-dk/node_modules/inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/@sap/cds-dk/node_modules/internal-slot": { + "version": "1.0.3", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/ipaddr.js": { + "version": "1.9.1", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-arguments": { + "version": "1.1.1", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-bigint": { + "version": "1.0.4", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-boolean-object": { + "version": "1.1.2", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-buffer": { + "version": "1.1.6", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/@sap/cds-dk/node_modules/is-callable": { + "version": "1.2.4", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-date-object": { + "version": "1.0.5", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-extglob": { + "version": "2.1.1", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-glob": { + "version": "4.0.3", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-map": { + "version": "2.0.2", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-negative-zero": { + "version": "2.0.2", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-number-object": { + "version": "1.0.7", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-regex": { + "version": "1.1.4", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-set": { + "version": "2.0.2", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-stream": { + "version": "2.0.1", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-string": { + "version": "1.0.7", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-symbol": { + "version": "1.0.4", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-typedarray": { + "version": "1.0.0", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/is-weakref": { + "version": "1.0.2", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/isarray": { + "version": "2.0.5", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/@sap/cds-dk/node_modules/isexe": { + "version": "2.0.0", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/@sap/cds-dk/node_modules/isstream": { + "version": "0.1.2", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/iterate-iterator": { + "version": "1.0.2", + "integrity": "sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/iterate-value": { + "version": "1.0.2", + "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "dependencies": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/js-yaml": { + "version": "4.1.0", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsbn": { + "version": "0.1.1", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/json-schema": { + "version": "0.4.0", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/json-schema-traverse": { + "version": "0.4.1", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/@sap/cds-dk/node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/@sap/cds-dk/node_modules/json-stringify-safe": { + "version": "5.0.1", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/jsonwebtoken": { + "version": "8.5.1", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "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": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsprim": { + "version": "1.4.2", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/jwa": { + "version": "1.4.1", + "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/@sap/cds-dk/node_modules/jws": { + "version": "3.2.2", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/kuler": { + "version": "2.0.0", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "node_modules/@sap/cds-dk/node_modules/levn": { + "version": "0.4.1", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/livereload-js": { + "version": "3.4.0", + "integrity": "sha512-F/pz9ZZP+R+arY94cECTZco7PXgBXyL+KVWUPZq8AQE9TOu14GV6fYeKOviv02JCvFa4Oi3Rs1hYEpfeajc+ow==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.includes": { + "version": "4.3.0", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isboolean": { + "version": "3.0.3", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isinteger": { + "version": "4.0.4", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isnumber": { + "version": "3.0.3", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isplainobject": { + "version": "4.0.6", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isstring": { + "version": "4.0.1", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.merge": { + "version": "4.6.2", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.once": { + "version": "4.1.1", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/@sap/cds-dk/node_modules/logform": { + "version": "2.4.0", + "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", + "dependencies": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/lru-cache": { + "version": "6.0.0", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/make-dir": { + "version": "3.1.0", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/md5": { + "version": "2.3.0", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/media-typer": { + "version": "0.3.0", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/merge-descriptors": { + "version": "1.0.1", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/@sap/cds-dk/node_modules/methods": { + "version": "1.1.2", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime-db": { + "version": "1.52.0", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime-types": { + "version": "2.1.35", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/minimatch": { + "version": "3.1.2", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/minipass": { + "version": "3.1.6", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/minizlib": { + "version": "2.1.2", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/mkdirp": { + "version": "1.0.4", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/moment": { + "version": "2.29.3", + "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@sap/cds-dk/node_modules/mustache": { + "version": "4.2.0", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/@sap/cds-dk/node_modules/natural-compare": { + "version": "1.4.0", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/@sap/cds-dk/node_modules/negotiator": { + "version": "0.6.3", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-addon-api": { + "version": "4.3.0", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch": { + "version": "2.6.7", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp": { + "version": "7.1.2", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/ansi-regex": { + "version": "2.1.1", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/aproba": { + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "1.1.7", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/gauge": { + "version": "2.7.4", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/isarray": { + "version": "1.0.0", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/npmlog": { + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/readable-stream": { + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/string_decoder": { + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/string-width": { + "version": "1.0.2", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/strip-ansi": { + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-rsa": { + "version": "1.1.1", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "dependencies": { + "asn1": "^0.2.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-watch": { + "version": "0.7.3", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/nopt": { + "version": "5.0.0", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/npmlog": { + "version": "5.0.1", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/number-is-nan": { + "version": "1.0.1", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/oauth-sign": { + "version": "0.9.0", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-inspect": { + "version": "1.12.2", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-keys": { + "version": "1.1.1", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/object.assign": { + "version": "4.1.2", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/on-finished": { + "version": "2.4.1", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/once": { + "version": "1.4.0", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/@sap/cds-dk/node_modules/one-time": { + "version": "1.0.0", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/opossum": { + "version": "6.3.0", + "integrity": "sha512-youR7pMTpgnbPJEPruM8Ku1WKUXnjmsK99GC5fkGFrOK8jduY1hvMiooUa3QZg6Xdso03skr37q6Evpt9PZ2cA==", + "engines": { + "node": "^16 || ^14 || ^12" + } + }, + "node_modules/@sap/cds-dk/node_modules/optionator": { + "version": "0.9.1", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/parent-module": { + "version": "1.0.1", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/parseurl": { + "version": "1.3.3", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-is-absolute": { + "version": "1.0.1", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-key": { + "version": "3.1.1", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-to-regexp": { + "version": "0.1.7", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/@sap/cds-dk/node_modules/performance-now": { + "version": "2.1.0", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/pluralize": { + "version": "8.0.0", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/prelude-ls": { + "version": "1.2.1", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/process-nextick-args": { + "version": "2.0.1", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/promise.allsettled": { + "version": "1.0.5", + "integrity": "sha512-tVDqeZPoBC0SlzJHzWGZ2NKAguVq2oiYj7gbggbiTvH2itHohijTp7njOUA0aQ/nl+0lr/r6egmhoYu63UZ/pQ==", + "dependencies": { + "array.prototype.map": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "iterate-value": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/proxy-addr": { + "version": "2.0.7", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/psl": { + "version": "1.8.0", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/punycode": { + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/qs": { + "version": "6.10.3", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/range-parser": { + "version": "1.2.1", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/raw-body": { + "version": "2.5.1", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "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/@sap/cds-dk/node_modules/readable-stream": { + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/regexpp": { + "version": "3.2.0", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/@sap/cds-dk/node_modules/request": { + "version": "2.88.2", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/qs": { + "version": "6.5.3", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/resolve-from": { + "version": "4.0.0", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/rimraf": { + "version": "3.0.2", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sap/cds-dk/node_modules/safe-buffer": { + "version": "5.2.1", + "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/@sap/cds-dk/node_modules/safe-stable-stringify": { + "version": "2.3.1", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/@sap/cds-dk/node_modules/sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/@sap/cds-dk/node_modules/semver": { + "version": "7.3.7", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/send": { + "version": "0.18.0", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "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/@sap/cds-dk/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/send/node_modules/ms": { + "version": "2.1.3", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@sap/cds-dk/node_modules/serve-static": { + "version": "1.15.0", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/set-blocking": { + "version": "2.0.0", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/setprototypeof": { + "version": "1.2.0", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/@sap/cds-dk/node_modules/shebang-command": { + "version": "2.0.0", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/shebang-regex": { + "version": "3.0.0", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/side-channel": { + "version": "1.0.4", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/signal-exit": { + "version": "3.0.7", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/simple-swizzle": { + "version": "0.2.2", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/@sap/cds-dk/node_modules/sqlite3": { + "name": "@mendix/sqlite3", + "version": "5.0.3", + "integrity": "sha512-GqQy6UZsr6pYZZjShmwy51VsPVROC88wDluQTCkWz9Cq/Y76ci2CJ4q2fjqEfiP2dQTAn4WxB1Ui2IZ5Z7/+Ow==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0" + }, + "optionalDependencies": { + "node-gyp": "7.x" + }, + "peerDependencies": { + "node-gyp": "7.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/sshpk": { + "version": "1.17.0", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/stack-trace": { + "version": "0.0.10", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/statuses": { + "version": "2.0.1", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/string_decoder": { + "version": "1.3.0", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/string-width": { + "version": "4.2.3", + "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/@sap/cds-dk/node_modules/string.prototype.trimend": { + "version": "1.0.5", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/strip-ansi": { + "version": "6.0.1", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/strip-json-comments": { + "version": "3.1.1", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/supports-color": { + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/tar": { + "version": "6.1.11", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sap/cds-dk/node_modules/text-hex": { + "version": "1.0.0", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "node_modules/@sap/cds-dk/node_modules/text-table": { + "version": "0.2.0", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "node_modules/@sap/cds-dk/node_modules/toidentifier": { + "version": "1.0.1", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/triple-beam": { + "version": "1.3.0", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "node_modules/@sap/cds-dk/node_modules/tunnel-agent": { + "version": "0.6.0", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/tweetnacl": { + "version": "0.14.5", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/type-check": { + "version": "0.4.0", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/type-fest": { + "version": "0.20.2", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/type-is": { + "version": "1.6.18", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/unbox-primitive": { + "version": "1.0.2", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/unpipe": { + "version": "1.0.0", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/uri-js": { + "version": "4.4.1", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/@sap/cds-dk/node_modules/utils-merge": { + "version": "1.0.1", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/uuid": { + "version": "8.3.2", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/v8-compile-cache": { + "version": "2.3.0", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "node_modules/@sap/cds-dk/node_modules/valid-url": { + "version": "1.0.9", + "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" + }, + "node_modules/@sap/cds-dk/node_modules/vary": { + "version": "1.1.2", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/verror": { + "version": "1.10.0", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/voca": { + "version": "1.4.0", + "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==" + }, + "node_modules/@sap/cds-dk/node_modules/which": { + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/which-boxed-primitive": { + "version": "1.0.2", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/wide-align": { + "version": "1.1.5", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/winston": { + "version": "3.7.2", + "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==", + "dependencies": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/winston-transport": { + "version": "4.5.0", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/word-wrap": { + "version": "1.2.3", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/wrappy": { + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/@sap/cds-dk/node_modules/ws": { + "version": "8.7.0", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/xml-js": { + "version": "1.6.11", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/yallist": { + "version": "4.0.0", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==", + "license": "ISC" + }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==", + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/os": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", + "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==", + "license": "MIT" + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "license": "MIT", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + } + } +} diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json index 6503344a9..caa288d17 100644 --- a/extractors/cds/tools/package.json +++ b/extractors/cds/tools/package.json @@ -7,6 +7,7 @@ "@sap/cds-dk": "^4.0.0", "child_process": "^1.0.2", "fs": "^0.0.1-security", + "os": "^0.1.2", "path": "^0.12.7" } } From ea229d13d2cd649f378f7362d8c4d2620d3781c4 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Mon, 27 Jan 2025 17:53:11 -0700 Subject: [PATCH 03/23] Add requested comment to extractor.js responsFiles --- extractors/cds/tools/index-files.js | 1 + 1 file changed, 1 insertion(+) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 5542cc7b4..7d9c198d8 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -21,6 +21,7 @@ if (!existsSync(responseFile)) { process.exit(0); } +// Read the response file and split it into lines, removing (filter(Boolean)) empty lines. const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); // If the response file is empty, terminate. if (statSync(responseFile).size === 0 || !responseFiles) { From aed1fc6e22f0b172b196ca102559c7d95f538fd4 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 29 Jan 2025 16:17:44 -0700 Subject: [PATCH 04/23] WIP fixes for CDS extractor rewrite First attempt at fixing `Indirect uncontrolled command line` code scanning alerts for the `index-fils.js` script. Improves error handling and improves the reliability and security of code that creates child (exec/spawn) processes. Attempts to improve the passing of env vars to child processes, especially for the `LGTM_INDEX_FILTERS` env var. WIP because CDS extractor invocation is still failing to identify .cds.json files. Possible problem in the way env vars are passed within the javascript extractor autobuilder shell script (to the JVM launched by the javascript extractor autobuilder). --- extractors/cds/tools/autobuild.cmd | 4 +- extractors/cds/tools/autobuild.sh | 2 +- extractors/cds/tools/index-files.js | 167 ++++++++++++++----- extractors/cds/tools/index-files.sh | 4 +- extractors/cds/tools/package-lock.json | 15 +- extractors/cds/tools/package.json | 3 +- extractors/javascript/tools/pre-finalize.cmd | 2 +- 7 files changed, 151 insertions(+), 46 deletions(-) diff --git a/extractors/cds/tools/autobuild.cmd b/extractors/cds/tools/autobuild.cmd index c048d8b57..d5143ae00 100644 --- a/extractors/cds/tools/autobuild.cmd +++ b/extractors/cds/tools/autobuild.cmd @@ -1,6 +1,6 @@ @echo off -type NUL && "%CODEQL_DIST%\codeql" database index-files ^ +type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ --include-extension=.cds ^ --language cds ^ --prune **\node_modules\**\* ^ @@ -9,4 +9,4 @@ type NUL && "%CODEQL_DIST%\codeql" database index-files ^ -- ^ "%CODEQL_EXTRACTOR_CDS_WIP_DATABASE%" -exit /b %ERRORLEVEL% \ No newline at end of file +exit /b %ERRORLEVEL% diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index 22712c917..fdf9dc225 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -15,4 +15,4 @@ exec "${CODEQL_DIST}/codeql" database index-files \ --prune **/.eslint/**/* \ --total-size-limit=10m \ -- \ - "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" \ No newline at end of file + "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 7d9c198d8..783ce2bdf 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,8 @@ -const { execSync, spawnSync } = require('child_process'); +const { execFileSync, execSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync } = require('fs'); const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); +const { quote } = require('shell-quote'); console.log('Indexing CDS files'); @@ -11,21 +12,42 @@ const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; +const autobuildScriptPath = join( + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName +); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(process.env.CODEQL_DIST, codeqlExe); -const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; +const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); -// If the response file does not exist, terminate. +/** + * Terminate early if: + * - the javascript extractor autobuild script does not exist; or + * - the codeql executable does not exist; or + * - the input responseFile does not exist; or + * - the input responseFile is empty or could not be parsed as a list of file paths. + */ +if (!existsSync(autobuildScriptPath)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as autobuild script '${autobuildScriptPath}' does not exist.`); + process.exit(0); +} +if (!existsSync(codeqlExePath)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as codeql executable '${codeqlExePath}' does not exist.`); + process.exit(0); +} if (!existsSync(responseFile)) { - console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); process.exit(0); } -// Read the response file and split it into lines, removing (filter(Boolean)) empty lines. -const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); -// If the response file is empty, terminate. -if (statSync(responseFile).size === 0 || !responseFiles) { - console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); +let responseFiles = []; +try { + // Read the response file and split it into lines, removing (filter(Boolean)) empty lines. + responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); + if (statSync(responseFile).size === 0 || responseFiles.length === 0) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); + process.exit(0); + } +} catch (err) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' could not be read due to an error: ${err}`); process.exit(0); } @@ -33,10 +55,12 @@ if (statSync(responseFile).size === 0 || !responseFiles) { // (cds-dk) in the appropriate directories and use npx to run the cds command from there. let cdsCommand = 'cds'; try { - execSync('cds --version', { stdio: 'ignore' }); + execFileSync('cds', ['--version'], { stdio: 'ignore' }); } catch { console.log('Pre-installing cds compiler'); + // Use a JS `Set` to avoid duplicate processing of the same directory. + const packageJsonDirs = new Set(); /** * Find all the directories containing a package.json with a dependency on `@sap/cds`, * where the directory contains at least one of the files listed in the response file @@ -52,22 +76,51 @@ try { * * We also ensure we skip node_modules, as we can end up in a recursive loop. */ - const packageJsonDirs = new Set(); responseFiles.forEach(file => { - let dir = dirname(file); + let dir = dirname(quote([file])); while (dir !== resolve(dir, '..')) { - if (existsSync(join(dir, 'package.json')) && readFileSync(join(dir, 'package.json'), 'utf-8').includes('@sap/cds')) { - packageJsonDirs.add(dir); - break; + const packageJsonPath = join(dir, 'package.json'); + if (existsSync(packageJsonPath)) { + const rawData = readFileSync(packageJsonPath, 'utf-8'); + const packageJsonData = JSON.parse(rawData); + // Check if the 'name' and 'dependencies' properties are present in the + // package.json file at packageJsonPath. + if ( + packageJsonData.name && + packageJsonData.dependencies && + typeof packageJsonData.dependencies === 'object' + ) { + const dependencyNames = Object.keys(packageJsonData.dependencies); + if ( + dependencyNames.includes('@sap/cds') + && + dependencyNames.includes('@sap/cds-dk') + ) { + packageJsonDirs.add(dir); + break; + } + } } + // Move up one directory level and try again to find a package.json file + // for the response file. dir = resolve(dir, '..'); } }); - packageJsonDirs.forEach(dir => { - console.log(`Installing @sap/cds-dk into ${dir} to enable CDS compilation.`); - execSync(`${npmInstallCmdWithArgs} @sap/cds-dk`, { cwd: dir }); - execSync(npmInstallCmdWithArgs, { cwd: dir }); + // TODO : revise this check as the equality is probably not guaranteed. + if (responseFiles.length !== packageJsonDirs.length) { + console.warn( + `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` + ); + } + + packageJsonDirs.forEach((dir) => { + console.log(`Installing node packages into ${dir} to enable CDS compilation.`); + execFileSync( + 'npm', + ['install', '--quiet', '--no-audit', '--no-fund'], + { cwd: dir, stdio: 'inherit' } + ); }); /** @@ -84,22 +137,46 @@ console.log('Processing CDS files to JSON'); * Run the cds compile command on each file in the response files list, outputting the * compiled JSON to a file with the same name but with a .json extension appended. */ -responseFiles.forEach(cdsFile => { - const cdsJsonFile = `${cdsFile}.json`; - console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); - const result = spawnSync(cdsCommand, ['compile', cdsFile, '-2', 'json', '-o', cdsJsonFile, '--locations'], { shell: true }); +responseFiles.forEach(rawCdsFilePath => { + const cdsFilePath = quote([rawCdsFilePath]); + const cdsJsonFilePath = `${cdsFilePath}.json`; + console.log(`Processing CDS file ${cdsFilePath} to: ${cdsJsonFilePath}`); + const result = spawnSync( + cdsCommand, + ['compile', cdsFilePath, '-2', 'json', '-o', cdsJsonFilePath, '--locations'], + { shell: true } + ); if (result.error || result.status !== 0) { - const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); - const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + const stderrTruncated = quote( + result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n')); + const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); - execSync(`${codeqlExePath} database add-diagnostic --extractor-name cds --ready-for-status-page --source-id=cds/compilation-failure --source-name="Failure to compile one or more SAP CAP CDS files" --severity=error --markdown-message="${errorMessage}" --file-path="${cdsFile}" -- "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + execFileSync( + codeqlExePath, + [ + 'database', + 'add-diagnostic', + '--extractor-name=cds', + '--ready-for-status-page', + '--source-id=cds/compilation-failure', + '--source-name="Failure to compile one or more SAP CAP CDS files"', + '--severity=error', + `--markdown-message="${errorMessage}"`, + `--file-path="${cdsFilePath}"`, + '--', + `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` + ], + ); } }); // Check if the (JavaScript) JS extractor variables are set, and set them if not. if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { // Find the JS extractor location. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${codeqlExePath} resolve extractor --language=javascript`).toString().trim(); + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( + codeqlExePath, + ['resolve', 'extractor', '--language=javascript'] + ).toString().trim(); // Set the JAVASCRIPT extractor environment variables to the same as the CDS // extractor environment variables so that the JS extractor will write to the // CDS database. @@ -134,16 +211,19 @@ if (process.env.LGTM_INDEX_FILTERS) { .filter(line => line.startsWith('exclude') && - !allowedExcludePatterns.includes(line) + !allowedExcludePatterns.some(pattern => line.includes(pattern)) ).join('\n'); } // Enable extraction of the .cds.json files only. -const lgtmIndexFiltersPatterns = join( - 'exclude:**', '*.*\ninclude:**', '*.cds.json\ninclude:**', '*.cds\nexclude:**', 'node_modules', '**', '*.*' -); -process.env.LGTM_INDEX_FILTERS = `${lgtmIndexFiltersPatterns}${excludeFilters}`; -console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); +const lgtmIndexFiltersPatterns = [ + join('exclude:**', '*.*'), + join('include:**', '*.cds.json'), + join('include:**', '*.cds'), + join('exclude:**', 'node_modules', '**', '*.*') +].join('\n');; +process.env.LGTM_INDEX_FILTERS = lgtmIndexFiltersPatterns + excludeFilters; +console.log(`Set $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; // Configure to copy over the .cds files as well, by pretending they are JSON. process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; @@ -151,8 +231,19 @@ process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; // refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; -console.log('Extracting the cds.json files'); +console.log('Extracting the .cds.json files'); -// Invoke the JS autobuilder to index the .cds.json files only. -const autobuildScriptPath = join(process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName); -execSync(autobuildScriptPath, { stdio: 'inherit' }); +console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptPath}`); +/** + * Invoke the javascript autobuilder to index the .cds.json files only. + * + * Environment variables must be passed from this script's process to the + * process that invokes the autobuild script, otherwise the CDS autobuild.sh + * script will not be invoked by the autobuild script built into the + * 'javascript' extractor. + */ +spawnSync( + autobuildScriptPath, + [], + { env: process.env, shell: true, stdio: 'inherit' } +); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index c20e9532c..67bb815e6 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -41,6 +41,6 @@ fi # dependencies (i.e. node_modules) relative to this directory. cd "$_script_dir" && \ echo "Installing node package dependencies" && \ -npm install --quiet --no-audit --no-fund --no-package-json && \ +npm install --quiet --no-audit --no-fund && \ echo "Running the 'index-files.js' script" && \ -node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file +node "$(dirname "$0")/index-files.js" "$_response_file_path" diff --git a/extractors/cds/tools/package-lock.json b/extractors/cds/tools/package-lock.json index a3edf5331..436181e58 100644 --- a/extractors/cds/tools/package-lock.json +++ b/extractors/cds/tools/package-lock.json @@ -12,7 +12,8 @@ "child_process": "^1.0.2", "fs": "^0.0.1-security", "os": "^0.1.2", - "path": "^0.12.7" + "path": "^0.12.7", + "shell-quote": "^1.8.2" } }, "node_modules/@sap/cds-dk": { @@ -3539,6 +3540,18 @@ "node": ">= 0.6.0" } }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json index caa288d17..a1c4cd78b 100644 --- a/extractors/cds/tools/package.json +++ b/extractors/cds/tools/package.json @@ -8,6 +8,7 @@ "child_process": "^1.0.2", "fs": "^0.0.1-security", "os": "^0.1.2", - "path": "^0.12.7" + "path": "^0.12.7", + "shell-quote": "^1.8.2" } } diff --git a/extractors/javascript/tools/pre-finalize.cmd b/extractors/javascript/tools/pre-finalize.cmd index 1f698488f..924856eb8 100644 --- a/extractors/javascript/tools/pre-finalize.cmd +++ b/extractors/javascript/tools/pre-finalize.cmd @@ -1,7 +1,7 @@ @echo off if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( - type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ --include-extension=.cds ^ --language cds ^ --prune **\node_modules\**\* ^ From d02234ed3493a54b630e4096d9107a3265947b2a Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 29 Jan 2025 19:21:25 -0700 Subject: [PATCH 05/23] Fix CDS extractor JS undefined var --- extractors/cds/tools/index-files.js | 57 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 783ce2bdf..250adf174 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -11,12 +11,43 @@ const responseFile = process.argv[2]; const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); +const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; +const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); + +let CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT + ? quote([process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT]) + : undefined; +// Check if the (JavaScript) JS extractor variables are set, and set them if not. +if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + // Find the JS extractor location. + CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( + codeqlExePath, + ['resolve', 'extractor', '--language=javascript'] + ).toString().trim(); + // Terminate early if the CODEQL_EXTRACTOR_JAVASCRIPT_ROOT environment + // variable was not already set and could not be resolved via CLI. + if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + console.warn( + `'${codeqlExe} database index-files --language cds' terminated early as CODEQL_EXTRACTOR_JAVASCRIPT_ROOT environment variable is not set.` + ); + process.exit(0); + } + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = CODEQL_EXTRACTOR_JAVASCRIPT_ROOT; + // Set the JAVASCRIPT extractor environment variables to the same as the CDS + // extractor environment variables so that the JS extractor will write to the + // CDS database. + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; +} + const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; const autobuildScriptPath = join( - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName + CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName ); -const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); /** * Terminate early if: @@ -108,7 +139,7 @@ try { }); // TODO : revise this check as the equality is probably not guaranteed. - if (responseFiles.length !== packageJsonDirs.length) { + if (responseFiles.length !== packageJsonDirs.size) { console.warn( `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` ); @@ -170,24 +201,6 @@ responseFiles.forEach(rawCdsFilePath => { } }); -// Check if the (JavaScript) JS extractor variables are set, and set them if not. -if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { - // Find the JS extractor location. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( - codeqlExePath, - ['resolve', 'extractor', '--language=javascript'] - ).toString().trim(); - // Set the JAVASCRIPT extractor environment variables to the same as the CDS - // extractor environment variables so that the JS extractor will write to the - // CDS database. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; -} - let excludeFilters = ''; /** * Check if LGTM_INDEX_FILTERS is already set. This tyically happens if either From a17b8c2fa7f06f7b674ae00d847fd30c845e1d4c Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 30 Jan 2025 09:03:29 -0700 Subject: [PATCH 06/23] Set cwd for CDS JS autobuild process Fixes the invocation of the javascript extractor autobuild within the index-files.js script of the CDS extractor. Ensures that the `cwd` property/option is set when spawning the process that runs the javascript extractor autobuild. Potential working version of initial rewrite for the CDS extractor. --- extractors/cds/tools/index-files.js | 45 +++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 250adf174..71be68573 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,4 +1,4 @@ -const { execFileSync, execSync, spawnSync } = require('child_process'); +const { execFileSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync } = require('fs'); const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); @@ -13,6 +13,12 @@ const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); +const projectRootDir = resolve(`${dirname(__filename)}/../../..`); + +if (!existsSync(projectRootDir)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${projectRootDir}'.`); + process.exit(0); +} let CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT ? quote([process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT]) @@ -122,11 +128,7 @@ try { typeof packageJsonData.dependencies === 'object' ) { const dependencyNames = Object.keys(packageJsonData.dependencies); - if ( - dependencyNames.includes('@sap/cds') - && - dependencyNames.includes('@sap/cds-dk') - ) { + if (dependencyNames.includes('@sap/cds')) { packageJsonDirs.add(dir); break; } @@ -138,14 +140,20 @@ try { } }); - // TODO : revise this check as the equality is probably not guaranteed. - if (responseFiles.length !== packageJsonDirs.size) { - console.warn( - `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` - ); + // Sanity check that we found at least one package.json directory from which the CDS + // compiler dependencies may be installed. + if (packageJsonDirs.size === 0) { + console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); + exit(0); } packageJsonDirs.forEach((dir) => { + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation.`); + execFileSync( + 'npm', + ['install', '--quiet', '--no-audit', '--no-fund', '@sap/cds-dk'], + { cwd: dir, stdio: 'inherit' } + ); console.log(`Installing node packages into ${dir} to enable CDS compilation.`); execFileSync( 'npm', @@ -244,9 +252,10 @@ process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; // refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; -console.log('Extracting the .cds.json files'); - -console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptPath}`); +console.log( + `Extracting the .cds.json files by running the 'javascript' extractor autobuild script: + ${autobuildScriptPath}` +); /** * Invoke the javascript autobuilder to index the .cds.json files only. * @@ -254,9 +263,15 @@ console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptP * process that invokes the autobuild script, otherwise the CDS autobuild.sh * script will not be invoked by the autobuild script built into the * 'javascript' extractor. + * + * IMPORTANT: The JavaScript extractor autobuild script must be invoked with + * the current working directory set to the project root directory because it + * assumes it is running from there. Without the `cwd` property set to the + * project root directory, the autobuild script will not detect the .cds.json + * files as being in the project and will not index them. */ spawnSync( autobuildScriptPath, [], - { env: process.env, shell: true, stdio: 'inherit' } + { cwd: projectRootDir, env: process.env, shell: true, stdio: 'inherit' } ); From 0b6994c9c27a293b2712fdbc1ce5aaf036954be4 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Tue, 4 Feb 2025 13:52:13 -0700 Subject: [PATCH 07/23] Another attempted fix for index-files.js cwd Changes the way the index-files.js script is invoked such that the original `--source-root` directory is used, where possible, as the current working directory for any work performed with within the extractor. Passes the original working directory as a parameter of the index-files.js script to allow that (child) script to run from the project/source root while ensuring node package dependencies are still installed in `extractors/cds/tools/node_modules`. --- extractors/cds/tools/autobuild.sh | 6 ----- extractors/cds/tools/index-files.cmd | 28 ++++++++++++++----- extractors/cds/tools/index-files.js | 30 ++++++++++++++------- extractors/cds/tools/index-files.sh | 20 +++++++++++--- extractors/javascript/tools/pre-finalize.sh | 9 +------ 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index fdf9dc225..579ce91a2 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -2,12 +2,6 @@ set -eu -# NOTE: the code below is copied in three places: -# - scripts/compile-cds.sh -# - extractors/cds/tools/autobuild.sh (here) -# - extractors/javascript/tools/pre-finalize.sh -# Any changes should be synchronized between these three places. - exec "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ --language cds \ diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd index 93db0625c..f10822602 100644 --- a/extractors/cds/tools/index-files.cmd +++ b/extractors/cds/tools/index-files.cmd @@ -19,20 +19,36 @@ if %ERRORLEVEL% neq 0 ( set "_response_file_path=%~1" set "_script_dir=%~dp0" +REM Set _cwd before changing the working directory to the script directory. +set "_cwd=%CD%" echo Checking response file for CDS files to index +REM Terminate early if the _response_file_path doesn't exist or is empty, +REM which indicates that no CDS files were selected or found. if not exist "%_response_file_path%" ( echo 'codeql database index-files --language cds' command terminated early as response file '%_response_file_path%' does not exist or is empty. This is because no CDS files were selected or found. exit /b 0 ) -REM Change to the directory of this script to ensure that npm looks up -REM the package.json file in the correct directory and installs the -REM dependencies (i.e. node_modules) relative to this directory. +REM Change to the directory of this script to ensure that npm looks up the +REM package.json file in the correct directory and installs the dependencies +REM (i.e. node_modules) relative to this directory. This is technically a +REM violation of the assumption that extractor scripts will be run with the +REM current working directory set to the root of the project source, but we +REM also need node_modules to be installed here and not in the project source +REM root, so we make a compromise of: +REM 1. changing to this script's directory; +REM 2. installing node dependencies here; +REM 3. passing the original working directory as a parameter to the +REM index-files.js script; +REM 4. expecting the index-files.js script to immediately change back to +REM the original working (aka the project source root) directory. + cd /d "%_script_dir%" && ^ -echo Installing node package dependencies and running the 'index-files.js' script && ^ -npm install --quiet --no-audit --no-fund --no-package-json && ^ -node "%_script_dir%index-files.js" "%_response_file_path%" +echo Installing node package dependencies && ^ +npm install --quiet --no-audit --no-fund && ^ +echo Running the 'index-files.js' script && ^ +node "%_script_dir%index-files.js" "%_response_file_path%" "%_cwd%" exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 71be68573..fe854e077 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -4,19 +4,29 @@ const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); -console.log('Indexing CDS files'); +// Terminate early if this script is not invoked with the required arguments. +if (process.argv.length !== 4) { + console.warn(`Usage: node index-files.js `); + process.exit(0); +} const responseFile = process.argv[2]; +const sourceRoot = process.argv[3]; + +// Force this script, and any process it spawns, to use the project (source) +// root directory as the current working directory. +process.chdir(sourceRoot); + +console.log(`Indexing CDS files in project source directory: ${sourceRoot}`); const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); -const projectRootDir = resolve(`${dirname(__filename)}/../../..`); -if (!existsSync(projectRootDir)) { - console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${projectRootDir}'.`); +if (!existsSync(sourceRoot)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${sourceRoot}'.`); process.exit(0); } @@ -265,13 +275,15 @@ console.log( * 'javascript' extractor. * * IMPORTANT: The JavaScript extractor autobuild script must be invoked with - * the current working directory set to the project root directory because it - * assumes it is running from there. Without the `cwd` property set to the - * project root directory, the autobuild script will not detect the .cds.json - * files as being in the project and will not index them. + * the current working directory set to the project (source) root directory + * because it assumes it is running from there. The JavaScript extractor will + * only find the .cds files to index (to the database) if those file are + * relative to where the autobuild script is invoked from, which should be the + * same as the `--source-root` argument passed to the `codeql database create` + * command. */ spawnSync( autobuildScriptPath, [], - { cwd: projectRootDir, env: process.env, shell: true, stdio: 'inherit' } + { cwd: sourceRoot, env: process.env, shell: true, stdio: 'inherit' } ); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 67bb815e6..dd839fb97 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -20,6 +20,7 @@ then exit 3 fi +_cwd="$PWD" _response_file_path="$1" _script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) @@ -36,11 +37,22 @@ then exit 0 fi -# Change to the directory of this script to ensure that npm looks up -# the package.json file in the correct directory and installs the -# dependencies (i.e. node_modules) relative to this directory. +# Change to the directory of this script to ensure that npm looks up the +# package.json file in the correct directory and installs the dependencies +# (i.e. node_modules) relative to this directory. This is technically a +# violation of the assumption that extractor scripts will be run with the +# current working directory set to the root of the project source, but we +# also need node_modules to be installed here and not in the project source +# root, so we make a compromise of: +# 1. changing to this script's directory; +# 2. installing node dependencies here; +# 3. passing the original working directory as a parameter to the +# index-files.js script; +# 4. expecting the index-files.js script to immediately change back to +# the original working (aka the project source root) directory. + cd "$_script_dir" && \ echo "Installing node package dependencies" && \ npm install --quiet --no-audit --no-fund && \ echo "Running the 'index-files.js' script" && \ -node "$(dirname "$0")/index-files.js" "$_response_file_path" +node "$(dirname "$0")/index-files.js" "$_response_file_path" "${_cwd}" diff --git a/extractors/javascript/tools/pre-finalize.sh b/extractors/javascript/tools/pre-finalize.sh index 770312831..d59d706da 100755 --- a/extractors/javascript/tools/pre-finalize.sh +++ b/extractors/javascript/tools/pre-finalize.sh @@ -2,14 +2,7 @@ set -eu -# NOTE: the code below is copied in three places: -# - scripts/compile-cds.sh -# - extractors/cds/tools/autobuild.sh -# - extractors/javascript/tools/pre-finalize.sh (here) -# Any changes should be synchronized between these three places. - -# Do not extract CDS files if the -# CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION # environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor From 2673f537b97a6fc5f59465a2251528d35c4bcf9a Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 07:19:10 -0700 Subject: [PATCH 08/23] Document index-files change for grandfathered package.json --- extractors/cds/tools/index-files.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index fe854e077..3a28387f4 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -119,9 +119,12 @@ try { * Nested package.json files simply cause the package to be installed in the parent * node_modules directory. * - * TODO : fix implementation or change ^comment^ to reflect the actual implementation. - * * We also ensure we skip node_modules, as we can end up in a recursive loop. + * + * NOTE: The original (sh-based) implementation of this extractor would also capture + * "grandfathered" package.json files, which are package.json files that exist in a + * parent directory of the first package.json file found. This (js-based) implementation + * removes this behavior as it seems unnecessary and potentially problematic. */ responseFiles.forEach(file => { let dir = dirname(quote([file])); From 212820a5782b2d704d8a26e8c592095491fc4abc Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 07:53:22 -0700 Subject: [PATCH 09/23] Remove shell quote from index-files logging --- extractors/cds/tools/index-files.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 3a28387f4..113eff4ec 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -199,8 +199,7 @@ responseFiles.forEach(rawCdsFilePath => { { shell: true } ); if (result.error || result.status !== 0) { - const stderrTruncated = quote( - result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n')); + const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); execFileSync( From cc99914f3f41575d574cf28694f45615ffef6090 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 12:25:54 -0700 Subject: [PATCH 10/23] index-files.js must compiles cds to file (not dir) Forces the `cds` compilier to output JSON to a file (via stdout) instead of creating an output directory. Accounts for what appears to be a change in the behavior of the `cds` (CLI) compiler, where the `-o` (or `--dest`) option now `Writes output to the given folder instead of stdout`. ``` $ npx cds --version @cap-js/asyncapi: 1.0.2 @cap-js/db-service: 1.16.0 @cap-js/openapi: 1.1.2 @cap-js/sqlite: 1.7.7 @capire/bookshop: 1.0.0 @sap/cds: 8.5.0 @sap/cds-compiler: 5.2.0 @sap/cds-dk: 8.7.1 @sap/cds-fiori: 1.2.7 @sap/cds-foss: 5.0.1 @sap/cds-mtxs: 2.5.1 @sap/eslint-plugin-cds: 3.1.2 Node.js: v20.15.0 ``` --- extractors/cds/tools/index-files.js | 77 ++++++++++++++++------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 113eff4ec..618aa95bc 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,7 @@ const { execFileSync, spawnSync } = require('child_process'); -const { existsSync, readFileSync, statSync } = require('fs'); +const { existsSync, readFileSync, statSync, writeFileSync } = require('fs'); const { arch, platform } = require('os'); -const { dirname, join, resolve } = require('path'); +const { basename, dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); // Terminate early if this script is not invoked with the required arguments. @@ -23,7 +23,7 @@ const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); +const codeqlExePath = resolve(join(quote([process.env.CODEQL_DIST]), codeqlExe)); if (!existsSync(sourceRoot)) { console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${sourceRoot}'.`); @@ -61,9 +61,9 @@ if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { } const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; -const autobuildScriptPath = join( +const autobuildScriptPath = resolve(join( CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName -); +)); /** * Terminate early if: @@ -104,7 +104,7 @@ let cdsCommand = 'cds'; try { execFileSync('cds', ['--version'], { stdio: 'ignore' }); } catch { - console.log('Pre-installing cds compiler'); + console.log('Pre-installing cds compiler ...'); // Use a JS `Set` to avoid duplicate processing of the same directory. const packageJsonDirs = new Set(); @@ -156,18 +156,18 @@ try { // Sanity check that we found at least one package.json directory from which the CDS // compiler dependencies may be installed. if (packageJsonDirs.size === 0) { - console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); + console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); exit(0); } packageJsonDirs.forEach((dir) => { - console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation.`); + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund', '@sap/cds-dk'], + ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], { cwd: dir, stdio: 'inherit' } ); - console.log(`Installing node packages into ${dir} to enable CDS compilation.`); + console.log(`Installing node packages into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', ['install', '--quiet', '--no-audit', '--no-fund'], @@ -183,7 +183,7 @@ try { cdsCommand = 'npx -y --package @sap/cds-dk cds'; } -console.log('Processing CDS files to JSON'); +console.log('Processing CDS files to JSON ...'); /** * Run the cds compile command on each file in the response files list, outputting the @@ -192,33 +192,44 @@ console.log('Processing CDS files to JSON'); responseFiles.forEach(rawCdsFilePath => { const cdsFilePath = quote([rawCdsFilePath]); const cdsJsonFilePath = `${cdsFilePath}.json`; - console.log(`Processing CDS file ${cdsFilePath} to: ${cdsJsonFilePath}`); + console.log(`Processing CDS file ${cdsFilePath} to ${cdsJsonFilePath} ...`); const result = spawnSync( cdsCommand, - ['compile', cdsFilePath, '-2', 'json', '-o', cdsJsonFilePath, '--locations'], - { shell: true } + [ + 'compile', cdsFilePath, + '-2', 'json', + '--locations', + '--log-level', 'warn' + ], + { cwd: dirname(cdsFilePath), shell: true, stdio: 'pipe' } ); - if (result.error || result.status !== 0) { - const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); - const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + if (result.error || result.status !== 0 || !result.stdout) { + const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\``; console.log(errorMessage); - execFileSync( - codeqlExePath, - [ - 'database', - 'add-diagnostic', - '--extractor-name=cds', - '--ready-for-status-page', - '--source-id=cds/compilation-failure', - '--source-name="Failure to compile one or more SAP CAP CDS files"', - '--severity=error', - `--markdown-message="${errorMessage}"`, - `--file-path="${cdsFilePath}"`, - '--', - `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` - ], - ); + try { + execFileSync( + codeqlExePath, + [ + 'database', + 'add-diagnostic', + '--extractor-name=cds', + '--ready-for-status-page', + '--source-id=cds/compilation-failure', + '--source-name="Failure to compile one or more SAP CAP CDS files"', + '--severity=error', + `--markdown-message="${errorMessage}"`, + `--file-path="${cdsFilePath}"`, + '--', + `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` + ], + ); + console.log(`Added error diagnostic for source file: ${cdsFilePath}`); + } catch (err) { + console.error(`Failed to add error diagnostic for source file=${cdsFilePath} : ${err}`); + } } + // Write the compiled JSON result to cdsJsonFilePath. + writeFileSync(cdsJsonFilePath, result.stdout); }); let excludeFilters = ''; From 5d16df050e21df7aa74f1229cdadd831d08f3cb1 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 16:33:37 -0700 Subject: [PATCH 11/23] Attempted fix for missing CDS SARIF results Avoids changing directory when running the `cds` compiler, which ensures that paths generated in .cds.json files are relative to the "source root" directory. This replicates the behavior of the original index-files.sh (shell) script, which works but is probably not correct. --- extractors/cds/tools/index-files.js | 15 +++++++++------ scripts/compile-cds.cmd | 14 ++++++++++++++ scripts/compile-cds.sh | 12 +++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 scripts/compile-cds.cmd diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 618aa95bc..a48d7988b 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,7 @@ const { execFileSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync, writeFileSync } = require('fs'); const { arch, platform } = require('os'); -const { basename, dirname, join, resolve } = require('path'); +const { dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); // Terminate early if this script is not invoked with the required arguments. @@ -161,16 +161,19 @@ try { } packageJsonDirs.forEach((dir) => { - console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); + console.log(`Installing node dependencies from ${dir}/package.json ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], + ['install', '--quiet', '--no-audit', '--no-fund'], { cwd: dir, stdio: 'inherit' } ); - console.log(`Installing node packages into ${dir} to enable CDS compilation ...`); + // Order is important here. Install dependencies from package.json in the directory, + // then install the CDS development kit (`@sap/cds-dk`) in the directory. Reversing + // this order causes cyclic install-remove behavior. + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund'], + ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], { cwd: dir, stdio: 'inherit' } ); }); @@ -201,7 +204,7 @@ responseFiles.forEach(rawCdsFilePath => { '--locations', '--log-level', 'warn' ], - { cwd: dirname(cdsFilePath), shell: true, stdio: 'pipe' } + { shell: true, stdio: 'pipe' } ); if (result.error || result.status !== 0 || !result.stdout) { const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\``; diff --git a/scripts/compile-cds.cmd b/scripts/compile-cds.cmd new file mode 100644 index 000000000..924856eb8 --- /dev/null +++ b/scripts/compile-cds.cmd @@ -0,0 +1,14 @@ +@echo off + +if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( + type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE%" +) + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/scripts/compile-cds.sh b/scripts/compile-cds.sh index 6f30a2495..a00b035dc 100755 --- a/scripts/compile-cds.sh +++ b/scripts/compile-cds.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # To use this script with the CodeQL CLI: # 1. Set the `codeql database create` `--search-path`` argument to the `extractors/` directory in this repository, e.g.: @@ -32,14 +32,16 @@ set -eu # - extractors/javascript/tools/pre-finalize.sh # Any changes should be synchronized between these three places. -# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION environment variable is set +# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor - "$CODEQL_DIST/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ + "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE" fi \ No newline at end of file From c9e02ed06fb6b017bfc544f7ff6b9e5afc8959f5 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 22 Jan 2025 21:02:09 -0700 Subject: [PATCH 12/23] WIP make the CDS extractor platform independent Adds .cmd script equivalents for autobuild.sh, index-files.sh, and pre-finalize.sh scripts -- with the (unverified) intention being that the CDS extractor should be able to run on Linux, Mac, or Windows. Migrates most of the `index-files` script logic from shell script to javascript. Adds a `package.json` file to assist with managing dependencies for the new `extractors/cds/tools/index-files.js` script. --- extractors/cds/tools/autobuild.cmd | 12 ++ extractors/cds/tools/autobuild.sh | 7 +- extractors/cds/tools/index-files.cmd | 33 ++++++ extractors/cds/tools/index-files.js | 88 ++++++++++++++ extractors/cds/tools/index-files.sh | 116 +++++-------------- extractors/cds/tools/package.json | 12 ++ extractors/javascript/tools/pre-finalize.cmd | 14 +++ extractors/javascript/tools/pre-finalize.sh | 13 ++- 8 files changed, 197 insertions(+), 98 deletions(-) create mode 100644 extractors/cds/tools/autobuild.cmd create mode 100644 extractors/cds/tools/index-files.cmd create mode 100644 extractors/cds/tools/index-files.js create mode 100644 extractors/cds/tools/package.json create mode 100644 extractors/javascript/tools/pre-finalize.cmd diff --git a/extractors/cds/tools/autobuild.cmd b/extractors/cds/tools/autobuild.cmd new file mode 100644 index 000000000..c048d8b57 --- /dev/null +++ b/extractors/cds/tools/autobuild.cmd @@ -0,0 +1,12 @@ +@echo off + +type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_CDS_WIP_DATABASE%" + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index 5396796d6..22712c917 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -eu @@ -9,9 +9,10 @@ set -eu # Any changes should be synchronized between these three places. exec "${CODEQL_DIST}/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" \ No newline at end of file diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd new file mode 100644 index 000000000..1b6816aab --- /dev/null +++ b/extractors/cds/tools/index-files.cmd @@ -0,0 +1,33 @@ +@echo off + +if "%~1"=="" ( + echo Usage: %0 ^ + exit /b 1 +) + +where node >nul 2>nul +if %ERRORLEVEL% neq 0 ( + echo node executable is required (in PATH) to run the 'index-files.js' script. Please install Node.js and try again. + exit /b 2 +) + +where npm >nul 2>nul +if %ERRORLEVEL% neq 0 ( + echo npm executable is required (in PATH) to install the dependencies for the 'index-files.js' script. + exit /b 3 +) + +set "_response_file_path=%~1" + +echo Checking response file for CDS files to index + +if not exist "%_response_file_path%" ( + echo 'codeql database index-files --language cds' command terminated early as response file '%_response_file_path%' does not exist or is empty. This is because no CDS files were selected or found. + exit /b 0 +) + +echo Installing node package dependencies and running the 'index-files.js' script +npm install --quiet --no-audit --no-fund --no-package-json && ^ +node "%~dp0index-files.js" "%_response_file_path%" + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js new file mode 100644 index 000000000..24579a608 --- /dev/null +++ b/extractors/cds/tools/index-files.js @@ -0,0 +1,88 @@ +const { existsSync, readFileSync, statSync } = require('fs'); +const { execSync, spawnSync } = require('child_process'); +const { dirname, join, resolve } = require('path'); + +console.log('Indexing CDS files'); + +const responseFile = process.argv[2]; + +const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; + +if (!existsSync(responseFile)) { + console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); + process.exit(0); +} + +if (statSync(responseFile).size === 0) { + console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); + process.exit(0); +} + +let cdsCommand = 'cds'; +try { + execSync('cds --version', { stdio: 'ignore' }); +} catch { + console.log('Pre-installing cds compiler'); + const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); + const packageJsonDirs = new Set(); + + responseFiles.forEach(file => { + let dir = dirname(file); + while (dir !== resolve(dir, '..')) { + if (existsSync(join(dir, 'package.json')) && readFileSync(join(dir, 'package.json'), 'utf-8').includes('@sap/cds')) { + packageJsonDirs.add(dir); + break; + } + dir = resolve(dir, '..'); + } + }); + + packageJsonDirs.forEach(dir => { + console.log(`Installing @sap/cds-dk into ${dir} to enable CDS compilation.`); + execSync(`${npmInstallCmdWithArgs} @sap/cds-dk`, { cwd: dir }); + execSync(npmInstallCmdWithArgs, { cwd: dir }); + }); + + cdsCommand = 'npx -y --package @sap/cds-dk cds'; +} + +console.log('Processing CDS files to JSON'); + +const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +responseFiles.forEach(cdsFile => { + const cdsJsonFile = `${cdsFile}.json`; + console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); + const result = spawnSync(cdsCommand, ['compile', cdsFile, '-2', 'json', '-o', cdsJsonFile, '--locations'], { shell: true }); + if (result.error || result.status !== 0) { + const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); + const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + console.log(errorMessage); + execSync(`${process.env.CODEQL_DIST}/codeql database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "${errorMessage}" --file-path "${cdsFile}" "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + } +}); + +if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${process.env.CODEQL_DIST}/codeql resolve extractor --language=javascript`).toString().trim(); + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; +} + +let excludeFilters = ''; +if (process.env.LGTM_INDEX_FILTERS) { + console.log(`Found $LGTM_INDEX_FILTERS already set to:\n${process.env.LGTM_INDEX_FILTERS}`); + excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS.split('\n').filter(line => line.startsWith('exclude') && !['exclude:**/*', 'exclude:**/*.*'].includes(line)).join('\n'); +} + +process.env.LGTM_INDEX_FILTERS = `exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*${excludeFilters}`; +console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); +process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; +process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; +delete process.env.LGTM_INDEX_INCLUDE; + +console.log('Extracting the cds.json files'); + +execSync(`${process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh`, { stdio: 'inherit' }); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 0d47239c9..5761a3651 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -1,104 +1,40 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu -echo "Indexing CDS files" - -# Check if the list of files is empty -response_file="$1" - -# If the response_file doesn't exist, terminate: -if [ ! -f "$response_file" ]; then - echo "codeql database index-files --language cds terminated early as response file '$response_file' does not exist. This is because no CDS files were selected or found." - exit 0 +if [ $# -ne 1 ] +then + echo "Usage: $0 " + exit 1 fi -# If the response_file is empty, terminate -if [ ! -s "$response_file" ]; then - echo "codeql database index-files --language cds terminated early as response file '$response_file' is empty. This is because no CDS files were selected or found." - exit 0 +if ! command -v node > /dev/null +then + echo "node executable is required (in PATH) to run the 'index-files.js' script. Please install Node.js and try again." + exit 2 fi -# Determine if we have the cds command available, and if not, install the cds development kit -# in the appropriate directories -if ! command -v cds &> /dev/null +if ! command -v npm > /dev/null then - echo "Pre-installing cds compiler" - - # Find all the directories containing a package.json with a dependency on @sap/cds, where - # the directory contains at least one of the files listed in the response file (e.g. the - # cds files we want to extract). - # - # We then install the cds development kit (@sap/cds-dk) in each directory, which makes the - # `cds` command usable from the npx command within that directory. - # - # Nested package.json files simply cause the package to be installed in the parent node_modules - # directory. - # - # We also ensure we skip node_modules, as we can end up in a recursive loop - find . -type d -name node_modules -prune -false -o -type f \( -iname 'package.json' \) -exec grep -ql '@sap/cds' {} \; -execdir bash -c "grep -q \"^\$(pwd)\(/\|$\)\" \"$response_file\"" \; -execdir bash -c "echo \"Installing @sap/cds-dk into \$(pwd) to enable CDS compilation.\"" \; -execdir npm install --silent @sap/cds-dk@8.6.1 \; -execdir npm install --silent \; - - # Use the npx command to dynamically install the cds development kit (@sap/cds-dk) package if necessary, - # which then provides the cds command line tool in directories which are not covered by the package.json - # install command approach above - cds_command="npx -y --package @sap/cds-dk cds" -else - cds_command="cds" + echo "npm executable is required (in PATH) to install the dependencies for the 'index-files.js' script." + exit 3 fi -echo "Processing CDS files to JSON" +_response_file_path="$1" -# Run the cds compile command on each file in the response file, outputting the compiled JSON to a file with -# the same name -while IFS= read -r cds_file; do - echo "Processing CDS file $cds_file to:" - if ! $cds_command compile "$cds_file" -2 json --locations > "$cds_file.json" 2> "$cds_file.err"; then - stderr_truncated=`grep "^\[ERROR\]" "$cds_file.err" | tail -n 4` - error_message=$'Could not compile the file '"$cds_file"$'.\nReported error(s):\n```\n'"$stderr_truncated"$'\n```' - echo "$error_message" - # Log an error diagnostic which appears on the status page - "$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "$error_message" --file-path "$cds_file" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" - fi -done < "$response_file" +echo "Checking response file for CDS files to index" -# Check if the JS extractor variables are set, and set them if not -if [ -z "${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT:-}" ]; then - # Find the JavaScript extractor location - export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$("$CODEQL_DIST/codeql" resolve extractor --language=javascript)" - - # Set the JAVASCRIPT extractor environment variables to the same as the CDS extractor environment variables - # so that the JS extractor will write to the CDS database - export CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" - export CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="$CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR="$CODEQL_EXTRACTOR_CDS_LOG_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR="$CODEQL_EXTRACTOR_CDS_SCRATCH_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="$CODEQL_EXTRACTOR_CDS_TRAP_DIR" - export CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="$CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR" -fi - -# Check if LGTM_INDEX_FILTERS is already set -# This typically happens if "paths" or "paths-ignore" are set in the LGTM.yml file -if [ -z "${LGTM_INDEX_FILTERS:-}" ]; then - exclude_filters="" -else - echo $'Found \$LGTM_INDEX_FILTERS already set to:\n'"$LGTM_INDEX_FILTERS" - # If it is set, we will try to honour the paths-ignore filter - # Split by \n and find all the entries that start with exclude, excluding "exclude:**/*" and "exclude:**/*.*" - # and then join them back together with \n - exclude_filters=$'\n'"$(echo "$LGTM_INDEX_FILTERS" | grep '^exclude' | grep -v 'exclude:\*\*/\*\|exclude:\*\*/\*\.\*')" +# Terminate early if the _response_file_path doesn't exist or is empty, +# which indicates that no CDS files were selected or found. +if [ ! -f "$_response_file_path" ] || [ ! -s "$_response_file_path" ] +then + echo "'codeql database index-files --language cds' command terminated early as response file '$_response_file_path' does not exist or is empty. This is because no CDS files were selected or found." + # Exit without error to avoid failing any calling (javascript) + # extractor, and llow the tool the report the lack of coverage + # for CDS files. + exit 0 fi -# Enable extraction of the cds.json files only -export LGTM_INDEX_FILTERS=$'exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*'"$exclude_filters" -echo "Setting \$LGTM_INDEX_FILTERS to:\n$LGTM_INDEX_FILTERS" -export LGTM_INDEX_TYPESCRIPT="NONE" -# Configure to copy over the CDS files as well, by pretending they are JSON -export LGTM_INDEX_FILETYPES=".cds:JSON" -# Ignore the LGTM_INDEX_INCLUDE variable for this purpose, as it may -# refer explicitly to .ts or .js files -unset LGTM_INDEX_INCLUDE - -echo "Extracting the cds.json files" - -# Invoke the JavaScript autobuilder to index the .cds.json files only -"$CODEQL_EXTRACTOR_JAVASCRIPT_ROOT"/tools/autobuild.sh \ No newline at end of file +echo "Installing node package dependencies and running the 'index-files.js' script" +npm install --quiet --no-audit --no-fund --no-package-json && \ +node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json new file mode 100644 index 000000000..6503344a9 --- /dev/null +++ b/extractors/cds/tools/package.json @@ -0,0 +1,12 @@ +{ + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "description": "CodeQL extractor for DB indexing of .cds.json files produced by the 'cds' compiler.", + "main": "index-files.js", + "dependencies": { + "@sap/cds-dk": "^4.0.0", + "child_process": "^1.0.2", + "fs": "^0.0.1-security", + "path": "^0.12.7" + } +} diff --git a/extractors/javascript/tools/pre-finalize.cmd b/extractors/javascript/tools/pre-finalize.cmd new file mode 100644 index 000000000..1f698488f --- /dev/null +++ b/extractors/javascript/tools/pre-finalize.cmd @@ -0,0 +1,14 @@ +@echo off + +if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( + type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE%" +) + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/javascript/tools/pre-finalize.sh b/extractors/javascript/tools/pre-finalize.sh index ad7b28f2f..770312831 100755 --- a/extractors/javascript/tools/pre-finalize.sh +++ b/extractors/javascript/tools/pre-finalize.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu @@ -8,14 +8,17 @@ set -eu # - extractors/javascript/tools/pre-finalize.sh (here) # Any changes should be synchronized between these three places. -# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION environment variable is set +# Do not extract CDS files if the +# CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor - "$CODEQL_DIST/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ + "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE" fi \ No newline at end of file From 93323119d64dc2e2a19002679415fc76e3ac9456 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Mon, 27 Jan 2025 17:46:46 -0700 Subject: [PATCH 13/23] Improve extractor script comments and file paths Adds comments in index-files.js to better reflect the documented intentions from the old version of index-files.sh script. Better explains the script magic, in places. Attempts to make the index-files.js (JavaScript) script more useful as a multi-platform solution by normalizing file paths using the path.join() function. --- extractors/cds/tools/index-files.cmd | 9 +- extractors/cds/tools/index-files.js | 89 +- extractors/cds/tools/index-files.sh | 8 +- extractors/cds/tools/package-lock.json | 3552 ++++++++++++++++++++++++ extractors/cds/tools/package.json | 1 + 5 files changed, 3646 insertions(+), 13 deletions(-) create mode 100644 extractors/cds/tools/package-lock.json diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd index 1b6816aab..93db0625c 100644 --- a/extractors/cds/tools/index-files.cmd +++ b/extractors/cds/tools/index-files.cmd @@ -18,6 +18,7 @@ if %ERRORLEVEL% neq 0 ( ) set "_response_file_path=%~1" +set "_script_dir=%~dp0" echo Checking response file for CDS files to index @@ -26,8 +27,12 @@ if not exist "%_response_file_path%" ( exit /b 0 ) -echo Installing node package dependencies and running the 'index-files.js' script +REM Change to the directory of this script to ensure that npm looks up +REM the package.json file in the correct directory and installs the +REM dependencies (i.e. node_modules) relative to this directory. +cd /d "%_script_dir%" && ^ +echo Installing node package dependencies and running the 'index-files.js' script && ^ npm install --quiet --no-audit --no-fund --no-package-json && ^ -node "%~dp0index-files.js" "%_response_file_path%" +node "%_script_dir%index-files.js" "%_response_file_path%" exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 24579a608..5542cc7b4 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,31 +1,57 @@ -const { existsSync, readFileSync, statSync } = require('fs'); const { execSync, spawnSync } = require('child_process'); +const { existsSync, readFileSync, statSync } = require('fs'); +const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); console.log('Indexing CDS files'); const responseFile = process.argv[2]; +const osPlatform = platform(); +const osPlatformArch = arch(); +console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); +const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; +const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; +const codeqlExePath = join(process.env.CODEQL_DIST, codeqlExe); const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; +// If the response file does not exist, terminate. if (!existsSync(responseFile)) { console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); process.exit(0); } -if (statSync(responseFile).size === 0) { +const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +// If the response file is empty, terminate. +if (statSync(responseFile).size === 0 || !responseFiles) { console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); process.exit(0); } +// Determine if we have the cds commands available. If not, install the cds develpment kit +// (cds-dk) in the appropriate directories and use npx to run the cds command from there. let cdsCommand = 'cds'; try { execSync('cds --version', { stdio: 'ignore' }); } catch { console.log('Pre-installing cds compiler'); - const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); - const packageJsonDirs = new Set(); + /** + * Find all the directories containing a package.json with a dependency on `@sap/cds`, + * where the directory contains at least one of the files listed in the response file + * (e.g. the cds files we want to extract). + * + * We then install the CDS development kit (`@sap/cds-dk`) in each directory, which + * makes the `cds` command usable from the npx command within that directory. + * + * Nested package.json files simply cause the package to be installed in the parent + * node_modules directory. + * + * TODO : fix implementation or change ^comment^ to reflect the actual implementation. + * + * We also ensure we skip node_modules, as we can end up in a recursive loop. + */ + const packageJsonDirs = new Set(); responseFiles.forEach(file => { let dir = dirname(file); while (dir !== resolve(dir, '..')) { @@ -43,12 +69,20 @@ try { execSync(npmInstallCmdWithArgs, { cwd: dir }); }); + /** + * Use the `npx` command to dynamically install the CDS development kit (`@sap/cds-dk`) + * package if necessary, which then provides the `cds` command line tool in directories + * which are not covered by the package.json install command approach above. + */ cdsCommand = 'npx -y --package @sap/cds-dk cds'; } console.log('Processing CDS files to JSON'); -const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); +/** + * Run the cds compile command on each file in the response files list, outputting the + * compiled JSON to a file with the same name but with a .json extension appended. + */ responseFiles.forEach(cdsFile => { const cdsJsonFile = `${cdsFile}.json`; console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); @@ -57,12 +91,17 @@ responseFiles.forEach(cdsFile => { const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); - execSync(`${process.env.CODEQL_DIST}/codeql database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "${errorMessage}" --file-path "${cdsFile}" "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + execSync(`${codeqlExePath} database add-diagnostic --extractor-name cds --ready-for-status-page --source-id=cds/compilation-failure --source-name="Failure to compile one or more SAP CAP CDS files" --severity=error --markdown-message="${errorMessage}" --file-path="${cdsFile}" -- "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); } }); +// Check if the (JavaScript) JS extractor variables are set, and set them if not. if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${process.env.CODEQL_DIST}/codeql resolve extractor --language=javascript`).toString().trim(); + // Find the JS extractor location. + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${codeqlExePath} resolve extractor --language=javascript`).toString().trim(); + // Set the JAVASCRIPT extractor environment variables to the same as the CDS + // extractor environment variables so that the JS extractor will write to the + // CDS database. process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; @@ -72,17 +111,47 @@ if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { } let excludeFilters = ''; +/** + * Check if LGTM_INDEX_FILTERS is already set. This tyically happens if either + * "paths" and/or "paths-ignore" is set in the lgtm.yml file. + */ if (process.env.LGTM_INDEX_FILTERS) { console.log(`Found $LGTM_INDEX_FILTERS already set to:\n${process.env.LGTM_INDEX_FILTERS}`); - excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS.split('\n').filter(line => line.startsWith('exclude') && !['exclude:**/*', 'exclude:**/*.*'].includes(line)).join('\n'); + const allowedExcludePatterns = [ + join('exclude:**', '*'), + join('exclude:**', '*.*'), + ]; + /** + * If it is set, we will try to honor the paths-ignore filter. + * + * Split by `\n` and find all the entries that start with exclude, with some + * exclusions allowed for supported glob patterns, and then join them back + * together with `\n`. + */ + excludeFilters = '\n' + process.env.LGTM_INDEX_FILTERS + .split('\n') + .filter(line => + line.startsWith('exclude') + && + !allowedExcludePatterns.includes(line) + ).join('\n'); } -process.env.LGTM_INDEX_FILTERS = `exclude:**/*.*\ninclude:**/*.cds.json\ninclude:**/*.cds\nexclude:**/node_modules/**/*.*${excludeFilters}`; +// Enable extraction of the .cds.json files only. +const lgtmIndexFiltersPatterns = join( + 'exclude:**', '*.*\ninclude:**', '*.cds.json\ninclude:**', '*.cds\nexclude:**', 'node_modules', '**', '*.*' +); +process.env.LGTM_INDEX_FILTERS = `${lgtmIndexFiltersPatterns}${excludeFilters}`; console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; +// Configure to copy over the .cds files as well, by pretending they are JSON. process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; +// Ignore the LGTM_INDEX_INCLUDE variable for this purpose as it may explicitly +// refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; console.log('Extracting the cds.json files'); -execSync(`${process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh`, { stdio: 'inherit' }); +// Invoke the JS autobuilder to index the .cds.json files only. +const autobuildScriptPath = join(process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName); +execSync(autobuildScriptPath, { stdio: 'inherit' }); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 5761a3651..c20e9532c 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -21,6 +21,7 @@ then fi _response_file_path="$1" +_script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) echo "Checking response file for CDS files to index" @@ -35,6 +36,11 @@ then exit 0 fi -echo "Installing node package dependencies and running the 'index-files.js' script" +# Change to the directory of this script to ensure that npm looks up +# the package.json file in the correct directory and installs the +# dependencies (i.e. node_modules) relative to this directory. +cd "$_script_dir" && \ +echo "Installing node package dependencies" && \ npm install --quiet --no-audit --no-fund --no-package-json && \ +echo "Running the 'index-files.js' script" && \ node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file diff --git a/extractors/cds/tools/package-lock.json b/extractors/cds/tools/package-lock.json new file mode 100644 index 000000000..a3edf5331 --- /dev/null +++ b/extractors/cds/tools/package-lock.json @@ -0,0 +1,3552 @@ +{ + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@advanced-security/codeql-sap-js_index-cds-files", + "version": "1.0.0", + "dependencies": { + "@sap/cds-dk": "^4.0.0", + "child_process": "^1.0.2", + "fs": "^0.0.1-security", + "os": "^0.1.2", + "path": "^0.12.7" + } + }, + "node_modules/@sap/cds-dk": { + "version": "4.9.7", + "resolved": "https://registry.npmjs.org/@sap/cds-dk/-/cds-dk-4.9.7.tgz", + "integrity": "sha512-o44qREvZYiNPJRey2dCFdQPqcc0S/S8Sh4Zde9u9Ehyf4WF844oYZjiIgeCXDK6JxzksCDCfcXnpUp51eG1fSg==", + "hasShrinkwrap": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@sap/cds": "^5.9.2", + "@sap/cds-foss": "^3", + "@sap/eslint-plugin-cds": "^2.3.3", + "axios": ">=0.21", + "connect-livereload": "^0.6.1", + "eslint": "^8", + "express": "^4.17.1", + "htmlparser2": "^7.2.0", + "livereload-js": "^3.3.1", + "md5": "^2.3.0", + "mustache": "^4.0.1", + "node-watch": ">=0.7", + "pluralize": "^8.0.0", + "ws": "^8.4.2", + "xml-js": "^1.6.11" + }, + "bin": { + "cds": "bin/cds.js", + "cds-ts": "bin/cds-ts.js" + }, + "optionalDependencies": { + "sqlite3": "npm:@mendix/sqlite3@^5.0.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@colors/colors": { + "version": "1.5.0", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@sap/cds-dk/node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@eslint/eslintrc": { + "version": "1.3.0", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "node_modules/@sap/cds-dk/node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/analytics": { + "version": "1.54.2", + "integrity": "sha512-CUoyVJ2HjPGJKwhV7EnUWR9n7c/uYpDyygy8ROzpgdT1qDVyMNWjtaaCbR4a15afIpRvJ5soLDFFLWyK6CV40g==", + "deprecated": "1.x is no longer maintained.", + "dependencies": { + "@sap-cloud-sdk/util": "^1.54.2", + "axios": "^0.26.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/analytics/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/core": { + "version": "1.54.2", + "integrity": "sha512-oF1nMYo9qAk4BDAypuAfhofxxeNKTqIroMfZAqgOb8vXxwtsZjS+bK03mptxE3cPnDhwUV0LaOeNy5foIv9oCw==", + "deprecated": "Version 1 of SAP Cloud SDK is no longer maintained. Check the upgrade guide for switching to version 2: https://sap.github.io/cloud-sdk/docs/js/guides/upgrade-to-version-2.", + "dependencies": { + "@sap-cloud-sdk/analytics": "^1.54.2", + "@sap-cloud-sdk/util": "^1.54.2", + "@sap/xsenv": "^3.0.0", + "@sap/xssec": "^3.2.7", + "@types/jsonwebtoken": "^8.3.8", + "axios": "^0.26.0", + "bignumber.js": "^9.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "jsonwebtoken": "^8.5.1", + "moment": "^2.29.0", + "opossum": "^6.0.0", + "uuid": "^8.2.0", + "voca": "^1.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/core/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/util": { + "version": "1.54.2", + "integrity": "sha512-ZC70YlHG6c2zH4OjzTtbb4s9eNJdMJEQm3KRL+u7/kN/vRJr7IrQZmidSa8RO86nnx2GZPn4zH3GTsnwAQEHuA==", + "deprecated": "1.x is no longer maintained.", + "dependencies": { + "axios": "^0.26.0", + "chalk": "^4.1.0", + "logform": "^2.2.0", + "promise.allsettled": "^1.0.4", + "voca": "^1.4.0", + "winston": "^3.3.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap-cloud-sdk/util/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds": { + "version": "5.9.6", + "integrity": "sha512-zzDoRrgAbRXUQ2n+BrDErtAyylMgcJxgWhsiJvjiZVMxAucJMPp9V+WlRsaGwSm8O6STC6NHcv9PWQ7500y9EQ==", + "dependencies": { + "@sap-cloud-sdk/core": "^1.41", + "@sap-cloud-sdk/util": "^1.41", + "@sap/cds-compiler": "^2.13.0", + "@sap/cds-foss": "^3" + }, + "bin": { + "cds": "bin/cds.js" + }, + "engines": { + "node": ">=12.18" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-compiler": { + "version": "2.15.2", + "integrity": "sha512-i4MmceDSsKX+6DieGBf3zo6EGjELNEVQLo7Wl0K2vP8gXJrtveFJQxHW6dsp/Cro7qh0C28WbBNTlPiHPjyygg==", + "hasInstallScript": true, + "dependencies": { + "antlr4": "4.8.0" + }, + "bin": { + "cdsc": "bin/cdsc.js", + "cdshi": "bin/cdshi.js", + "cdsse": "bin/cdsse.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss": { + "version": "3.1.1", + "integrity": "sha512-U4DF1VdPiqqCYmV7w9mLgRaM3F98cuJaCBRsrSp9rUCt3yAXeUnHflQhGDHmFnQRCGDStxFNx7oskDfpkD5lWw==", + "hasShrinkwrap": true, + "dependencies": { + "big.js": "6.1.1", + "fs-extra": "10.0.1", + "generic-pool": "3.8.2", + "uuid": "8.3.2", + "xmlbuilder": "15.1.1", + "yaml": "1.10.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/big.js": { + "version": "6.1.1", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/fs-extra": { + "version": "10.0.1", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/generic-pool": { + "version": "3.8.2", + "integrity": "sha1-qrTygK21Iv373F5bZNcY02g/BOk=", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/graceful-fs": { + "version": "4.2.6", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "license": "ISC" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/jsonfile": { + "version": "6.1.0", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/universalify": { + "version": "2.0.0", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/uuid": { + "version": "8.3.2", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/xmlbuilder": { + "version": "15.1.1", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/cds-foss/node_modules/yaml": { + "version": "1.10.2", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/eslint-plugin-cds": { + "version": "2.3.5", + "integrity": "sha512-wbCqc+Vwiqg8svvPB/ms5r/z5VS7ckkSPBKTPY83jftUtvMGKVWvC3yMctAaGItlE32eK5FjHKCmgNZu4qG9Tg==", + "dependencies": { + "@sap/cds": "^5.6.0", + "semver": "^7.3.4" + }, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv": { + "version": "3.3.1", + "integrity": "sha512-ESsfrlGBRZ7AF1ud+ZZ3CVfGgifPx2lo0djOpqHgzPzSkjv3h3hIGXF5ErW6gKcrwSKCPNA6j3STfbdSK5zqwA==", + "hasShrinkwrap": true, + "dependencies": { + "debug": "4.3.3", + "node-cache": "^5.1.0", + "verror": "1.10.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || ^14.0.0 || ^16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/assert-plus": { + "version": "1.0.0" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/clone": { + "version": "2.1.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/core-util-is": { + "version": "1.0.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/debug": { + "version": "4.3.3", + "dependencies": { + "ms": "2.1.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/extsprintf": { + "version": "1.4.1" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/ms": { + "version": "2.1.2" + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/node-cache": { + "version": "5.1.2", + "dependencies": { + "clone": "2.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xsenv/node_modules/verror": { + "version": "1.10.0", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xssec": { + "version": "3.2.13", + "integrity": "sha512-F/hFDDf00y/n1ngbnHS9yTcyZqN88q3tMWbG2/AmJYz0PvBGgfmkgkcKxVq+D+aIQmtBJpWZ43H9Pu53MOcJfQ==", + "dependencies": { + "axios": "^0.26.0", + "debug": "4.3.2", + "jsonwebtoken": "^8.5.1", + "lru-cache": "6.0.0", + "node-rsa": "^1.1.1", + "valid-url": "1.0.9" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/@sap/xssec/node_modules/axios": { + "version": "0.26.1", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/@tootallnate/once": { + "version": "2.0.0", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sap/cds-dk/node_modules/@types/jsonwebtoken": { + "version": "8.5.8", + "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/@types/node": { + "version": "17.0.41", + "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==" + }, + "node_modules/@sap/cds-dk/node_modules/abbrev": { + "version": "1.1.1", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/accepts": { + "version": "1.3.8", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/acorn": { + "version": "8.7.1", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/acorn-jsx": { + "version": "5.3.2", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/agent-base": { + "version": "6.0.2", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ajv": { + "version": "6.12.6", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@sap/cds-dk/node_modules/ansi-regex": { + "version": "5.0.1", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/ansi-styles": { + "version": "4.3.0", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/antlr4": { + "version": "4.8.0", + "integrity": "sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==" + }, + "node_modules/@sap/cds-dk/node_modules/aproba": { + "version": "2.0.0", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/are-we-there-yet": { + "version": "2.0.0", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/argparse": { + "version": "2.0.1", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@sap/cds-dk/node_modules/array-flatten": { + "version": "1.1.1", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/@sap/cds-dk/node_modules/array.prototype.map": { + "version": "1.0.4", + "integrity": "sha512-Qds9QnX7A0qISY7JT5WuJO0NJPE9CMlC6JzHQfhpqAAQQzufVRoeH7EzUY5GcPTx72voG8LV/5eo+b8Qi8hmhA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/asn1": { + "version": "0.2.6", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/assert-plus": { + "version": "1.0.0", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/async": { + "version": "3.2.4", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/@sap/cds-dk/node_modules/asynckit": { + "version": "0.4.0", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/@sap/cds-dk/node_modules/aws-sign2": { + "version": "0.7.0", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/aws4": { + "version": "1.11.0", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/axios": { + "version": "0.27.2", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/balanced-match": { + "version": "1.0.2", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/@sap/cds-dk/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/bignumber.js": { + "version": "9.0.2", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser": { + "version": "1.20.0", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "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.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/brace-expansion": { + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/@sap/cds-dk/node_modules/bytes": { + "version": "3.1.2", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/call-bind": { + "version": "1.0.2", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/callsites": { + "version": "3.1.0", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/caseless": { + "version": "0.12.0", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/chalk": { + "version": "4.1.2", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/charenc": { + "version": "0.0.2", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/chownr": { + "version": "2.0.0", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/code-point-at": { + "version": "1.1.0", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color": { + "version": "3.2.1", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-convert": { + "version": "2.0.1", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-name": { + "version": "1.1.4", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@sap/cds-dk/node_modules/color-string": { + "version": "1.9.1", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/@sap/cds-dk/node_modules/color-support": { + "version": "1.1.3", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@sap/cds-dk/node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@sap/cds-dk/node_modules/colorspace": { + "version": "1.1.4", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/combined-stream": { + "version": "1.0.8", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/concat-map": { + "version": "0.0.1", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/@sap/cds-dk/node_modules/connect-livereload": { + "version": "0.6.1", + "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/console-control-strings": { + "version": "1.1.0", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/content-disposition": { + "version": "0.5.4", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/content-type": { + "version": "1.0.4", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/cookie": { + "version": "0.5.0", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/cookie-signature": { + "version": "1.0.6", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/@sap/cds-dk/node_modules/core-util-is": { + "version": "1.0.2", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/cross-spawn": { + "version": "7.0.3", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/crypt": { + "version": "0.0.2", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/dashdash": { + "version": "1.14.1", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/debug": { + "version": "4.3.2", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/deep-is": { + "version": "0.1.4", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/@sap/cds-dk/node_modules/define-properties": { + "version": "1.1.4", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/delayed-stream": { + "version": "1.0.0", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/delegates": { + "version": "1.0.0", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/depd": { + "version": "2.0.0", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/destroy": { + "version": "1.2.0", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/@sap/cds-dk/node_modules/detect-libc": { + "version": "2.0.1", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/doctrine": { + "version": "3.0.0", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/dom-serializer": { + "version": "1.4.1", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/domelementtype": { + "version": "2.3.0", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/@sap/cds-dk/node_modules/domhandler": { + "version": "4.3.1", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/domutils": { + "version": "2.8.0", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/ecc-jsbn": { + "version": "0.1.2", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/ee-first": { + "version": "1.1.1", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/@sap/cds-dk/node_modules/emoji-regex": { + "version": "8.0.0", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/enabled": { + "version": "2.0.0", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "node_modules/@sap/cds-dk/node_modules/encodeurl": { + "version": "1.0.2", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/entities": { + "version": "3.0.1", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@sap/cds-dk/node_modules/env-paths": { + "version": "2.2.1", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-abstract": { + "version": "1.20.1", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/@sap/cds-dk/node_modules/es-get-iterator": { + "version": "1.1.2", + "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/es-to-primitive": { + "version": "1.2.1", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/escape-html": { + "version": "1.0.3", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/@sap/cds-dk/node_modules/escape-string-regexp": { + "version": "4.0.0", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint": { + "version": "8.17.0", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "dependencies": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-scope": { + "version": "7.1.1", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-utils": { + "version": "3.0.0", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/espree": { + "version": "9.3.2", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dependencies": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/esquery": { + "version": "1.4.0", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/esrecurse": { + "version": "4.3.0", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/estraverse": { + "version": "5.3.0", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/esutils": { + "version": "2.0.3", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/etag": { + "version": "1.8.1", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/express": { + "version": "4.18.1", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "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.10.3", + "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" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/extend": { + "version": "3.0.2", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/extsprintf": { + "version": "1.3.0", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/fast-deep-equal": { + "version": "3.1.3", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/@sap/cds-dk/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/@sap/cds-dk/node_modules/fast-levenshtein": { + "version": "2.0.6", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/@sap/cds-dk/node_modules/fecha": { + "version": "4.2.3", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "node_modules/@sap/cds-dk/node_modules/file-entry-cache": { + "version": "6.0.1", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/finalhandler": { + "version": "1.2.0", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "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/@sap/cds-dk/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/flat-cache": { + "version": "3.0.4", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/flatted": { + "version": "3.2.5", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + }, + "node_modules/@sap/cds-dk/node_modules/fn.name": { + "version": "1.1.0", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "node_modules/@sap/cds-dk/node_modules/follow-redirects": { + "version": "1.15.1", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/forever-agent": { + "version": "0.6.1", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/form-data": { + "version": "4.0.0", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/forwarded": { + "version": "0.2.0", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/fresh": { + "version": "0.5.2", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/fs-minipass": { + "version": "2.1.0", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/fs.realpath": { + "version": "1.0.0", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/@sap/cds-dk/node_modules/function-bind": { + "version": "1.1.1", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/@sap/cds-dk/node_modules/function.prototype.name": { + "version": "1.1.5", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/functional-red-black-tree": { + "version": "1.0.1", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, + "node_modules/@sap/cds-dk/node_modules/functions-have-names": { + "version": "1.2.3", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/gauge": { + "version": "3.0.2", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/get-intrinsic": { + "version": "1.1.1", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/get-symbol-description": { + "version": "1.0.0", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/getpass": { + "version": "0.1.7", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/glob": { + "version": "7.2.3", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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/@sap/cds-dk/node_modules/glob-parent": { + "version": "6.0.2", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/globals": { + "version": "13.15.0", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/graceful-fs": { + "version": "4.2.10", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/har-schema": { + "version": "2.0.0", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/har-validator": { + "version": "5.1.5", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "optional": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/has": { + "version": "1.0.3", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-bigints": { + "version": "1.0.2", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-flag": { + "version": "4.0.0", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-property-descriptors": { + "version": "1.0.0", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-symbols": { + "version": "1.0.3", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-tostringtag": { + "version": "1.0.0", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/has-unicode": { + "version": "2.0.1", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/htmlparser2": { + "version": "7.2.0", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/http-errors": { + "version": "2.0.0", + "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/@sap/cds-dk/node_modules/http-proxy-agent": { + "version": "5.0.0", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/http-signature": { + "version": "1.2.0", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/@sap/cds-dk/node_modules/https-proxy-agent": { + "version": "5.0.1", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/ignore": { + "version": "5.2.0", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/import-fresh": { + "version": "3.3.0", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/imurmurhash": { + "version": "0.1.4", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/@sap/cds-dk/node_modules/inflight": { + "version": "1.0.6", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/@sap/cds-dk/node_modules/inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/@sap/cds-dk/node_modules/internal-slot": { + "version": "1.0.3", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/ipaddr.js": { + "version": "1.9.1", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-arguments": { + "version": "1.1.1", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-bigint": { + "version": "1.0.4", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-boolean-object": { + "version": "1.1.2", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-buffer": { + "version": "1.1.6", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/@sap/cds-dk/node_modules/is-callable": { + "version": "1.2.4", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-date-object": { + "version": "1.0.5", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-extglob": { + "version": "2.1.1", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-glob": { + "version": "4.0.3", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-map": { + "version": "2.0.2", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-negative-zero": { + "version": "2.0.2", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-number-object": { + "version": "1.0.7", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-regex": { + "version": "1.1.4", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-set": { + "version": "2.0.2", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-stream": { + "version": "2.0.1", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-string": { + "version": "1.0.7", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-symbol": { + "version": "1.0.4", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/is-typedarray": { + "version": "1.0.0", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/is-weakref": { + "version": "1.0.2", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/isarray": { + "version": "2.0.5", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/@sap/cds-dk/node_modules/isexe": { + "version": "2.0.0", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/@sap/cds-dk/node_modules/isstream": { + "version": "0.1.2", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/iterate-iterator": { + "version": "1.0.2", + "integrity": "sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/iterate-value": { + "version": "1.0.2", + "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "dependencies": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/js-yaml": { + "version": "4.1.0", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsbn": { + "version": "0.1.1", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/json-schema": { + "version": "0.4.0", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/json-schema-traverse": { + "version": "0.4.1", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/@sap/cds-dk/node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/@sap/cds-dk/node_modules/json-stringify-safe": { + "version": "5.0.1", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/jsonwebtoken": { + "version": "8.5.1", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "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": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@sap/cds-dk/node_modules/jsprim": { + "version": "1.4.2", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/jwa": { + "version": "1.4.1", + "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/@sap/cds-dk/node_modules/jws": { + "version": "3.2.2", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/kuler": { + "version": "2.0.0", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "node_modules/@sap/cds-dk/node_modules/levn": { + "version": "0.4.1", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/livereload-js": { + "version": "3.4.0", + "integrity": "sha512-F/pz9ZZP+R+arY94cECTZco7PXgBXyL+KVWUPZq8AQE9TOu14GV6fYeKOviv02JCvFa4Oi3Rs1hYEpfeajc+ow==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.includes": { + "version": "4.3.0", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isboolean": { + "version": "3.0.3", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isinteger": { + "version": "4.0.4", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isnumber": { + "version": "3.0.3", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isplainobject": { + "version": "4.0.6", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.isstring": { + "version": "4.0.1", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.merge": { + "version": "4.6.2", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/@sap/cds-dk/node_modules/lodash.once": { + "version": "4.1.1", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/@sap/cds-dk/node_modules/logform": { + "version": "2.4.0", + "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", + "dependencies": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/lru-cache": { + "version": "6.0.0", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/make-dir": { + "version": "3.1.0", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/md5": { + "version": "2.3.0", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/media-typer": { + "version": "0.3.0", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/merge-descriptors": { + "version": "1.0.1", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/@sap/cds-dk/node_modules/methods": { + "version": "1.1.2", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime": { + "version": "1.6.0", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime-db": { + "version": "1.52.0", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/mime-types": { + "version": "2.1.35", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/minimatch": { + "version": "3.1.2", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/minipass": { + "version": "3.1.6", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/minizlib": { + "version": "2.1.2", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/mkdirp": { + "version": "1.0.4", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/moment": { + "version": "2.29.3", + "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/ms": { + "version": "2.1.2", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@sap/cds-dk/node_modules/mustache": { + "version": "4.2.0", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/@sap/cds-dk/node_modules/natural-compare": { + "version": "1.4.0", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/@sap/cds-dk/node_modules/negotiator": { + "version": "0.6.3", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-addon-api": { + "version": "4.3.0", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch": { + "version": "2.6.7", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp": { + "version": "7.1.2", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/ansi-regex": { + "version": "2.1.1", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/aproba": { + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "1.1.7", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/gauge": { + "version": "2.7.4", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/isarray": { + "version": "1.0.0", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/npmlog": { + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/readable-stream": { + "version": "2.3.7", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/string_decoder": { + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/string-width": { + "version": "1.0.2", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-gyp/node_modules/strip-ansi": { + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-rsa": { + "version": "1.1.1", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "dependencies": { + "asn1": "^0.2.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/node-watch": { + "version": "0.7.3", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/nopt": { + "version": "5.0.0", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/npmlog": { + "version": "5.0.1", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/number-is-nan": { + "version": "1.0.1", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/oauth-sign": { + "version": "0.9.0", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-inspect": { + "version": "1.12.2", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/object-keys": { + "version": "1.1.1", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@sap/cds-dk/node_modules/object.assign": { + "version": "4.1.2", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/on-finished": { + "version": "2.4.1", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/once": { + "version": "1.4.0", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/@sap/cds-dk/node_modules/one-time": { + "version": "1.0.0", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/@sap/cds-dk/node_modules/opossum": { + "version": "6.3.0", + "integrity": "sha512-youR7pMTpgnbPJEPruM8Ku1WKUXnjmsK99GC5fkGFrOK8jduY1hvMiooUa3QZg6Xdso03skr37q6Evpt9PZ2cA==", + "engines": { + "node": "^16 || ^14 || ^12" + } + }, + "node_modules/@sap/cds-dk/node_modules/optionator": { + "version": "0.9.1", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/parent-module": { + "version": "1.0.1", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/parseurl": { + "version": "1.3.3", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-is-absolute": { + "version": "1.0.1", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-key": { + "version": "3.1.1", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/path-to-regexp": { + "version": "0.1.7", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/@sap/cds-dk/node_modules/performance-now": { + "version": "2.1.0", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/pluralize": { + "version": "8.0.0", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/prelude-ls": { + "version": "1.2.1", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/process-nextick-args": { + "version": "2.0.1", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/promise.allsettled": { + "version": "1.0.5", + "integrity": "sha512-tVDqeZPoBC0SlzJHzWGZ2NKAguVq2oiYj7gbggbiTvH2itHohijTp7njOUA0aQ/nl+0lr/r6egmhoYu63UZ/pQ==", + "dependencies": { + "array.prototype.map": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "iterate-value": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/proxy-addr": { + "version": "2.0.7", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@sap/cds-dk/node_modules/psl": { + "version": "1.8.0", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/punycode": { + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sap/cds-dk/node_modules/qs": { + "version": "6.10.3", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/range-parser": { + "version": "1.2.1", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/raw-body": { + "version": "2.5.1", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "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/@sap/cds-dk/node_modules/readable-stream": { + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/regexpp": { + "version": "3.2.0", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/@sap/cds-dk/node_modules/request": { + "version": "2.88.2", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/qs": { + "version": "6.5.3", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/resolve-from": { + "version": "4.0.0", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@sap/cds-dk/node_modules/rimraf": { + "version": "3.0.2", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sap/cds-dk/node_modules/safe-buffer": { + "version": "5.2.1", + "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/@sap/cds-dk/node_modules/safe-stable-stringify": { + "version": "2.3.1", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/@sap/cds-dk/node_modules/sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/@sap/cds-dk/node_modules/semver": { + "version": "7.3.7", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sap/cds-dk/node_modules/send": { + "version": "0.18.0", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "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/@sap/cds-dk/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@sap/cds-dk/node_modules/send/node_modules/ms": { + "version": "2.1.3", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@sap/cds-dk/node_modules/serve-static": { + "version": "1.15.0", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/set-blocking": { + "version": "2.0.0", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/setprototypeof": { + "version": "1.2.0", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/@sap/cds-dk/node_modules/shebang-command": { + "version": "2.0.0", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/shebang-regex": { + "version": "3.0.0", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/side-channel": { + "version": "1.0.4", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/signal-exit": { + "version": "3.0.7", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/simple-swizzle": { + "version": "0.2.2", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/@sap/cds-dk/node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/@sap/cds-dk/node_modules/sqlite3": { + "name": "@mendix/sqlite3", + "version": "5.0.3", + "integrity": "sha512-GqQy6UZsr6pYZZjShmwy51VsPVROC88wDluQTCkWz9Cq/Y76ci2CJ4q2fjqEfiP2dQTAn4WxB1Ui2IZ5Z7/+Ow==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0" + }, + "optionalDependencies": { + "node-gyp": "7.x" + }, + "peerDependencies": { + "node-gyp": "7.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/sshpk": { + "version": "1.17.0", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/stack-trace": { + "version": "0.0.10", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/statuses": { + "version": "2.0.1", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/string_decoder": { + "version": "1.3.0", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/string-width": { + "version": "4.2.3", + "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/@sap/cds-dk/node_modules/string.prototype.trimend": { + "version": "1.0.5", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/strip-ansi": { + "version": "6.0.1", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/strip-json-comments": { + "version": "3.1.1", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/supports-color": { + "version": "7.2.0", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sap/cds-dk/node_modules/tar": { + "version": "6.1.11", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sap/cds-dk/node_modules/text-hex": { + "version": "1.0.0", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "node_modules/@sap/cds-dk/node_modules/text-table": { + "version": "0.2.0", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "node_modules/@sap/cds-dk/node_modules/toidentifier": { + "version": "1.0.1", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/triple-beam": { + "version": "1.3.0", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "node_modules/@sap/cds-dk/node_modules/tunnel-agent": { + "version": "0.6.0", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@sap/cds-dk/node_modules/tweetnacl": { + "version": "0.14.5", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "node_modules/@sap/cds-dk/node_modules/type-check": { + "version": "0.4.0", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/type-fest": { + "version": "0.20.2", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sap/cds-dk/node_modules/type-is": { + "version": "1.6.18", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sap/cds-dk/node_modules/unbox-primitive": { + "version": "1.0.2", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/unpipe": { + "version": "1.0.0", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/uri-js": { + "version": "4.4.1", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/@sap/cds-dk/node_modules/utils-merge": { + "version": "1.0.1", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/uuid": { + "version": "8.3.2", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@sap/cds-dk/node_modules/v8-compile-cache": { + "version": "2.3.0", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "node_modules/@sap/cds-dk/node_modules/valid-url": { + "version": "1.0.9", + "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" + }, + "node_modules/@sap/cds-dk/node_modules/vary": { + "version": "1.1.2", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@sap/cds-dk/node_modules/verror": { + "version": "1.10.0", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/voca": { + "version": "1.4.0", + "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==" + }, + "node_modules/@sap/cds-dk/node_modules/which": { + "version": "2.0.2", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sap/cds-dk/node_modules/which-boxed-primitive": { + "version": "1.0.2", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@sap/cds-dk/node_modules/wide-align": { + "version": "1.1.5", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/@sap/cds-dk/node_modules/winston": { + "version": "3.7.2", + "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==", + "dependencies": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/winston-transport": { + "version": "4.5.0", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/word-wrap": { + "version": "1.2.3", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@sap/cds-dk/node_modules/wrappy": { + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/@sap/cds-dk/node_modules/ws": { + "version": "8.7.0", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@sap/cds-dk/node_modules/xml-js": { + "version": "1.6.11", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/@sap/cds-dk/node_modules/yallist": { + "version": "4.0.0", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==", + "license": "ISC" + }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==", + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/os": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", + "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==", + "license": "MIT" + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "license": "MIT", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + } + } +} diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json index 6503344a9..caa288d17 100644 --- a/extractors/cds/tools/package.json +++ b/extractors/cds/tools/package.json @@ -7,6 +7,7 @@ "@sap/cds-dk": "^4.0.0", "child_process": "^1.0.2", "fs": "^0.0.1-security", + "os": "^0.1.2", "path": "^0.12.7" } } From a9b987a7f9b463cbbe71842a22a0d1e9e2e7a0bd Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Mon, 27 Jan 2025 17:53:11 -0700 Subject: [PATCH 14/23] Add requested comment to extractor.js responsFiles --- extractors/cds/tools/index-files.js | 1 + 1 file changed, 1 insertion(+) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 5542cc7b4..7d9c198d8 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -21,6 +21,7 @@ if (!existsSync(responseFile)) { process.exit(0); } +// Read the response file and split it into lines, removing (filter(Boolean)) empty lines. const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); // If the response file is empty, terminate. if (statSync(responseFile).size === 0 || !responseFiles) { From 5a49a25eac73159f503ab2622be9938692a5cb68 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 29 Jan 2025 16:17:44 -0700 Subject: [PATCH 15/23] WIP fixes for CDS extractor rewrite First attempt at fixing `Indirect uncontrolled command line` code scanning alerts for the `index-fils.js` script. Improves error handling and improves the reliability and security of code that creates child (exec/spawn) processes. Attempts to improve the passing of env vars to child processes, especially for the `LGTM_INDEX_FILTERS` env var. WIP because CDS extractor invocation is still failing to identify .cds.json files. Possible problem in the way env vars are passed within the javascript extractor autobuilder shell script (to the JVM launched by the javascript extractor autobuilder). --- extractors/cds/tools/autobuild.cmd | 4 +- extractors/cds/tools/autobuild.sh | 2 +- extractors/cds/tools/index-files.js | 167 ++++++++++++++----- extractors/cds/tools/index-files.sh | 4 +- extractors/cds/tools/package-lock.json | 15 +- extractors/cds/tools/package.json | 3 +- extractors/javascript/tools/pre-finalize.cmd | 2 +- 7 files changed, 151 insertions(+), 46 deletions(-) diff --git a/extractors/cds/tools/autobuild.cmd b/extractors/cds/tools/autobuild.cmd index c048d8b57..d5143ae00 100644 --- a/extractors/cds/tools/autobuild.cmd +++ b/extractors/cds/tools/autobuild.cmd @@ -1,6 +1,6 @@ @echo off -type NUL && "%CODEQL_DIST%\codeql" database index-files ^ +type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ --include-extension=.cds ^ --language cds ^ --prune **\node_modules\**\* ^ @@ -9,4 +9,4 @@ type NUL && "%CODEQL_DIST%\codeql" database index-files ^ -- ^ "%CODEQL_EXTRACTOR_CDS_WIP_DATABASE%" -exit /b %ERRORLEVEL% \ No newline at end of file +exit /b %ERRORLEVEL% diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index 22712c917..fdf9dc225 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -15,4 +15,4 @@ exec "${CODEQL_DIST}/codeql" database index-files \ --prune **/.eslint/**/* \ --total-size-limit=10m \ -- \ - "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" \ No newline at end of file + "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE" diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 7d9c198d8..783ce2bdf 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,8 @@ -const { execSync, spawnSync } = require('child_process'); +const { execFileSync, execSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync } = require('fs'); const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); +const { quote } = require('shell-quote'); console.log('Indexing CDS files'); @@ -11,21 +12,42 @@ const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; +const autobuildScriptPath = join( + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName +); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(process.env.CODEQL_DIST, codeqlExe); -const npmInstallCmdWithArgs = 'npm install --quiet --no-audit --no-fund --no-package-lock'; +const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); -// If the response file does not exist, terminate. +/** + * Terminate early if: + * - the javascript extractor autobuild script does not exist; or + * - the codeql executable does not exist; or + * - the input responseFile does not exist; or + * - the input responseFile is empty or could not be parsed as a list of file paths. + */ +if (!existsSync(autobuildScriptPath)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as autobuild script '${autobuildScriptPath}' does not exist.`); + process.exit(0); +} +if (!existsSync(codeqlExePath)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as codeql executable '${codeqlExePath}' does not exist.`); + process.exit(0); +} if (!existsSync(responseFile)) { - console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' does not exist. This is because no CDS files were selected or found.`); process.exit(0); } -// Read the response file and split it into lines, removing (filter(Boolean)) empty lines. -const responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); -// If the response file is empty, terminate. -if (statSync(responseFile).size === 0 || !responseFiles) { - console.log(`'codeql database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); +let responseFiles = []; +try { + // Read the response file and split it into lines, removing (filter(Boolean)) empty lines. + responseFiles = readFileSync(responseFile, 'utf-8').split('\n').filter(Boolean); + if (statSync(responseFile).size === 0 || responseFiles.length === 0) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' is empty. This is because no CDS files were selected or found.`); + process.exit(0); + } +} catch (err) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early as response file '${responseFile}' could not be read due to an error: ${err}`); process.exit(0); } @@ -33,10 +55,12 @@ if (statSync(responseFile).size === 0 || !responseFiles) { // (cds-dk) in the appropriate directories and use npx to run the cds command from there. let cdsCommand = 'cds'; try { - execSync('cds --version', { stdio: 'ignore' }); + execFileSync('cds', ['--version'], { stdio: 'ignore' }); } catch { console.log('Pre-installing cds compiler'); + // Use a JS `Set` to avoid duplicate processing of the same directory. + const packageJsonDirs = new Set(); /** * Find all the directories containing a package.json with a dependency on `@sap/cds`, * where the directory contains at least one of the files listed in the response file @@ -52,22 +76,51 @@ try { * * We also ensure we skip node_modules, as we can end up in a recursive loop. */ - const packageJsonDirs = new Set(); responseFiles.forEach(file => { - let dir = dirname(file); + let dir = dirname(quote([file])); while (dir !== resolve(dir, '..')) { - if (existsSync(join(dir, 'package.json')) && readFileSync(join(dir, 'package.json'), 'utf-8').includes('@sap/cds')) { - packageJsonDirs.add(dir); - break; + const packageJsonPath = join(dir, 'package.json'); + if (existsSync(packageJsonPath)) { + const rawData = readFileSync(packageJsonPath, 'utf-8'); + const packageJsonData = JSON.parse(rawData); + // Check if the 'name' and 'dependencies' properties are present in the + // package.json file at packageJsonPath. + if ( + packageJsonData.name && + packageJsonData.dependencies && + typeof packageJsonData.dependencies === 'object' + ) { + const dependencyNames = Object.keys(packageJsonData.dependencies); + if ( + dependencyNames.includes('@sap/cds') + && + dependencyNames.includes('@sap/cds-dk') + ) { + packageJsonDirs.add(dir); + break; + } + } } + // Move up one directory level and try again to find a package.json file + // for the response file. dir = resolve(dir, '..'); } }); - packageJsonDirs.forEach(dir => { - console.log(`Installing @sap/cds-dk into ${dir} to enable CDS compilation.`); - execSync(`${npmInstallCmdWithArgs} @sap/cds-dk`, { cwd: dir }); - execSync(npmInstallCmdWithArgs, { cwd: dir }); + // TODO : revise this check as the equality is probably not guaranteed. + if (responseFiles.length !== packageJsonDirs.length) { + console.warn( + `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` + ); + } + + packageJsonDirs.forEach((dir) => { + console.log(`Installing node packages into ${dir} to enable CDS compilation.`); + execFileSync( + 'npm', + ['install', '--quiet', '--no-audit', '--no-fund'], + { cwd: dir, stdio: 'inherit' } + ); }); /** @@ -84,22 +137,46 @@ console.log('Processing CDS files to JSON'); * Run the cds compile command on each file in the response files list, outputting the * compiled JSON to a file with the same name but with a .json extension appended. */ -responseFiles.forEach(cdsFile => { - const cdsJsonFile = `${cdsFile}.json`; - console.log(`Processing CDS file ${cdsFile} to: ${cdsJsonFile}`); - const result = spawnSync(cdsCommand, ['compile', cdsFile, '-2', 'json', '-o', cdsJsonFile, '--locations'], { shell: true }); +responseFiles.forEach(rawCdsFilePath => { + const cdsFilePath = quote([rawCdsFilePath]); + const cdsJsonFilePath = `${cdsFilePath}.json`; + console.log(`Processing CDS file ${cdsFilePath} to: ${cdsJsonFilePath}`); + const result = spawnSync( + cdsCommand, + ['compile', cdsFilePath, '-2', 'json', '-o', cdsJsonFilePath, '--locations'], + { shell: true } + ); if (result.error || result.status !== 0) { - const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); - const errorMessage = `Could not compile the file ${cdsFile}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + const stderrTruncated = quote( + result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n')); + const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); - execSync(`${codeqlExePath} database add-diagnostic --extractor-name cds --ready-for-status-page --source-id=cds/compilation-failure --source-name="Failure to compile one or more SAP CAP CDS files" --severity=error --markdown-message="${errorMessage}" --file-path="${cdsFile}" -- "${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}"`); + execFileSync( + codeqlExePath, + [ + 'database', + 'add-diagnostic', + '--extractor-name=cds', + '--ready-for-status-page', + '--source-id=cds/compilation-failure', + '--source-name="Failure to compile one or more SAP CAP CDS files"', + '--severity=error', + `--markdown-message="${errorMessage}"`, + `--file-path="${cdsFilePath}"`, + '--', + `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` + ], + ); } }); // Check if the (JavaScript) JS extractor variables are set, and set them if not. if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { // Find the JS extractor location. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execSync(`${codeqlExePath} resolve extractor --language=javascript`).toString().trim(); + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( + codeqlExePath, + ['resolve', 'extractor', '--language=javascript'] + ).toString().trim(); // Set the JAVASCRIPT extractor environment variables to the same as the CDS // extractor environment variables so that the JS extractor will write to the // CDS database. @@ -134,16 +211,19 @@ if (process.env.LGTM_INDEX_FILTERS) { .filter(line => line.startsWith('exclude') && - !allowedExcludePatterns.includes(line) + !allowedExcludePatterns.some(pattern => line.includes(pattern)) ).join('\n'); } // Enable extraction of the .cds.json files only. -const lgtmIndexFiltersPatterns = join( - 'exclude:**', '*.*\ninclude:**', '*.cds.json\ninclude:**', '*.cds\nexclude:**', 'node_modules', '**', '*.*' -); -process.env.LGTM_INDEX_FILTERS = `${lgtmIndexFiltersPatterns}${excludeFilters}`; -console.log(`Setting $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); +const lgtmIndexFiltersPatterns = [ + join('exclude:**', '*.*'), + join('include:**', '*.cds.json'), + join('include:**', '*.cds'), + join('exclude:**', 'node_modules', '**', '*.*') +].join('\n');; +process.env.LGTM_INDEX_FILTERS = lgtmIndexFiltersPatterns + excludeFilters; +console.log(`Set $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; // Configure to copy over the .cds files as well, by pretending they are JSON. process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; @@ -151,8 +231,19 @@ process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; // refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; -console.log('Extracting the cds.json files'); +console.log('Extracting the .cds.json files'); -// Invoke the JS autobuilder to index the .cds.json files only. -const autobuildScriptPath = join(process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName); -execSync(autobuildScriptPath, { stdio: 'inherit' }); +console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptPath}`); +/** + * Invoke the javascript autobuilder to index the .cds.json files only. + * + * Environment variables must be passed from this script's process to the + * process that invokes the autobuild script, otherwise the CDS autobuild.sh + * script will not be invoked by the autobuild script built into the + * 'javascript' extractor. + */ +spawnSync( + autobuildScriptPath, + [], + { env: process.env, shell: true, stdio: 'inherit' } +); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index c20e9532c..67bb815e6 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -41,6 +41,6 @@ fi # dependencies (i.e. node_modules) relative to this directory. cd "$_script_dir" && \ echo "Installing node package dependencies" && \ -npm install --quiet --no-audit --no-fund --no-package-json && \ +npm install --quiet --no-audit --no-fund && \ echo "Running the 'index-files.js' script" && \ -node "$(dirname "$0")/index-files.js" "$_response_file_path" \ No newline at end of file +node "$(dirname "$0")/index-files.js" "$_response_file_path" diff --git a/extractors/cds/tools/package-lock.json b/extractors/cds/tools/package-lock.json index a3edf5331..436181e58 100644 --- a/extractors/cds/tools/package-lock.json +++ b/extractors/cds/tools/package-lock.json @@ -12,7 +12,8 @@ "child_process": "^1.0.2", "fs": "^0.0.1-security", "os": "^0.1.2", - "path": "^0.12.7" + "path": "^0.12.7", + "shell-quote": "^1.8.2" } }, "node_modules/@sap/cds-dk": { @@ -3539,6 +3540,18 @@ "node": ">= 0.6.0" } }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", diff --git a/extractors/cds/tools/package.json b/extractors/cds/tools/package.json index caa288d17..a1c4cd78b 100644 --- a/extractors/cds/tools/package.json +++ b/extractors/cds/tools/package.json @@ -8,6 +8,7 @@ "child_process": "^1.0.2", "fs": "^0.0.1-security", "os": "^0.1.2", - "path": "^0.12.7" + "path": "^0.12.7", + "shell-quote": "^1.8.2" } } diff --git a/extractors/javascript/tools/pre-finalize.cmd b/extractors/javascript/tools/pre-finalize.cmd index 1f698488f..924856eb8 100644 --- a/extractors/javascript/tools/pre-finalize.cmd +++ b/extractors/javascript/tools/pre-finalize.cmd @@ -1,7 +1,7 @@ @echo off if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( - type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ --include-extension=.cds ^ --language cds ^ --prune **\node_modules\**\* ^ From caaadbba570a67c6f885b8a11d65a82d7e4d0fe1 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 29 Jan 2025 19:21:25 -0700 Subject: [PATCH 16/23] Fix CDS extractor JS undefined var --- extractors/cds/tools/index-files.js | 57 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 783ce2bdf..250adf174 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -11,12 +11,43 @@ const responseFile = process.argv[2]; const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); +const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; +const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); + +let CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT + ? quote([process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT]) + : undefined; +// Check if the (JavaScript) JS extractor variables are set, and set them if not. +if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + // Find the JS extractor location. + CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( + codeqlExePath, + ['resolve', 'extractor', '--language=javascript'] + ).toString().trim(); + // Terminate early if the CODEQL_EXTRACTOR_JAVASCRIPT_ROOT environment + // variable was not already set and could not be resolved via CLI. + if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { + console.warn( + `'${codeqlExe} database index-files --language cds' terminated early as CODEQL_EXTRACTOR_JAVASCRIPT_ROOT environment variable is not set.` + ); + process.exit(0); + } + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = CODEQL_EXTRACTOR_JAVASCRIPT_ROOT; + // Set the JAVASCRIPT extractor environment variables to the same as the CDS + // extractor environment variables so that the JS extractor will write to the + // CDS database. + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; + process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; +} + const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; const autobuildScriptPath = join( - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName + CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName ); -const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); /** * Terminate early if: @@ -108,7 +139,7 @@ try { }); // TODO : revise this check as the equality is probably not guaranteed. - if (responseFiles.length !== packageJsonDirs.length) { + if (responseFiles.length !== packageJsonDirs.size) { console.warn( `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` ); @@ -170,24 +201,6 @@ responseFiles.forEach(rawCdsFilePath => { } }); -// Check if the (JavaScript) JS extractor variables are set, and set them if not. -if (!process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { - // Find the JS extractor location. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = execFileSync( - codeqlExePath, - ['resolve', 'extractor', '--language=javascript'] - ).toString().trim(); - // Set the JAVASCRIPT extractor environment variables to the same as the CDS - // extractor environment variables so that the JS extractor will write to the - // CDS database. - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = process.env.CODEQL_EXTRACTOR_CDS_DIAGNOSTIC_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = process.env.CODEQL_EXTRACTOR_CDS_LOG_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = process.env.CODEQL_EXTRACTOR_CDS_SCRATCH_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = process.env.CODEQL_EXTRACTOR_CDS_TRAP_DIR; - process.env.CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = process.env.CODEQL_EXTRACTOR_CDS_SOURCE_ARCHIVE_DIR; -} - let excludeFilters = ''; /** * Check if LGTM_INDEX_FILTERS is already set. This tyically happens if either From c9c7cdedc884d5b785b013d625f0c994950940a4 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 30 Jan 2025 09:03:29 -0700 Subject: [PATCH 17/23] Set cwd for CDS JS autobuild process Fixes the invocation of the javascript extractor autobuild within the index-files.js script of the CDS extractor. Ensures that the `cwd` property/option is set when spawning the process that runs the javascript extractor autobuild. Potential working version of initial rewrite for the CDS extractor. --- extractors/cds/tools/index-files.js | 45 +++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 250adf174..71be68573 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,4 +1,4 @@ -const { execFileSync, execSync, spawnSync } = require('child_process'); +const { execFileSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync } = require('fs'); const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); @@ -13,6 +13,12 @@ const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); +const projectRootDir = resolve(`${dirname(__filename)}/../../..`); + +if (!existsSync(projectRootDir)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${projectRootDir}'.`); + process.exit(0); +} let CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT ? quote([process.env.CODEQL_EXTRACTOR_JAVASCRIPT_ROOT]) @@ -122,11 +128,7 @@ try { typeof packageJsonData.dependencies === 'object' ) { const dependencyNames = Object.keys(packageJsonData.dependencies); - if ( - dependencyNames.includes('@sap/cds') - && - dependencyNames.includes('@sap/cds-dk') - ) { + if (dependencyNames.includes('@sap/cds')) { packageJsonDirs.add(dir); break; } @@ -138,14 +140,20 @@ try { } }); - // TODO : revise this check as the equality is probably not guaranteed. - if (responseFiles.length !== packageJsonDirs.size) { - console.warn( - `WARN: mismatch between number of response files (${responseFiles.length}) and package.json directories (${packageJsonDirs.length})` - ); + // Sanity check that we found at least one package.json directory from which the CDS + // compiler dependencies may be installed. + if (packageJsonDirs.size === 0) { + console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); + exit(0); } packageJsonDirs.forEach((dir) => { + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation.`); + execFileSync( + 'npm', + ['install', '--quiet', '--no-audit', '--no-fund', '@sap/cds-dk'], + { cwd: dir, stdio: 'inherit' } + ); console.log(`Installing node packages into ${dir} to enable CDS compilation.`); execFileSync( 'npm', @@ -244,9 +252,10 @@ process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; // refer to .js or .ts files. delete process.env.LGTM_INDEX_INCLUDE; -console.log('Extracting the .cds.json files'); - -console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptPath}`); +console.log( + `Extracting the .cds.json files by running the 'javascript' extractor autobuild script: + ${autobuildScriptPath}` +); /** * Invoke the javascript autobuilder to index the .cds.json files only. * @@ -254,9 +263,15 @@ console.log(`Running 'javascript' extractor autobuild script: ${autobuildScriptP * process that invokes the autobuild script, otherwise the CDS autobuild.sh * script will not be invoked by the autobuild script built into the * 'javascript' extractor. + * + * IMPORTANT: The JavaScript extractor autobuild script must be invoked with + * the current working directory set to the project root directory because it + * assumes it is running from there. Without the `cwd` property set to the + * project root directory, the autobuild script will not detect the .cds.json + * files as being in the project and will not index them. */ spawnSync( autobuildScriptPath, [], - { env: process.env, shell: true, stdio: 'inherit' } + { cwd: projectRootDir, env: process.env, shell: true, stdio: 'inherit' } ); From c213d6b58d46d6798b99794c5ea9d0549a2ec2b1 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Tue, 4 Feb 2025 13:52:13 -0700 Subject: [PATCH 18/23] Another attempted fix for index-files.js cwd Changes the way the index-files.js script is invoked such that the original `--source-root` directory is used, where possible, as the current working directory for any work performed with within the extractor. Passes the original working directory as a parameter of the index-files.js script to allow that (child) script to run from the project/source root while ensuring node package dependencies are still installed in `extractors/cds/tools/node_modules`. --- extractors/cds/tools/autobuild.sh | 6 ----- extractors/cds/tools/index-files.cmd | 28 ++++++++++++++----- extractors/cds/tools/index-files.js | 30 ++++++++++++++------- extractors/cds/tools/index-files.sh | 20 +++++++++++--- extractors/javascript/tools/pre-finalize.sh | 9 +------ 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/extractors/cds/tools/autobuild.sh b/extractors/cds/tools/autobuild.sh index fdf9dc225..579ce91a2 100755 --- a/extractors/cds/tools/autobuild.sh +++ b/extractors/cds/tools/autobuild.sh @@ -2,12 +2,6 @@ set -eu -# NOTE: the code below is copied in three places: -# - scripts/compile-cds.sh -# - extractors/cds/tools/autobuild.sh (here) -# - extractors/javascript/tools/pre-finalize.sh -# Any changes should be synchronized between these three places. - exec "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ --language cds \ diff --git a/extractors/cds/tools/index-files.cmd b/extractors/cds/tools/index-files.cmd index 93db0625c..f10822602 100644 --- a/extractors/cds/tools/index-files.cmd +++ b/extractors/cds/tools/index-files.cmd @@ -19,20 +19,36 @@ if %ERRORLEVEL% neq 0 ( set "_response_file_path=%~1" set "_script_dir=%~dp0" +REM Set _cwd before changing the working directory to the script directory. +set "_cwd=%CD%" echo Checking response file for CDS files to index +REM Terminate early if the _response_file_path doesn't exist or is empty, +REM which indicates that no CDS files were selected or found. if not exist "%_response_file_path%" ( echo 'codeql database index-files --language cds' command terminated early as response file '%_response_file_path%' does not exist or is empty. This is because no CDS files were selected or found. exit /b 0 ) -REM Change to the directory of this script to ensure that npm looks up -REM the package.json file in the correct directory and installs the -REM dependencies (i.e. node_modules) relative to this directory. +REM Change to the directory of this script to ensure that npm looks up the +REM package.json file in the correct directory and installs the dependencies +REM (i.e. node_modules) relative to this directory. This is technically a +REM violation of the assumption that extractor scripts will be run with the +REM current working directory set to the root of the project source, but we +REM also need node_modules to be installed here and not in the project source +REM root, so we make a compromise of: +REM 1. changing to this script's directory; +REM 2. installing node dependencies here; +REM 3. passing the original working directory as a parameter to the +REM index-files.js script; +REM 4. expecting the index-files.js script to immediately change back to +REM the original working (aka the project source root) directory. + cd /d "%_script_dir%" && ^ -echo Installing node package dependencies and running the 'index-files.js' script && ^ -npm install --quiet --no-audit --no-fund --no-package-json && ^ -node "%_script_dir%index-files.js" "%_response_file_path%" +echo Installing node package dependencies && ^ +npm install --quiet --no-audit --no-fund && ^ +echo Running the 'index-files.js' script && ^ +node "%_script_dir%index-files.js" "%_response_file_path%" "%_cwd%" exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 71be68573..fe854e077 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -4,19 +4,29 @@ const { arch, platform } = require('os'); const { dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); -console.log('Indexing CDS files'); +// Terminate early if this script is not invoked with the required arguments. +if (process.argv.length !== 4) { + console.warn(`Usage: node index-files.js `); + process.exit(0); +} const responseFile = process.argv[2]; +const sourceRoot = process.argv[3]; + +// Force this script, and any process it spawns, to use the project (source) +// root directory as the current working directory. +process.chdir(sourceRoot); + +console.log(`Indexing CDS files in project source directory: ${sourceRoot}`); const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); -const projectRootDir = resolve(`${dirname(__filename)}/../../..`); -if (!existsSync(projectRootDir)) { - console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${projectRootDir}'.`); +if (!existsSync(sourceRoot)) { + console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${sourceRoot}'.`); process.exit(0); } @@ -265,13 +275,15 @@ console.log( * 'javascript' extractor. * * IMPORTANT: The JavaScript extractor autobuild script must be invoked with - * the current working directory set to the project root directory because it - * assumes it is running from there. Without the `cwd` property set to the - * project root directory, the autobuild script will not detect the .cds.json - * files as being in the project and will not index them. + * the current working directory set to the project (source) root directory + * because it assumes it is running from there. The JavaScript extractor will + * only find the .cds files to index (to the database) if those file are + * relative to where the autobuild script is invoked from, which should be the + * same as the `--source-root` argument passed to the `codeql database create` + * command. */ spawnSync( autobuildScriptPath, [], - { cwd: projectRootDir, env: process.env, shell: true, stdio: 'inherit' } + { cwd: sourceRoot, env: process.env, shell: true, stdio: 'inherit' } ); diff --git a/extractors/cds/tools/index-files.sh b/extractors/cds/tools/index-files.sh index 67bb815e6..dd839fb97 100755 --- a/extractors/cds/tools/index-files.sh +++ b/extractors/cds/tools/index-files.sh @@ -20,6 +20,7 @@ then exit 3 fi +_cwd="$PWD" _response_file_path="$1" _script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) @@ -36,11 +37,22 @@ then exit 0 fi -# Change to the directory of this script to ensure that npm looks up -# the package.json file in the correct directory and installs the -# dependencies (i.e. node_modules) relative to this directory. +# Change to the directory of this script to ensure that npm looks up the +# package.json file in the correct directory and installs the dependencies +# (i.e. node_modules) relative to this directory. This is technically a +# violation of the assumption that extractor scripts will be run with the +# current working directory set to the root of the project source, but we +# also need node_modules to be installed here and not in the project source +# root, so we make a compromise of: +# 1. changing to this script's directory; +# 2. installing node dependencies here; +# 3. passing the original working directory as a parameter to the +# index-files.js script; +# 4. expecting the index-files.js script to immediately change back to +# the original working (aka the project source root) directory. + cd "$_script_dir" && \ echo "Installing node package dependencies" && \ npm install --quiet --no-audit --no-fund && \ echo "Running the 'index-files.js' script" && \ -node "$(dirname "$0")/index-files.js" "$_response_file_path" +node "$(dirname "$0")/index-files.js" "$_response_file_path" "${_cwd}" diff --git a/extractors/javascript/tools/pre-finalize.sh b/extractors/javascript/tools/pre-finalize.sh index 770312831..d59d706da 100755 --- a/extractors/javascript/tools/pre-finalize.sh +++ b/extractors/javascript/tools/pre-finalize.sh @@ -2,14 +2,7 @@ set -eu -# NOTE: the code below is copied in three places: -# - scripts/compile-cds.sh -# - extractors/cds/tools/autobuild.sh -# - extractors/javascript/tools/pre-finalize.sh (here) -# Any changes should be synchronized between these three places. - -# Do not extract CDS files if the -# CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION # environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor From 4f234be4c9d1167d945ba43612af66a7f9760696 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 07:19:10 -0700 Subject: [PATCH 19/23] Document index-files change for grandfathered package.json --- extractors/cds/tools/index-files.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index fe854e077..3a28387f4 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -119,9 +119,12 @@ try { * Nested package.json files simply cause the package to be installed in the parent * node_modules directory. * - * TODO : fix implementation or change ^comment^ to reflect the actual implementation. - * * We also ensure we skip node_modules, as we can end up in a recursive loop. + * + * NOTE: The original (sh-based) implementation of this extractor would also capture + * "grandfathered" package.json files, which are package.json files that exist in a + * parent directory of the first package.json file found. This (js-based) implementation + * removes this behavior as it seems unnecessary and potentially problematic. */ responseFiles.forEach(file => { let dir = dirname(quote([file])); From b614751780ffe8171cac21a95aaf73fc76023053 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 07:53:22 -0700 Subject: [PATCH 20/23] Remove shell quote from index-files logging --- extractors/cds/tools/index-files.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 3a28387f4..113eff4ec 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -199,8 +199,7 @@ responseFiles.forEach(rawCdsFilePath => { { shell: true } ); if (result.error || result.status !== 0) { - const stderrTruncated = quote( - result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n')); + const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; console.log(errorMessage); execFileSync( From 08f8624fa95ba3f73472e66fa6099f53e56ac5f0 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 12:25:54 -0700 Subject: [PATCH 21/23] index-files.js must compiles cds to file (not dir) Forces the `cds` compilier to output JSON to a file (via stdout) instead of creating an output directory. Accounts for what appears to be a change in the behavior of the `cds` (CLI) compiler, where the `-o` (or `--dest`) option now `Writes output to the given folder instead of stdout`. ``` $ npx cds --version @cap-js/asyncapi: 1.0.2 @cap-js/db-service: 1.16.0 @cap-js/openapi: 1.1.2 @cap-js/sqlite: 1.7.7 @capire/bookshop: 1.0.0 @sap/cds: 8.5.0 @sap/cds-compiler: 5.2.0 @sap/cds-dk: 8.7.1 @sap/cds-fiori: 1.2.7 @sap/cds-foss: 5.0.1 @sap/cds-mtxs: 2.5.1 @sap/eslint-plugin-cds: 3.1.2 Node.js: v20.15.0 ``` --- extractors/cds/tools/index-files.js | 77 ++++++++++++++++------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 113eff4ec..618aa95bc 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,7 @@ const { execFileSync, spawnSync } = require('child_process'); -const { existsSync, readFileSync, statSync } = require('fs'); +const { existsSync, readFileSync, statSync, writeFileSync } = require('fs'); const { arch, platform } = require('os'); -const { dirname, join, resolve } = require('path'); +const { basename, dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); // Terminate early if this script is not invoked with the required arguments. @@ -23,7 +23,7 @@ const osPlatform = platform(); const osPlatformArch = arch(); console.log(`Detected OS platform=${osPlatform} : arch=${osPlatformArch}`); const codeqlExe = osPlatform === 'win32' ? 'codeql.exe' : 'codeql'; -const codeqlExePath = join(quote([process.env.CODEQL_DIST]), codeqlExe); +const codeqlExePath = resolve(join(quote([process.env.CODEQL_DIST]), codeqlExe)); if (!existsSync(sourceRoot)) { console.warn(`'${codeqlExe} database index-files --language cds' terminated early due to internal error: could not find project root directory '${sourceRoot}'.`); @@ -61,9 +61,9 @@ if (!CODEQL_EXTRACTOR_JAVASCRIPT_ROOT) { } const autobuildScriptName = osPlatform === 'win32' ? 'autobuild.cmd' : 'autobuild.sh'; -const autobuildScriptPath = join( +const autobuildScriptPath = resolve(join( CODEQL_EXTRACTOR_JAVASCRIPT_ROOT, 'tools', autobuildScriptName -); +)); /** * Terminate early if: @@ -104,7 +104,7 @@ let cdsCommand = 'cds'; try { execFileSync('cds', ['--version'], { stdio: 'ignore' }); } catch { - console.log('Pre-installing cds compiler'); + console.log('Pre-installing cds compiler ...'); // Use a JS `Set` to avoid duplicate processing of the same directory. const packageJsonDirs = new Set(); @@ -156,18 +156,18 @@ try { // Sanity check that we found at least one package.json directory from which the CDS // compiler dependencies may be installed. if (packageJsonDirs.size === 0) { - console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); + console.warn('WARN: failed to detect any package.json directories for cds compiler installation.'); exit(0); } packageJsonDirs.forEach((dir) => { - console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation.`); + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund', '@sap/cds-dk'], + ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], { cwd: dir, stdio: 'inherit' } ); - console.log(`Installing node packages into ${dir} to enable CDS compilation.`); + console.log(`Installing node packages into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', ['install', '--quiet', '--no-audit', '--no-fund'], @@ -183,7 +183,7 @@ try { cdsCommand = 'npx -y --package @sap/cds-dk cds'; } -console.log('Processing CDS files to JSON'); +console.log('Processing CDS files to JSON ...'); /** * Run the cds compile command on each file in the response files list, outputting the @@ -192,33 +192,44 @@ console.log('Processing CDS files to JSON'); responseFiles.forEach(rawCdsFilePath => { const cdsFilePath = quote([rawCdsFilePath]); const cdsJsonFilePath = `${cdsFilePath}.json`; - console.log(`Processing CDS file ${cdsFilePath} to: ${cdsJsonFilePath}`); + console.log(`Processing CDS file ${cdsFilePath} to ${cdsJsonFilePath} ...`); const result = spawnSync( cdsCommand, - ['compile', cdsFilePath, '-2', 'json', '-o', cdsJsonFilePath, '--locations'], - { shell: true } + [ + 'compile', cdsFilePath, + '-2', 'json', + '--locations', + '--log-level', 'warn' + ], + { cwd: dirname(cdsFilePath), shell: true, stdio: 'pipe' } ); - if (result.error || result.status !== 0) { - const stderrTruncated = result.stderr.toString().split('\n').filter(line => line.startsWith('[ERROR]')).slice(-4).join('\n'); - const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${stderrTruncated}\n\`\`\``; + if (result.error || result.status !== 0 || !result.stdout) { + const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\``; console.log(errorMessage); - execFileSync( - codeqlExePath, - [ - 'database', - 'add-diagnostic', - '--extractor-name=cds', - '--ready-for-status-page', - '--source-id=cds/compilation-failure', - '--source-name="Failure to compile one or more SAP CAP CDS files"', - '--severity=error', - `--markdown-message="${errorMessage}"`, - `--file-path="${cdsFilePath}"`, - '--', - `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` - ], - ); + try { + execFileSync( + codeqlExePath, + [ + 'database', + 'add-diagnostic', + '--extractor-name=cds', + '--ready-for-status-page', + '--source-id=cds/compilation-failure', + '--source-name="Failure to compile one or more SAP CAP CDS files"', + '--severity=error', + `--markdown-message="${errorMessage}"`, + `--file-path="${cdsFilePath}"`, + '--', + `${process.env.CODEQL_EXTRACTOR_CDS_WIP_DATABASE}` + ], + ); + console.log(`Added error diagnostic for source file: ${cdsFilePath}`); + } catch (err) { + console.error(`Failed to add error diagnostic for source file=${cdsFilePath} : ${err}`); + } } + // Write the compiled JSON result to cdsJsonFilePath. + writeFileSync(cdsJsonFilePath, result.stdout); }); let excludeFilters = ''; From dbc3ba7610ec60d079aa457ce1ee60eaad96a302 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 5 Feb 2025 16:33:37 -0700 Subject: [PATCH 22/23] Attempted fix for missing CDS SARIF results Avoids changing directory when running the `cds` compiler, which ensures that paths generated in .cds.json files are relative to the "source root" directory. This replicates the behavior of the original index-files.sh (shell) script, which works but is probably not correct. --- extractors/cds/tools/index-files.js | 15 +++++++++------ scripts/compile-cds.cmd | 14 ++++++++++++++ scripts/compile-cds.sh | 12 +++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 scripts/compile-cds.cmd diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index 618aa95bc..a48d7988b 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,7 @@ const { execFileSync, spawnSync } = require('child_process'); const { existsSync, readFileSync, statSync, writeFileSync } = require('fs'); const { arch, platform } = require('os'); -const { basename, dirname, join, resolve } = require('path'); +const { dirname, join, resolve } = require('path'); const { quote } = require('shell-quote'); // Terminate early if this script is not invoked with the required arguments. @@ -161,16 +161,19 @@ try { } packageJsonDirs.forEach((dir) => { - console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); + console.log(`Installing node dependencies from ${dir}/package.json ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], + ['install', '--quiet', '--no-audit', '--no-fund'], { cwd: dir, stdio: 'inherit' } ); - console.log(`Installing node packages into ${dir} to enable CDS compilation ...`); + // Order is important here. Install dependencies from package.json in the directory, + // then install the CDS development kit (`@sap/cds-dk`) in the directory. Reversing + // this order causes cyclic install-remove behavior. + console.log(`Installing '@sap/cds-dk' into ${dir} to enable CDS compilation ...`); execFileSync( 'npm', - ['install', '--quiet', '--no-audit', '--no-fund'], + ['install', '--quiet', '--no-audit', '--no-fund', '--no-save', '@sap/cds-dk'], { cwd: dir, stdio: 'inherit' } ); }); @@ -201,7 +204,7 @@ responseFiles.forEach(rawCdsFilePath => { '--locations', '--log-level', 'warn' ], - { cwd: dirname(cdsFilePath), shell: true, stdio: 'pipe' } + { shell: true, stdio: 'pipe' } ); if (result.error || result.status !== 0 || !result.stdout) { const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\``; diff --git a/scripts/compile-cds.cmd b/scripts/compile-cds.cmd new file mode 100644 index 000000000..924856eb8 --- /dev/null +++ b/scripts/compile-cds.cmd @@ -0,0 +1,14 @@ +@echo off + +if not defined CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION ( + type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ + --include-extension=.cds ^ + --language cds ^ + --prune **\node_modules\**\* ^ + --prune **\.eslint\**\* ^ + --total-size-limit=10m ^ + -- ^ + "%CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE%" +) + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/scripts/compile-cds.sh b/scripts/compile-cds.sh index 6f30a2495..a00b035dc 100755 --- a/scripts/compile-cds.sh +++ b/scripts/compile-cds.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # To use this script with the CodeQL CLI: # 1. Set the `codeql database create` `--search-path`` argument to the `extractors/` directory in this repository, e.g.: @@ -32,14 +32,16 @@ set -eu # - extractors/javascript/tools/pre-finalize.sh # Any changes should be synchronized between these three places. -# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION environment variable is set +# Do not extract CDS files if the CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION +# environment variable is set. if [ -z "${CODEQL_EXTRACTOR_CDS_SKIP_EXTRACTION:-}" ]; then # Call the index-files command with the CDS extractor - "$CODEQL_DIST/codeql" database index-files \ - --language cds \ - --total-size-limit 10m \ + "${CODEQL_DIST}/codeql" database index-files \ --include-extension=.cds \ + --language cds \ --prune **/node_modules/**/* \ --prune **/.eslint/**/* \ + --total-size-limit=10m \ + -- \ "$CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE" fi \ No newline at end of file From 33d51d0b3cc84f7824da0ec90bad944684808dbf Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Tue, 4 Mar 2025 11:58:29 -0700 Subject: [PATCH 23/23] Improve handling of cds compile output files --- extractors/cds/tools/index-files.js | 114 +++++++++++++++++++++------- 1 file changed, 88 insertions(+), 26 deletions(-) diff --git a/extractors/cds/tools/index-files.js b/extractors/cds/tools/index-files.js index a48d7988b..885307e40 100644 --- a/extractors/cds/tools/index-files.js +++ b/extractors/cds/tools/index-files.js @@ -1,7 +1,7 @@ const { execFileSync, spawnSync } = require('child_process'); -const { existsSync, readFileSync, statSync, writeFileSync } = require('fs'); +const { existsSync, readdirSync, readFileSync, renameSync, statSync } = require('fs'); const { arch, platform } = require('os'); -const { dirname, join, resolve } = require('path'); +const { dirname, format, join, parse, resolve } = require('path'); const { quote } = require('shell-quote'); // Terminate early if this script is not invoked with the required arguments. @@ -186,29 +186,96 @@ try { cdsCommand = 'npx -y --package @sap/cds-dk cds'; } +/** + * Recursively renames all .json files to .cds.json in the given directory and + * its subdirectories, except for those that already have .cds.json extension. + * + * @param {string} dirPath - The directory path to start recursion from + */ +function recursivelyRenameJsonFiles(dirPath) { + // Make sure the directory exists + if (!existsSync(dirPath) || !statSync(dirPath).isDirectory()) { + console.log(`Directory not found or not a directory: ${dirPath}`); + return; + } + console.log(`Processing JSON files in output directory: ${dirPath}`); + // Get all entries in the directory + const entries = readdirSync(dirPath, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = join(dirPath, entry.name); + if (entry.isDirectory()) { + // Recursively process subdirectories + recursivelyRenameJsonFiles(fullPath); + } else if ( + entry.isFile() && + entry.name.endsWith('.json') && + !entry.name.endsWith('.cds.json') + ) { + // Rename .json files to .cds.json + const newPath = format({ ...parse(fullPath), base: '', ext: '.cds.json' }); + renameSync(fullPath, newPath); + console.log(`Renamed CDS output file from ${fullPath} to ${newPath}`); + } + } +} + console.log('Processing CDS files to JSON ...'); /** * Run the cds compile command on each file in the response files list, outputting the * compiled JSON to a file with the same name but with a .json extension appended. */ -responseFiles.forEach(rawCdsFilePath => { - const cdsFilePath = quote([rawCdsFilePath]); - const cdsJsonFilePath = `${cdsFilePath}.json`; - console.log(`Processing CDS file ${cdsFilePath} to ${cdsJsonFilePath} ...`); - const result = spawnSync( - cdsCommand, - [ - 'compile', cdsFilePath, - '-2', 'json', - '--locations', - '--log-level', 'warn' - ], - { shell: true, stdio: 'pipe' } - ); - if (result.error || result.status !== 0 || !result.stdout) { - const errorMessage = `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\``; - console.log(errorMessage); +for (const rawCdsFilePath of responseFiles) { + const cdsFilePath = resolve(quote([rawCdsFilePath])); + try { + if (!existsSync(cdsFilePath)) { + throw new Error(`Expected CDS file '${cdsFilePath}' does not exist.`); + } + const cdsJsonOutPath = `${cdsFilePath}.json`; + console.log(`Processing CDS file ${cdsFilePath} to ${cdsJsonOutPath} ...`); + const result = spawnSync( + cdsCommand, + [ + 'compile', cdsFilePath, + '--to', 'json', + '--dest', cdsJsonOutPath, + '--locations', + '--log-level', 'warn' + ], + { cwd: sourceRoot, shell: true, stdio: 'pipe' } + ); + if (result.error || result.status !== 0) { + throw new Error( + `Could not compile the file ${cdsFilePath}.\nReported error(s):\n\`\`\`\n${result.stderr.toString()}\n\`\`\`` + ); + } + /** + * The `cds compile` command chooses how it outputs the JSON. If it creates the + * output files in a directory (at cdsJsonOutPath), then it will create the + * directory when it runs and will choose the file names within that directory. + * If it creates the output as a single file (at cdsJsonOutPath), then there is + * nothing more to do as we create the output path by simple appending `.json` to + * the input file path/name, where the input path should already end with `.cds` + * (or else it shouldn't be in the response file). + * + * Therefore, if the output is a directory, we need to rename the output files + * to have a `.cds.json` extension, not just `.json`, so that the JS extractor + * recognizes them as CDS files to be indexed. + */ + if (!existsSync(cdsJsonOutPath) || (!statSync(cdsJsonOutPath).isFile() && !statSync(cdsJsonOutPath).isDirectory())) { + throw new Error( + `CDS source file '${cdsFilePath}' was not compiled to JSON. This is likely because the file does not exist or is not a valid CDS file.` + ); + } + if (statSync(cdsJsonOutPath).isDirectory()) { + console.log(`CDS compiler generated JSON to output directory: ${cdsJsonOutPath}`); + // Recursively rename all .json files to have a .cds.json extension + recursivelyRenameJsonFiles(cdsJsonOutPath); + } else { + console.log(`CDS compiler generated JSON to file: ${cdsJsonOutPath}`); + } + } catch (errorMessage) { + console.error(`ERROR: adding diagnostic for source file=${cdsFilePath} : ${errorMessage} ...`); try { execFileSync( codeqlExePath, @@ -228,12 +295,10 @@ responseFiles.forEach(rawCdsFilePath => { ); console.log(`Added error diagnostic for source file: ${cdsFilePath}`); } catch (err) { - console.error(`Failed to add error diagnostic for source file=${cdsFilePath} : ${err}`); + console.error(`ERROR: Failed to add error diagnostic for source file=${cdsFilePath} : ${err}`); } } - // Write the compiled JSON result to cdsJsonFilePath. - writeFileSync(cdsJsonFilePath, result.stdout); -}); +} let excludeFilters = ''; /** @@ -274,9 +339,6 @@ console.log(`Set $LGTM_INDEX_FILTERS to:\n${process.env.LGTM_INDEX_FILTERS}`); process.env.LGTM_INDEX_TYPESCRIPT = 'NONE'; // Configure to copy over the .cds files as well, by pretending they are JSON. process.env.LGTM_INDEX_FILETYPES = '.cds:JSON'; -// Ignore the LGTM_INDEX_INCLUDE variable for this purpose as it may explicitly -// refer to .js or .ts files. -delete process.env.LGTM_INDEX_INCLUDE; console.log( `Extracting the .cds.json files by running the 'javascript' extractor autobuild script: