diff --git a/.vscode/launch.json b/.vscode/launch.json index 9691d0dab..929db2703 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,13 +5,15 @@ "version": "0.2.0", "configurations": [ { + "name": "Docker: Attach to Autobuilder", "type": "node", - "request": "launch", - "name": "Launch Program", - "skipFiles": ["/**"], - "program": "${workspaceFolder}/modules/oas-page-builder/tests/unit/services/pageBuilder.test.ts", - "preLaunchTask": "tsc: build - tsconfig.json", - "outFiles": ["${workspaceFolder}/build/**/*.js"] + "request": "attach", + "port": 9229, + "address": "localhost", + "localRoot": "${workspaceFolder}", + "remoteRoot": "/home/docsworker-xlarge", + "autoAttachChildProcesses": false, + "protocol": "inspector" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..63166342f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "debug.javascript.autoAttachFilter": "disabled" +} diff --git a/Dockerfile.local b/Dockerfile.local index 7fe85a591..49f7d9167 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -1,4 +1,4 @@ -FROM arm64v8/ubuntu:20.04 +FROM arm64v8/ubuntu:20.04 as initial ARG NPM_BASE_64_AUTH ARG NPM_EMAIL ARG SNOOTY_PARSER_VERSION=0.15.0 @@ -7,10 +7,13 @@ ARG MUT_VERSION=0.10.7 ARG REDOC_CLI_VERSION=1.2.3 ARG NPM_BASE_64_AUTH ARG NPM_EMAIL +ARG WORK_DIRECTORY=/home/docsworker-xlarge + ENV DEBIAN_FRONTEND=noninteractive +WORKDIR ${WORK_DIRECTORY} # helper libraries for docs builds -RUN apt-get update && apt-get install -y vim git unzip zip +RUN apt-get update && apt-get install -y vim git unzip zip chromium-browser rsync # get node 18 # https://gist.github.com/RinatMullayanov/89687a102e696b1d4cab @@ -20,7 +23,6 @@ RUN apt-get install --yes nodejs RUN apt-get install --yes build-essential RUN apt-get install --yes python3-pip libxml2-dev libxslt-dev python-dev pkg-config -WORKDIR /app RUN python3 -m pip install poetry @@ -39,53 +41,66 @@ RUN git clone -b v${MUT_VERSION} --depth 1 https://github.com/mongodb/mut.git \ && make package \ && mv dist/mut /opt/ -RUN curl -L -o redoc.zip https://github.com/mongodb-forks/redoc/archive/refs/tags/v${REDOC_CLI_VERSION}.zip \ - && unzip redoc.zip \ - && mv redoc-${REDOC_CLI_VERSION} redoc/ - -ENV PATH="${PATH}:/opt/snooty:/opt/mut:/app/.local/bin" +ENV PATH="${PATH}:/opt/snooty:/opt/mut:/${WORK_DIRECTORY}/.local/bin" # setup user and root directory -RUN useradd -ms /bin/bash docsworker -RUN chmod 755 -R /app -RUN chown -Rv docsworker /app -USER docsworker +RUN useradd -ms /bin/bash docsworker-xlarge +RUN chmod 755 -R ${WORK_DIRECTORY} +RUN chown -Rv docsworker-xlarge ${WORK_DIRECTORY} +USER docsworker-xlarge # install snooty frontend and docs-tools RUN git clone -b v${SNOOTY_FRONTEND_VERSION} --depth 1 https://github.com/mongodb/snooty.git \ && cd snooty \ && npm ci --legacy-peer-deps --omit=dev +RUN curl https://raw.githubusercontent.com/mongodb/docs-worker-pool/meta/makefiles/shared.mk -o shared.mk + + +RUN git clone -b @dop/redoc-cli@${REDOC_CLI_VERSION} --depth 1 https://github.com/mongodb-forks/redoc.git redoc \ + # Install dependencies for Redoc CLI + && cd redoc/ \ + && npm ci --prefix cli/ --omit=dev + +FROM initial as persistence + RUN mkdir -p modules/persistence && chmod 755 modules/persistence COPY modules/persistence/package*.json ./modules/persistence/ RUN cd ./modules/persistence \ && npm ci --legacy-peer-deps +# Build persistence module + +COPY --chown=docsworker-xlarge modules/persistence/tsconfig*.json ./modules/persistence +COPY --chown=docsworker-xlarge modules/persistence/src ./modules/persistence/src/ +COPY --chown=docsworker-xlarge modules/persistence/index.ts ./modules/persistence + +RUN cd ./modules/persistence \ + && npm run build:esbuild + +FROM initial as oas RUN mkdir -p modules/oas-page-builder && chmod 755 modules/oas-page-builder COPY modules/oas-page-builder/package*.json ./modules/oas-page-builder/ RUN cd ./modules/oas-page-builder \ && npm ci --legacy-peer-deps +# Build modules +# OAS Page Builder +COPY --chown=docsworker-xlarge modules/oas-page-builder/tsconfig*.json ./modules/oas-page-builder +COPY --chown=docsworker-xlarge modules/oas-page-builder/src ./modules/oas-page-builder/src/ +COPY --chown=docsworker-xlarge modules/oas-page-builder/index.ts ./modules/oas-page-builder -# Root project build -COPY package*.json ./ -RUN npm ci --legacy-peer-deps -# Build persistence module +RUN cd ./modules/oas-page-builder \ + && npm run build:esbuild -COPY --chown=docsworker modules/persistence/tsconfig*.json ./modules/persistence -COPY --chown=docsworker modules/persistence/src ./modules/persistence/src/ -COPY --chown=docsworker modules/persistence/index.ts ./modules/persistence +FROM initial as root -RUN cd ./modules/persistence \ - && npm run build +COPY --from=persistence --chown=docsworker-xlarge ${WORK_DIRECTORY}/modules/persistence/dist/ ./modules/persistence +COPY --from=oas --chown=docsworker-xlarge ${WORK_DIRECTORY}/modules/oas-page-builder/dist/ ./modules/oas-page-builder -# Build modules -# OAS Page Builder -COPY --chown=docsworker modules/oas-page-builder/tsconfig*.json ./modules/oas-page-builder -COPY --chown=docsworker modules/oas-page-builder/src ./modules/oas-page-builder/src/ -COPY --chown=docsworker modules/oas-page-builder/index.ts ./modules/oas-page-builder +# Root project build +COPY package*.json ./ +RUN npm ci --legacy-peer-deps -RUN cd ./modules/oas-page-builder \ - && npm run build COPY tsconfig*.json ./ COPY config config/ @@ -94,8 +109,13 @@ COPY src src/ RUN npm run build:esbuild +ENV PERSISTENCE_MODULE_PATH=${WORK_DIRECTORY}/modules/persistence/index.js +ENV OAS_MODULE_PATH=${WORK_DIRECTORY}/modules/oas-page-builder/index.js +ENV REDOC_PATH=${WORK_DIRECTORY}/redoc/cli/index.js + +RUN mkdir -p modules/persistence && chmod 755 modules/persistence RUN mkdir repos && chmod 755 repos EXPOSE 3000 -CMD ["node", "--enable-source-maps", "dist/entrypoints/localApp.js"] \ No newline at end of file +CMD ["node", "--inspect-brk=0.0.0.0", "--enable-source-maps", "dist/entrypoints/onDemandApp.js"] diff --git a/README.md b/README.md index 9074078ee..d62b6b9b7 100644 --- a/README.md +++ b/README.md @@ -21,49 +21,81 @@ To add a new property: - Go to `infrastructure/ecs-main/ecs-service.yml` `TaskDefinition` section - Add the new property to the `ContainerDefinitions`/`Environment` section -## Build and Run Docker Image for local testing +## Debug the Autobuilder for Local Testing -The npm build args are required for the portion of the dockerfile that installs the [snooty-frontend]. `NPM_CONFIG__AUTH` -and `NPM_CONFIG_EMAIL` are environment variables available in our working directory. `NPM_CONFIG_{OPTION}` environment -variables can actually be used instead of the `~/.npmrc` file. The reason we need the build args to be `NPM_BASE_64_AUTH` -and `NPM_EMAIL` is because that's what's expected in the `.npmrc` within [snooty-frontend]. +### Setup -```shell -docker build --tag=workerpool --build-arg NPM_BASE_64_AUTH=${NPM_CONFIG__AUTH} --build-arg NPM_EMAIL=${NPM_CONFIG_EMAIL} . -``` +To debug the Autobuilder for local testing, you first need to ensure the following has been done: -```shell -docker run \ - --env MONGO_ATLAS_USERNAME \ - --env MONGO_ATLAS_PASSWORD \ - --env AWS_ACCESS_KEY_ID \ - --env AWS_SECRET_ACCESS_KEY \ - --env GITHUB_BOT_USERNAME \ - --env GITHUB_BOT_PASSWORD \ - --env DB_NAME \ - --env XLARGE \ - --env SNOOTY_ENV \ - --env FASTLY_TOKEN \ - --env FASTLY_DOCHUB_MAP \ - --env FASTLY_SERVICE_ID \ - workerpool -``` +1. Docker is running +2. The `~/.aws/credentials` file contains unexpired credentials for the `default` profile -- `MONGO_ATLAS_USERNAME` and `MONGO_ATLAS_PASSWORD` is username/password of atlas database -- `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are needed for uploading to S3 via [mut](https://github.com/mongodb/mut) -- `GITHUB_BOT_USERNAME` and `GITHUB_BOT_PASSWORD` are needed so builder can access private repos -- `DB_NAME` allows the indication of a pool database (pool, pool_test) -- `XLARGE` true or false indicates whether this instance will run on an XLARGE server or not -- `SNOOTY_ENV` indicates whether the build environment is stage, prod, or dev -- `FASTLY_TOKEN` is needed for connecting to the Fastly edge dictionary -- `FASTLY_DOCHUB_MAP` is the id of the redirect map that we publish dochub links to -- `FASTLY_SERVICE_ID` is the id of the service used for dochub +For retrieving credentials, head to AWS and under `Docs Platform`, click on `Command line or programmatic access`. +![AWS console](images/aws-console-admin.png) -If you are running a local version of the docker image for testing, we have a separate staging environment setup. Testing in this environment is automated through the "stage" branch. Add the following env variables to the `docker run` command: +Copy the value in option 2, `Manually add a profile to your AWS credentials file (Short-term credentials)`. +![Alt text](images/aws-credentials.png) + +From there, paste this value in `~/.aws/credentials`, and replace the randomly generated profile (which looks something like `[123456789_AdministratorAccess]`) with `[default]`. +You should now have the correct credentials to run the debugger. + +_**NOTE: credentials expire pretty quickly. Not sure how exactly how long they last for, but in my experience they expire in approximately 30 minutes.**_ + +You should now be all set to run the debugger command: + +`npm run debug` + +To view all of the options for the command, you can run: + +`npm run debug -- --help` + +Here is an example of running the local debugger for `cloud-docs`: + +`npm run debug -- -o 10gen -n cloud-docs` + +Here is an example of running the local debugger for `docs-monorepo/docs-landing` on branch `groot`: + +`npm run debug -- -o 10gen -n docs-monorepo -d cloud-docs -b groot` + +By default, the environment that is used for the local Autobuilder is `stg`. + +### Debugger Behavior + +When the command is run, there are several steps that occur before the Autobuilder begins: + +1. Environment variables and other information are pulled from Parameter Store +2. The GitHub repository is queried for data to create the job +3. The container is built + - NOTE: If you have not run the debug command before, the build will take a substantial amount of time (approximately 10-15 minutes). + Subsequent builds will be much shorter, especially if the changes are just code changes. If just a code change is made after the initial build, it should only take a few seconds for the build to complete and the container to run. Changes such as updating the version of the Snooty Parser, or the Redoc CLI will cause the builds to take much longer, but these happen much less frequently. The majority of the build should be on the order of a few seconds. +4. The data from step 2 is then added as a record in the `pool_test.queue`. +5. The container is then run, and waits for the user to connect to it via the VSCode debugger. + +Once the container starts successfully, you should see something like the following message: + +`Debugger listening on ws://0.0.0.0:9229/....` + +To connect, click on the debug tab on the left side of your VSCode editor. Make sure the dropdown to the right of the green play button is set to the `Docker: Attach to Autobuilder` configuration. Press the green play button, and you will attach to the container. + +### Troubleshooting + +The most frequent cause of build failures will be related to expired AWS credentials, or not having Docker running. Also, if you haven't run `npm ci` in a while, you will need to do so as a new dependency was added to run the command. + +Occasionally, errors may occur inexplicably, and the error messages may seem unrelated to any change made. Oftentimes, running the following commands can resolve these sporadic issues: + +```sh +docker image prune +docker container prune ``` ---env DB_NAME -``` + +Also, another potential error could be due to the Dockerfile.local not being updated. If you are not seeing changes that are occurring in the Autobuilder in another environment, this may be why. For example, the Dockerfile.local could be using an older version of the Snooty Parser. + +![Alt text](images/vsode-debugger.png) + +By default, the container will break at the first line of code, which will be in a file called `bind.js`. Press the fast-forward button to continue the execution. You are also able to add other breakpoints to stop the application. Once the application is complete, press `CTRL + C` for the terminal to exit out of the connection to the container. + +If you receive `CredentialsProviderError: Could not load credentials from any providers`, make sure that there is no env `AWS_PROFILE` defined as a different profile anywhere (such as in the global `~/.zshrc` file). Otherwise, ensure that `AWS_PROFILE` matches the same profile defined in `~/.aws/credentials`. ## Run Tests diff --git a/api/controllers/v1/github.ts b/api/controllers/v1/github.ts index b72f1d646..f743e65b8 100644 --- a/api/controllers/v1/github.ts +++ b/api/controllers/v1/github.ts @@ -6,6 +6,7 @@ import { RepoBranchesRepository } from '../../../src/repositories/repoBranchesRe import { markBuildArtifactsForDeletion, validateJsonWebhook } from '../../handlers/github'; import { DocsetsRepository } from '../../../src/repositories/docsetsRepository'; import { ReposBranchesDocsetsDocument } from '../../../modules/persistence/src/services/metadata/repos_branches'; +import { PushEvent } from '@octokit/webhooks-types'; async function prepGithubPushPayload( githubEvent: any, @@ -77,7 +78,28 @@ export const TriggerBuild = async (event: any = {}, context: any = {}): Promise< body: errMsg, }; } - const body = JSON.parse(event.body); + if (!event.body) { + const err = 'Trigger build does not have a body in event payload'; + consoleLogger.error('TriggerBuildError', err); + return { + statusCode: 400, + headers: { 'Content-Type': 'text/plain' }, + body: err, + }; + } + + let body: PushEvent; + try { + body = JSON.parse(event.body) as PushEvent; + } catch (e) { + consoleLogger.error('[TriggerBuild]', `ERROR! Could not parse event.body ${e}`); + console.log(`event: ${event} and event body: ${event.body}`); + return { + statusCode: 502, + headers: { 'Content-Type': 'text/plain' }, + body: ' ERROR! Could not parse event.body', + }; + } if (body.deleted) { return { diff --git a/api/controllers/v1/jobs.ts b/api/controllers/v1/jobs.ts index 4b116e19c..14e0ce6aa 100644 --- a/api/controllers/v1/jobs.ts +++ b/api/controllers/v1/jobs.ts @@ -90,7 +90,7 @@ export const HandleJobs = async (event: any = {}): Promise => { await SubmitArchiveJob(jobId); break; default: - consoleLogger.error(jobId, 'Invalid status'); + consoleLogger.error(jobId, `Invalid status: ${jobStatus}`); break; } } catch (err) { diff --git a/api/controllers/v2/github.ts b/api/controllers/v2/github.ts index ccb205f6e..e562d2a2f 100644 --- a/api/controllers/v2/github.ts +++ b/api/controllers/v2/github.ts @@ -18,7 +18,8 @@ async function prepGithubPushPayload( githubEvent: PushEvent, repoBranchesRepository: RepoBranchesRepository, prefix: string, - repoInfo: ReposBranchesDocsetsDocument + repoInfo: ReposBranchesDocsetsDocument, + directory?: string ): Promise> { const branch_name = githubEvent.ref.split('/')[2]; const branch_info = await repoBranchesRepository.getRepoBranchAliases( @@ -53,6 +54,7 @@ async function prepGithubPushPayload( urlSlug: urlSlug, prefix: prefix, project: project, + directory: directory, }, logs: [], }; @@ -110,7 +112,7 @@ export const TriggerBuild = async (event: APIGatewayEvent): Promise 1) continue; try { - await createAndInsertJob(`/${path}`); + await createAndInsertJob(path); } catch (err) { return { statusCode: 500, diff --git a/api/controllers/v2/jobs.ts b/api/controllers/v2/jobs.ts index d6d56a741..a5339346b 100644 --- a/api/controllers/v2/jobs.ts +++ b/api/controllers/v2/jobs.ts @@ -72,7 +72,7 @@ export const HandleJobs = async (event: SQSEvent): Promise => { await notifyBuildSummary(jobId); break; default: - consoleLogger.error(jobId, 'Invalid status'); + consoleLogger.error(jobId, `Invalid status: ${jobStatus}`); break; } } catch (err) { @@ -150,7 +150,7 @@ async function NotifyBuildProgress(jobId: string): Promise { return; } - const jobTitle = fullDocument.title; + const jobTitle = `${fullDocument.title}${fullDocument.payload.directory ? `/${fullDocument.payload.directory}` : ''}`; const username = fullDocument.user; const repoEntitlementRepository = new RepoEntitlementsRepository(db, c, consoleLogger); const entitlement = await repoEntitlementRepository.getSlackUserIdByGithubUsername(username); diff --git a/api/controllers/v2/slack.ts b/api/controllers/v2/slack.ts index 68afa8eec..2cb5307bc 100644 --- a/api/controllers/v2/slack.ts +++ b/api/controllers/v2/slack.ts @@ -92,14 +92,12 @@ export const getDeployableJobs = async ( let repoOwner: string, repoName: string, branchName: string, directory: string | undefined; const splitValues = values.repo_option[i].value.split('/'); - if (splitValues.length === 3) { - // e.g. mongodb/docs-realm/master => (owner/repo/branch) - [repoOwner, repoName, branchName] = splitValues; - } else if (splitValues.length === 4 && process.env.FEATURE_FLAG_MONOREPO_PATH === 'true') { + if (process.env.FEATURE_FLAG_MONOREPO_PATH === 'true' && splitValues.length === 4) { // e.g. 10gen/docs-monorepo/cloud-docs/master => (owner/monorepo/repoDirectory/branch) [repoOwner, repoName, directory, branchName] = splitValues; } else { - throw Error('Selected entitlement value is configured incorrectly. Check user entitlements!'); + // e.g. mongodb/docs-realm/master => (owner/repo/branch) + [repoOwner, repoName, branchName] = splitValues; } const hashOption = values?.hash_option ?? null; diff --git a/cdk-infra/lib/constructs/api/webhook-env-construct.ts b/cdk-infra/lib/constructs/api/webhook-env-construct.ts index 114db52dc..800b9277d 100644 --- a/cdk-infra/lib/constructs/api/webhook-env-construct.ts +++ b/cdk-infra/lib/constructs/api/webhook-env-construct.ts @@ -50,7 +50,7 @@ export class WebhookEnvConstruct extends Construct { USER_ENTITLEMENT_COL_NAME: entitlementCollection, DASHBOARD_URL: getDashboardUrl(env, jobCollection), STAGE: env, - FEATURE_FLAG_MONOREPO_PATH: featureFlagMonorepoPath.stringValue, + FEATURE_FLAG_MONOREPO_PATH: featureFlagMonorepoPath, }; } } diff --git a/config/default.json b/config/default.json index db824094f..8a089b421 100644 --- a/config/default.json +++ b/config/default.json @@ -13,7 +13,7 @@ "fastlyDochubMap": "devfslydochubmap", "entitlementCollection": "entitlements", "docsetsCollection": "docsets", - "MONGO_TIMEOUT_S": 15, + "MONGO_TIMEOUT_S": 1500, "JOB_TIMEOUT_S": 900, "RETRY_TIMEOUT_MS": 5000, "MIN_TIMEOUT_MS": 1, diff --git a/images/aws-console-admin.png b/images/aws-console-admin.png new file mode 100644 index 000000000..bec944940 Binary files /dev/null and b/images/aws-console-admin.png differ diff --git a/images/aws-credentials.png b/images/aws-credentials.png new file mode 100644 index 000000000..4f9b471cc Binary files /dev/null and b/images/aws-credentials.png differ diff --git a/images/vsode-debugger.png b/images/vsode-debugger.png new file mode 100644 index 000000000..25561b1c9 Binary files /dev/null and b/images/vsode-debugger.png differ diff --git a/modules/oas-page-builder/README.md b/modules/oas-page-builder/README.md index cab1ed407..48d92feb4 100644 --- a/modules/oas-page-builder/README.md +++ b/modules/oas-page-builder/README.md @@ -55,7 +55,7 @@ npm run start -- --bundle /home/docsworker-xlarge/repos/cloud-docs/bundle.zip -- ### (Required) Options | Option | Description | -| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | bundle | Path to the parsed bundle zip file. This should be the output of the parser and will be used to obtain build metadata about OpenAPI content pages. | | output | Path to the directory that the OpenAPI content pages should be built to. Typically, this would be the same output `public/` directory of a Snooty frontend build. | | redoc | Path to the local installation of Redoc CLI to use. This should point to the team's [fork of Redoc](https://github.com/mongodb-forks/redoc), with the target being a compiled JS file. | diff --git a/modules/oas-page-builder/package-lock.json b/modules/oas-page-builder/package-lock.json index d366fa89b..64a58bbf8 100644 --- a/modules/oas-page-builder/package-lock.json +++ b/modules/oas-page-builder/package-lock.json @@ -26,6 +26,7 @@ "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", "babel-jest": "^29.3.1", + "esbuild": "^0.19.11", "eslint": "^8.27.0", "jest": "^29.3.1", "prettier": "^2.8.1", @@ -2786,6 +2787,374 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -4819,6 +5188,44 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -11004,6 +11411,167 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -12511,6 +13079,37 @@ "is-arrayish": "^0.2.1" } }, + "esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", diff --git a/modules/oas-page-builder/package.json b/modules/oas-page-builder/package.json index 198d1a3d1..5cd294873 100644 --- a/modules/oas-page-builder/package.json +++ b/modules/oas-page-builder/package.json @@ -5,6 +5,7 @@ "main": "index.js", "scripts": { "build": "rm -rf ./dist/ && tsc", + "build:esbuild": "esbuild index.ts --bundle --platform=node --outdir=./dist --allow-overwrite", "format": "npm run prettier -- --check", "lint": "eslint --ext .ts .", "lint:fix": "npm run lint -- --fix", @@ -24,6 +25,7 @@ "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", "babel-jest": "^29.3.1", + "esbuild": "^0.19.11", "eslint": "^8.27.0", "jest": "^29.3.1", "prettier": "^2.8.1", diff --git a/modules/persistence/package-lock.json b/modules/persistence/package-lock.json index c24d1dd63..e27aa4cff 100644 --- a/modules/persistence/package-lock.json +++ b/modules/persistence/package-lock.json @@ -29,6 +29,7 @@ "@shelf/jest-mongodb": "^4.1.4", "@typescript-eslint/eslint-plugin": "~5.5.0", "@typescript-eslint/parser": "^5.47.0", + "esbuild": "^0.19.11", "eslint": "^8.3.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.25.3", @@ -1746,6 +1747,374 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", @@ -4299,6 +4668,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -10988,6 +11395,167 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", @@ -12706,6 +13274,37 @@ "is-symbol": "^1.0.2" } }, + "esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", diff --git a/modules/persistence/package.json b/modules/persistence/package.json index 6ed94734e..78611f804 100644 --- a/modules/persistence/package.json +++ b/modules/persistence/package.json @@ -10,6 +10,7 @@ "lint": "eslint . --ext .ts", "test": "jest --coverage", "build": "tsc", + "build:esbuild": "esbuild index.ts --bundle --platform=node --outdir=./dist --allow-overwrite", "start": "node --unhandled-rejections=strict ./dist/index.js", "dev": "tsc && node --unhandled-rejections=strict ./dist/index.js --path ./build/artifacts.zip " }, @@ -36,6 +37,7 @@ "@shelf/jest-mongodb": "^4.1.4", "@typescript-eslint/eslint-plugin": "~5.5.0", "@typescript-eslint/parser": "^5.47.0", + "esbuild": "^0.19.11", "eslint": "^8.3.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.25.3", diff --git a/package-lock.json b/package-lock.json index cb42cd1bd..a440c38d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,6 +70,7 @@ "serverless-plugin-include-dependencies": "^5.1.0", "serverless-prune-plugin": "^2.0.2", "ts-jest": "^27.0.5", + "tsx": "^4.6.0", "typescript": "^4.4.3" } }, @@ -10197,9 +10198,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -10351,6 +10352,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -17123,6 +17136,15 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/resolve.exports": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", @@ -18913,6 +18935,414 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tsx": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.1.tgz", + "integrity": "sha512-OQ4TAPHXAPUo/NZAmmIybl0o8LFOTlycQxFepLBAp6EV87U88fOKYGCQI2viGAEOVU9UW/cgQcxcOMnfEKVY3Q==", + "dev": true, + "dependencies": { + "esbuild": "~0.18.20", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, "node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -27327,9 +27757,9 @@ } }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, "function-bind": { @@ -27426,6 +27856,15 @@ "get-intrinsic": "^1.1.1" } }, + "get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -32468,6 +32907,12 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "resolve.exports": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", @@ -33821,6 +34266,203 @@ } } }, + "tsx": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.1.tgz", + "integrity": "sha512-OQ4TAPHXAPUo/NZAmmIybl0o8LFOTlycQxFepLBAp6EV87U88fOKYGCQI2viGAEOVU9UW/cgQcxcOMnfEKVY3Q==", + "dev": true, + "requires": { + "esbuild": "~0.18.20", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.2" + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + } + } + }, "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", diff --git a/package.json b/package.json index 4c349508a..0710f3fa4 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,13 @@ "start": "node index.js", "clean": "node maintain.js", "build": "tsc", - "build:esbuild": "esbuild src/entrypoints/localApp.ts --bundle --platform=node --outdir=./dist/entrypoints --allow-overwrite --sourcemap", + "build:esbuild": "esbuild src/onDemandApp.ts --bundle --platform=node --outdir=./dist/entrypoints --allow-overwrite --sourcemap", "format": "npm run prettier -- --check", "format:fix": "npm run prettier -- --write", "lint": "eslint --ext .ts .", "lint:fix": "npm run lint -- --fix", "prettier": "prettier '**/*.{js,jsx,json,md,ts}' '!modules/**' '!cdk-infra/**'", + "debug": "npm run build:esbuild && tsx src/commands/src/scripts/local-build/index.ts", "prepare": "husky install" }, "repository": { @@ -84,6 +85,7 @@ "serverless-plugin-include-dependencies": "^5.1.0", "serverless-prune-plugin": "^2.0.2", "ts-jest": "^27.0.5", + "tsx": "^4.6.0", "typescript": "^4.4.3" }, "husky": { diff --git a/src/clients/githubClient.ts b/src/clients/githubClient.ts index 6011c4fce..04e3f51dd 100644 --- a/src/clients/githubClient.ts +++ b/src/clients/githubClient.ts @@ -2,11 +2,11 @@ import { Octokit } from '@octokit/rest'; let client: Octokit; -export function getOctokitClient(): Octokit { +export function getOctokitClient(password?: string): Octokit { if (client) return client; try { - const { GITHUB_BOT_PASSWORD } = process.env; + const GITHUB_BOT_PASSWORD = process.env.GITHUB_BOT_PASSWORD ?? password; if (!GITHUB_BOT_PASSWORD) throw new Error('GITHUB_BOT_PASSWORD is not defined'); diff --git a/src/commands/src/helpers/dependency-helpers.ts b/src/commands/src/helpers/dependency-helpers.ts index 5e15be23b..17da25acd 100644 --- a/src/commands/src/helpers/dependency-helpers.ts +++ b/src/commands/src/helpers/dependency-helpers.ts @@ -7,14 +7,21 @@ import { BuildDependencies } from '../../../entities/job'; const existsAsync = promisify(fs.exists); const writeFileAsync = promisify(fs.writeFile); -async function cloneRepo(repoName: string) { - await executeCliCommand({ - command: 'git', - args: ['clone', `https://github.com/mongodb/${repoName}`], - options: { cwd: `${process.cwd()}/repos` }, - }); -} -async function createEnvProdFile(repoDir: string, projectName: string, baseUrl: string, prefix = '') { +async function createEnvProdFile({ + repoDir, + projectName, + baseUrl, + prefix = '', + patchId, + commitHash, +}: { + repoDir: string; + projectName: string; + baseUrl: string; + prefix?: string; + patchId?: string; + commitHash?: string; +}) { const prodFileName = `${process.cwd()}/snooty/.env.production`; try { @@ -22,14 +29,16 @@ async function createEnvProdFile(repoDir: string, projectName: string, baseUrl: prodFileName, `GATSBY_SITE=${projectName} GATSBY_MANIFEST_PATH=${repoDir}/bundle.zip - GATSBY_PARSER_USER=${process.env.USER} + GATSBY_PARSER_USER=${process.env.USER ?? 'docsworker-xlarge'} GATSBY_BASE_URL=${baseUrl} GATSBY_MARIAN_URL=${process.env.GATSBY_MARIAN_URL} - PATH_PREFIX=${prefix}`, + PATH_PREFIX=${prefix} + ${patchId ? `PATCH_ID=${patchId}` : ''} + ${commitHash ? `COMMIT_HASH=${commitHash}` : ''}`, 'utf8' ); } catch (e) { - console.error(`ERROR! Could not write to .env.production`); + console.error(`ERROR! Could not write to .env.production: ${e}`); throw e; } } @@ -78,14 +87,12 @@ export async function prepareBuildAndGetDependencies( repoName: string, projectName: string, baseUrl: string, - buildDependencies: BuildDependencies + buildDependencies: BuildDependencies, + directory?: string ) { - // before we get build dependencies, we need to clone the repo - await cloneRepo(repoName); - - const repoDir = getRepoDir(repoName); - + const repoDir = getRepoDir(repoName, directory); await downloadBuildDependencies(buildDependencies, repoName); + console.log('Downloaded Build dependencies'); // doing these in parallel const commandPromises = [ @@ -93,11 +100,17 @@ export async function prepareBuildAndGetDependencies( getCommitBranch(repoDir), getPatchId(repoDir), existsAsync(path.join(process.cwd(), 'config/redirects')), - createEnvProdFile(repoDir, projectName, baseUrl), ]; try { const dependencies = await Promise.all(commandPromises); + await createEnvProdFile({ + repoDir, + projectName, + baseUrl, + commitHash: dependencies[1] as string | undefined, + patchId: dependencies[2] as string | undefined, + }); return { commitHash: dependencies[0] as string, @@ -108,7 +121,7 @@ export async function prepareBuildAndGetDependencies( repoDir, }; } catch (error) { - console.error('ERROR! Could not get build dependencies'); + console.error(`Error: Could not get build deps: ${error}`); throw error; } } diff --git a/src/commands/src/helpers/index.ts b/src/commands/src/helpers/index.ts index 4089b2178..dd22ad760 100644 --- a/src/commands/src/helpers/index.ts +++ b/src/commands/src/helpers/index.ts @@ -20,7 +20,7 @@ export class ExecuteCommandError extends Error { } } -interface CliCommandParams { +export interface CliCommandParams { command: string; args?: readonly string[]; options?: SpawnOptions; @@ -167,13 +167,16 @@ export async function executeCliCommand({ if (writeStream) executedCommand.stdout?.pipe(writeStream); executedCommand.stdout?.on('data', (data: Buffer) => { outputText.push(data.toString()); + console.log(data.toString()); }); executedCommand.stderr?.on('data', (data: Buffer) => { errorText.push(data.toString()); + console.log(data.toString()); }); executedCommand.on('error', (err) => { + console.log(`ERROR in executeCliCommand.\nCommand: ${command} ${args.join(' ')}\nError: ${err}`); reject(new ExecuteCommandError('The command failed', err)); }); @@ -181,7 +184,7 @@ export async function executeCliCommand({ if (writeStream) writeStream.end(); if (exitCode !== 0) { - console.error(`ERROR! The command ${command} closed with an exit code other than 0: ${exitCode}.`); + console.error(`ERROR! The command "${command}" closed with an exit code other than 0: ${exitCode}.`); console.error('Arguments provided: ', args); console.error('Options provided: ', options); @@ -193,7 +196,17 @@ export async function executeCliCommand({ console.error(errorText.join('')); } - reject(new ExecuteCommandError('The command failed', exitCode)); + reject( + new ExecuteCommandError( + `The command failed.\n + ERROR! The command ${command} closed with an exit code other than 0: ${exitCode}.\n + Arguments provided: ${args}\n + Options provided: ${JSON.stringify(options, null, 4)}\n + Stdout: ${outputText.join('')} \n + Error: ${errorText.join('')}`, + exitCode + ) + ); return; } @@ -249,31 +262,42 @@ export async function getPatchId(repoDir: string): Promise { return gitPatchId.slice(0, 7); } catch (err) { - console.warn('No patch ID found'); + console.log('No patch ID found: ' + err); } } -export async function getCommitBranch(repoDir: string): Promise { - // equivalent to git rev-parse --abbrev-ref HEAD - const response = await executeCliCommand({ - command: 'git', - args: ['rev-parse', '--abbrev-ref', 'HEAD'], - options: { cwd: repoDir }, - }); +export async function getCommitBranch(repoDir: string): Promise { + try { + // equivalent to git rev-parse --abbrev-ref HEAD + const response = await executeCliCommand({ + command: 'git', + args: ['rev-parse', '--abbrev-ref', 'HEAD'], + options: { cwd: repoDir }, + }); - return response.outputText; + return response.outputText; + } catch (err) { + console.log(`ERROR in getCommitBranch: ${err}`); + throw Error; + } } -export async function getCommitHash(repoDir: string): Promise { - // equivalent to git rev-parse --short HEAD - const response = await executeCliCommand({ - command: 'git', - args: ['rev-parse', '--short', 'HEAD'], - options: { cwd: repoDir }, - }); +export async function getCommitHash(repoDir: string): Promise { + try { + // equivalent to git rev-parse --short HEAD + const response = await executeCliCommand({ + command: 'git', + args: ['rev-parse', '--short', 'HEAD'], + options: { cwd: repoDir }, + }); - return response.outputText; + return response.outputText; + } catch (err) { + console.log(`ERROR in getCommitHash: ${err}`); + throw Error; + } } export const checkIfPatched = async (repoDir: string) => !existsAsync(path.join(repoDir, 'myPatch.patch')); -export const getRepoDir = (repoName: string) => path.join(process.cwd(), `repos/${repoName}`); +export const getRepoDir = (repoName: string, directory?: string) => + path.join(process.cwd(), `/repos/${repoName}${directory ? `/${directory}` : ''}`); diff --git a/src/commands/src/scripts/local-build/index.ts b/src/commands/src/scripts/local-build/index.ts new file mode 100644 index 000000000..fc5b2c846 --- /dev/null +++ b/src/commands/src/scripts/local-build/index.ts @@ -0,0 +1,84 @@ +import os from 'os'; +import * as c from 'config'; +import { MongoClient } from 'mongodb'; +import { getOctokitClient } from '../../../../clients/githubClient'; +import { executeCliCommand } from '../../helpers'; +import { getArgs } from './utils/get-args'; +import { getWorkerEnv } from './utils/get-env-vars'; +import { createLocalJob } from './utils/create-job'; +import { DocsetsRepository } from '../../../../repositories/docsetsRepository'; +import { ConsoleLogger } from '../../../../services/logger'; + +const buildDockerImage = async (npmAuth: string) => + executeCliCommand({ + command: 'docker', + args: [ + 'buildx', + 'build', + '--file', + 'Dockerfile.local', + '.', + '--build-arg', + `NPM_BASE_64_AUTH=${npmAuth}`, + '--build-arg', + 'NPM_EMAIL=docs-platform', + '-t', + 'autobuilder/local:latest', + ], + }); + +async function runDockerContainer(env: Record) { + const args = ['run', '-p', '9229:9229', '--rm', '-v', `${os.homedir()}/.aws:/home/docsworker-xlarge/.aws`]; + + for (const envName in env) { + args.push('-e'); + args.push(`${envName}=${env[envName]}`); + } + + args.push('autobuilder/local:latest'); + return executeCliCommand({ + command: 'docker', + args, + }); +} + +async function main() { + const { repoName, repoOwner, directory, branchName } = getArgs(); + + const env = await getWorkerEnv('stg'); + const octokitClient = getOctokitClient(env.GITHUB_BOT_PASSWORD); + + const commitPromise = octokitClient.request('GET /repos/{owner}/{repo}/commits/{ref}', { + owner: repoOwner, + repo: repoName, + ref: branchName, + headers: { + 'X-GitHub-Api-Version': '2022-11-28', + }, + }); + + const buildPromise = buildDockerImage(env.NPM_BASE_64_AUTH); + const dbClient = new MongoClient(env.MONGO_ATLAS_URL); + + console.log('Building docker container....'); + const [commit, connectedDbClient] = await Promise.all([commitPromise, dbClient.connect(), buildPromise]); + console.log('build complete'); + const db = connectedDbClient.db(env.DB_NAME); + const collection = db.collection(env.JOB_QUEUE_COL_NAME); + + const consoleLogger = new ConsoleLogger(); + + const docsetsRepository = new DocsetsRepository(db, c, consoleLogger); + const project = (await docsetsRepository.getProjectByRepoName(repoName, directory)) as string; + + const job = createLocalJob({ commit: commit.data, branchName, repoName, repoOwner, project, directory }); + + console.log('inserting job into queue collection'); + const { insertedId: jobId } = await collection.insertOne(job); + + console.log('starting container'); + await runDockerContainer({ ...env, jobId: jobId.toString() }); + console.log('Job complete. Please press CTRL+C to exit.'); +} + +main(); diff --git a/src/commands/src/scripts/local-build/utils/create-job.ts b/src/commands/src/scripts/local-build/utils/create-job.ts new file mode 100644 index 000000000..2a06538a5 --- /dev/null +++ b/src/commands/src/scripts/local-build/utils/create-job.ts @@ -0,0 +1,53 @@ +import { EnhancedJob, JobStatus } from '../../../../../entities/job'; +import { CommitGetResponse } from './types'; + +interface Props { + branchName: string; + repoOwner: string; + repoName: string; + commit: CommitGetResponse; + project: string; + directory?: string; +} + +export function createLocalJob({ + branchName, + repoName, + repoOwner, + commit, + project, + directory, +}: Props): Omit { + return { + isLocal: true, + title: `${repoOwner}/${repoName}`, + user: commit.author?.name ?? '', + email: commit.author?.email ?? '', + status: JobStatus.inQueue, + createdTime: new Date(), + startTime: null, + endTime: null, + priority: 1, + error: {}, + result: null, + pathPrefix: `${project}/docsworker-xlarge/${branchName}`, + payload: { + jobType: 'githubPush', + source: 'github', + action: 'push', + repoName, + branchName, + isFork: repoOwner !== '10gen' && repoOwner !== 'mongodb', + repoOwner, + url: commit.url, + newHead: commit.sha, + urlSlug: branchName, + prefix: '', + project: project, + pathPrefix: `${project}/docsworker-xlarge/${branchName}`, + mutPrefix: project, + directory: directory, + }, + logs: [], + }; +} diff --git a/src/commands/src/scripts/local-build/utils/get-args.ts b/src/commands/src/scripts/local-build/utils/get-args.ts new file mode 100644 index 000000000..ac840ac28 --- /dev/null +++ b/src/commands/src/scripts/local-build/utils/get-args.ts @@ -0,0 +1,62 @@ +export function getArgs() { + const helpIdx = process.argv.findIndex((str) => str === '--help' || str === '-h'); + + if (helpIdx !== -1) { + console.log(` + This command builds and runs the Autobuilder for local debugging. + + Flags: + --repo-owner, -o (required) The owner of the repo. Typically this is 'mongodb' or '10gen'. This should be your username for a fork. + --repo-name, -n (required) The name of the repo e.g. docs-java or cloud-docs. + --directory, -d (optional) The project directory path for a monorepo project. A slash is not needed at the beginning. For example, cloud-docs in the monorepo would just be cloud-docs for the argument. + --branch-name, -b (optional) The branch name we want to parse. If not provided, the value 'master' is used by default. + `); + + process.exit(0); + } + const repoOwnerIdx = process.argv.findIndex((str) => str === '--repo-owner' || str === '-o'); + const repoNameIdx = process.argv.findIndex((str) => str === '--repo-name' || str === '-n'); + + // optional args + const directoryIdx = process.argv.findIndex((str) => str === '--directory' || str === '-d'); + const branchNameIdx = process.argv.findIndex((str) => str === '--branch-name' || str === '-b'); + + if (repoOwnerIdx === -1) + throw new Error( + 'Please provide a repo owner. The flag to provide this is --repo-owner, or you can use -o as well.' + ); + + if (repoNameIdx === -1) + throw new Error('Please provide a repo name. The flag to provide this is --repo-name, or you can use -n as well.'); + + if (repoOwnerIdx + 1 === process.argv.length) throw new Error('Please provide a value for the repo owner flag'); + if (process.argv[repoOwnerIdx + 1].startsWith('-')) + throw new Error(`Please provide a valid repo owner value. Value provided: ${process.argv[repoOwnerIdx + 1]}`); + + if (repoNameIdx + 1 === process.argv.length) throw new Error('Please provide a value for the repo name flag'); + if (process.argv[repoNameIdx + 1].startsWith('-')) + throw new Error(`Please provide a valid repo name value. Value provided: ${process.argv[repoNameIdx + 1]}`); + + if (directoryIdx + 1 === process.argv.length) + throw new Error('Please provide a value for the monorepo directory flag'); + if (process.argv[directoryIdx + 1].startsWith('-')) + throw new Error( + `Please provide a valid monorepo directory value. Value provided: ${process.argv[directoryIdx + 1]}` + ); + + if (branchNameIdx + 1 === process.argv.length) throw new Error('Please provide a value for the branch name flag'); + if (process.argv[branchNameIdx + 1].startsWith('-')) + throw new Error(`Please provide a valid branch name value. Value provided: ${process.argv[branchNameIdx + 1]}`); + + const repoOwner = process.argv[repoOwnerIdx + 1]; + const repoName = process.argv[repoNameIdx + 1]; + const directory = directoryIdx !== -1 ? process.argv[directoryIdx + 1] : undefined; + const branchName = branchNameIdx !== -1 ? process.argv[branchNameIdx + 1] : 'master'; + + return { + repoOwner, + repoName, + directory, + branchName, + }; +} diff --git a/src/commands/src/scripts/local-build/utils/get-env-vars.ts b/src/commands/src/scripts/local-build/utils/get-env-vars.ts new file mode 100644 index 000000000..37d401ec9 --- /dev/null +++ b/src/commands/src/scripts/local-build/utils/get-env-vars.ts @@ -0,0 +1,174 @@ +import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'; + +// This array contains the Parameter Store paths of the secure strings +// we want to add to the worker environment. These are mapped +// to their environment variable name in the workerParamPathToEnvName map. +const workerParamStrings = [ + '/npm/auth', + '/github/webhook/secret', + '/github/bot/password', + '/atlas/password', + '/fastly/docs/dochub/token', + '/npm/auth', + '/fastly/docs/dochub/service_id', + '/fastly/dochub_map', + '/fastly/docs/main/token', + '/fastly/docs/main/service_id', + '/fastly/docs/cloudmanager/token', + '/fastly/docs/cloudmanager/service_id', + '/fastly/docs/atlas/token', + '/fastly/docs/atlas/service_id', + '/fastly/docs/opsmanager/token', + '/fastly/docs/opsmanager/service_id', + '/cdn/client/id', + '/cdn/client/secret', + '/atlas/dbname', + '/atlas/collections/snooty', + '/atlas/username', + '/atlas/host', + '/flag/preview_webhook_enable', + '/flag/hide_locale', + '/flag/use_chatbot', + '/github/bot/username', + '/npm/email', + '/frontend/base_url', + '/flag/preview_build/enabled', + '/flag/update_pages', + '/flag/monorepo_path', + '/atlas/collections/repo', + '/atlas/collections/docsets', + '/atlas/collections/job/queue', + '/atlas/collections/user/entitlements', +] as const; + +type WorkerParamString = (typeof workerParamStrings)[number]; +const workerParamPathToEnvName: Record = { + '/npm/auth': 'NPM_BASE_64_AUTH', + '/github/webhook/secret': 'GITHUB_SECRET', + '/github/bot/password': 'GITHUB_BOT_PASSWORD', + '/atlas/password': 'MONGO_ATLAS_PASSWORD', + '/fastly/docs/dochub/token': 'FASTLY_DOCHUB_TOKEN', + '/fastly/docs/dochub/service_id': 'FASTLY_DOCHUB_SERVICE_ID', + '/fastly/dochub_map': 'FASTLY_DOCHUB_MAP', + '/fastly/docs/main/token': 'FASTLY_MAIN_TOKEN', + '/fastly/docs/main/service_id': 'FASTLY_MAIN_SERVICE_ID', + '/fastly/docs/cloudmanager/token': 'FASTLY_CLOUD_MANAGER_TOKEN', + '/fastly/docs/cloudmanager/service_id': 'FASTLY_CLOUD_MANAGER_SERVICE_ID', + '/fastly/docs/atlas/token': 'FASTLY_ATLAS_TOKEN', + '/fastly/docs/atlas/service_id': 'FASTLY_ATLAS_SERVICE_ID', + '/fastly/docs/opsmanager/token': 'FASTLY_OPS_MANAGER_TOKEN', + '/fastly/docs/opsmanager/service_id': 'FASTLY_OPS_MANAGER_SERVICE_ID', + '/cdn/client/id': 'CDN_CLIENT_ID', + '/cdn/client/secret': 'CDN_CLIENT_SECRET', + '/atlas/collections/docsets': 'DOCSETS_COL_NAME', + '/atlas/dbname': 'DB_NAME', + '/atlas/collections/snooty': 'SNOOTY_DB_NAME', + '/atlas/username': 'MONGO_ATLAS_USERNAME', + '/atlas/host': 'MONGO_ATLAS_HOST', + '/github/bot/username': 'GITHUB_BOT_USERNAME', + '/frontend/base_url': 'GATSBY_BASE_URL', + '/flag/preview_build/enabled': 'PREVIEW_BUILD_ENABLED', + '/flag/update_pages': 'FEATURE_FLAG_UPDATE_PAGES', + '/flag/monorepo_path': 'FEATURE_FLAG_MONOREPO_PATH', + '/atlas/collections/user/entitlements': 'USER_ENTITLEMENT_COL_NAME', + '/npm/email': 'NPM_EMAIL', + '/atlas/collections/repo': 'REPO_BRANCHES_COL_NAME', + '/flag/use_chatbot': 'GATSBY_SHOW_CHATBOT', + '/flag/hide_locale': 'GATSBY_HIDE_UNIFIED_FOOTER_LOCALE', + '/atlas/collections/job/queue': 'JOB_QUEUE_COL_NAME', + '/flag/preview_webhook_enable': 'GATSBY_CLOUD_PREVIEW_WEBHOOK_ENABLED', +}; + +async function getSecureStrings( + ssmPrefix: string, + params: readonly string[], + paramToEnvMap: Record, + resourceName: string +): Promise> { + const ssmClient = new SSMClient({ region: 'us-east-2' }); + + const paramsMap: Record = {}; + + await Promise.all( + params.map(async (paramName: string) => { + const getParamCommand = new GetParameterCommand({ + Name: `${ssmPrefix}${paramName}`, + WithDecryption: true, + }); + + const ssmResponse = await ssmClient.send(getParamCommand); + const paramValue = ssmResponse.Parameter?.Value; + + if (!paramValue) { + console.error(`ERROR! Could not retrieve string for the following param: ${paramName}`); + return; + } + + const envName = paramToEnvMap[paramName]; + + if (!envName) { + console.error( + `ERROR! The param '${paramName}' does not having a mapping to an environment variable name. Please define this in the ${resourceName} map.` + ); + return; + } + + paramsMap[envName] = paramValue; + }) + ); + + return paramsMap; +} + +const snootyEnvs = ['staging', 'production', 'dotcomstg', 'dotcomprd', 'legacydotcomprd', 'legacydotcomstg'] as const; +const autoBuilderEnvs = ['stg', 'prd', 'dev', 'dotcomstg', 'dotcomprd', 'legacydotcomstg', 'legacydotcomprd'] as const; + +type SnootyEnv = (typeof snootyEnvs)[number]; +type AutoBuilderEnv = (typeof autoBuilderEnvs)[number]; + +const isAutoBuilderEnv = (str: string): str is AutoBuilderEnv => autoBuilderEnvs.includes(str as AutoBuilderEnv); + +const autoBuilderToSnootyEnvMap: Record = { + stg: 'staging', + dev: 'staging', + prd: 'production', + dotcomprd: 'dotcomprd', + dotcomstg: 'dotcomstg', + legacydotcomstg: 'legacydotcomstg', + legacydotcomprd: 'legacydotcomprd', +}; + +function envShortToFullName(env: string): SnootyEnv { + if (!isAutoBuilderEnv(env)) throw new Error(`ERROR! ${env} is not a valid env`); + + return autoBuilderToSnootyEnvMap[env]; +} +function getCdnInvalidatorUrl(env: AutoBuilderEnv): string { + return `https://cdnvalidator.${ + env === 'dotcomprd' || env === 'prd' ? 'prod' : 'staging' + }.staging.corp.mongodb.com/api/v1beta1/distributions/${env}/invalidations`; +} + +export async function getWorkerEnv(env: AutoBuilderEnv): Promise> { + const envRecord = await getSecureStrings( + `/env/${env}/docs/worker_pool`, + workerParamStrings, + workerParamPathToEnvName, + 'workerParamPathToEnvName' + ); + + // TODO: Add JOB_UPDATES_QUEUE_URL. Can retrieve with https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cloudformation/command/DescribeStacksCommand/ + return { + ...envRecord, + SNOOTY_ENV: envShortToFullName(env), + SEARCH_INDEX_BUCKET: 'docs-search-indexes-test', + CDN_INVALIDATOR_SERVICE_URL: getCdnInvalidatorUrl(env), + MONGO_ATLAS_URL: `mongodb+srv://${envRecord.MONGO_ATLAS_USERNAME}:${envRecord.MONGO_ATLAS_PASSWORD}@${envRecord.MONGO_ATLAS_HOST}/admin?retryWrites=true`, + STAGE: env, + MONGO_TIMEOUT_S: '3000', + IS_LOCAL: 'true', + ENHANCED: 'true', + JOB_UPDATES_QUEUE_URL: + 'https://sqs.us-east-2.amazonaws.com/216656347858/auto-builder-stack-enhancedApp-dotcom-queuesJobUpdatesQueue60725415-k32LRG3HnCHm', // temp hardcode + }; +} diff --git a/src/commands/src/scripts/local-build/utils/types.ts b/src/commands/src/scripts/local-build/utils/types.ts new file mode 100644 index 000000000..aaacab934 --- /dev/null +++ b/src/commands/src/scripts/local-build/utils/types.ts @@ -0,0 +1,3 @@ +import { RestEndpointMethodTypes } from '@octokit/rest'; + +export type CommitGetResponse = RestEndpointMethodTypes['repos']['getCommit']['response']['data']; diff --git a/src/commands/src/shared/next-gen-deploy.ts b/src/commands/src/shared/next-gen-deploy.ts index d980e1d1f..5d86baf73 100644 --- a/src/commands/src/shared/next-gen-deploy.ts +++ b/src/commands/src/shared/next-gen-deploy.ts @@ -1,38 +1,65 @@ +import { CommandExecutorResponse, CommandExecutorResponseStatus } from '../../../services/commandExecutor'; import { executeAndPipeCommands, executeCliCommand } from '../helpers'; interface NextGenDeployParams { - bucket: string; mutPrefix: string; gitBranch: string; hasConfigRedirects: boolean; + bucket: string; url: string; } -export async function nextGenDeploy({ bucket, mutPrefix, gitBranch, hasConfigRedirects, url }: NextGenDeployParams) { - if (hasConfigRedirects && (gitBranch === 'main' || gitBranch === 'master')) { - // equivalent to: mut-redirects config/redirects -o public/.htaccess - await executeCliCommand({ command: 'mut-redirects', args: ['config/redirects', '-o', 'public/.htaccess'] }); - } - - // equivalent to: yes | mut-publish public ${BUCKET} --prefix="${MUT_PREFIX}" --deploy --deployed-url-prefix=${URL} --json --all-subdirectories ${ARGS}; - const { outputText } = await executeAndPipeCommands( - { command: 'yes' }, - { - command: 'mut-publish', - args: [ - 'public', - bucket, - `--prefix=${mutPrefix}`, - '--deploy', - `--deployed-url-prefix=${url}`, - '--json', - '--all-subdirectories', - ], - options: { - cwd: `${process.cwd()}/snooty`, - }, +/* This is still in development - use with caution */ +/* Logs here for future debugging purposes */ +export async function nextGenDeploy({ + mutPrefix, + gitBranch, + hasConfigRedirects, + bucket, + url, +}: NextGenDeployParams): Promise { + try { + if (hasConfigRedirects && (gitBranch === 'main' || gitBranch === 'master')) { + // equivalent to: mut-redirects config/redirects -o public/.htaccess + await executeCliCommand({ command: 'mut-redirects', args: ['config/redirects', '-o', 'public/.htaccess'] }); + console.log(`COMMAND: mut-redirects config/redirects -o public/.htaccess`); } - ); - return `${outputText}\n Hosted at ${url}/${mutPrefix}`; + // equivalent to: yes | mut-publish public ${BUCKET} --prefix=${MUT_PREFIX} --deploy --deployed-url-prefix=${URL} --json --all-subdirectories ${ARGS}; + const { outputText } = await executeAndPipeCommands( + { command: 'yes' }, + { + command: 'mut-publish', + args: [ + 'public', + bucket, + `--prefix=${mutPrefix}`, + '--deploy', + `--deployed-url-prefix=${url}`, + '--json', + '--all-subdirectories', + '--dry-run', + ], + options: { + cwd: `${process.cwd()}/snooty`, + }, + } + ); + console.log( + `COMMAND: yes | mut-publish public ${bucket} --prefix=${mutPrefix} --deploy --deployed-url-prefix=${url} --json --all-subdirectories --dry-run` + ); + console.log(`${outputText}\n Hosted at ${url}/${mutPrefix}`); + return { + status: CommandExecutorResponseStatus.success, + output: outputText, + error: '', + }; + } catch (error) { + console.log(`nextGenDeploy has failed.`); + return { + status: CommandExecutorResponseStatus.failed, + output: 'Failed in nextGenDeploy', + error: error?.message || '', + }; + } } diff --git a/src/commands/src/shared/next-gen-html.ts b/src/commands/src/shared/next-gen-html.ts index 226a14a97..fc790f41b 100644 --- a/src/commands/src/shared/next-gen-html.ts +++ b/src/commands/src/shared/next-gen-html.ts @@ -1,11 +1,14 @@ -import { executeCliCommand } from '../helpers'; +import { CliCommandResponse, executeCliCommand } from '../helpers'; -export async function nextGenHtml() { - const result = await executeCliCommand({ - command: 'npm', - args: ['run', 'build'], - options: { cwd: `${process.cwd()}/snooty` }, - }); - - return result; +export async function nextGenHtml(): Promise { + try { + const result = await executeCliCommand({ + command: 'npm', + args: ['run', 'build'], + options: { cwd: `${process.cwd()}/snooty` }, + }); + return result; + } catch (error) { + throw new Error(`next-gen-html failed. \n ${error}`); + } } diff --git a/src/commands/src/shared/next-gen-parse.ts b/src/commands/src/shared/next-gen-parse.ts index 5fd6b6c01..12467d04c 100644 --- a/src/commands/src/shared/next-gen-parse.ts +++ b/src/commands/src/shared/next-gen-parse.ts @@ -1,33 +1,42 @@ +import path from 'path'; +import { Job } from '../../../entities/job'; +import { getDirectory } from '../../../job/jobHandler'; import { CliCommandResponse, executeCliCommand } from '../helpers'; const RSTSPEC_FLAG = '--rstspec=https://raw.githubusercontent.com/mongodb/snooty-parser/latest/snooty/rstspec.toml'; interface NextGenParseParams { - repoDir: string; - commitHash: string; + job: Job; patchId?: string; isProd?: boolean; } -export async function nextGenParse({ - repoDir, - patchId, - commitHash, - isProd, -}: NextGenParseParams): Promise { - const commandArgs = ['build', repoDir, '--output', `${repoDir}/bundle.zip`, RSTSPEC_FLAG]; +export async function nextGenParse({ job, patchId, isProd }: NextGenParseParams): Promise { + const repoDir = path.resolve(process.cwd(), `repos/${getDirectory(job)}`); + const commitHash = job.payload.newHead; - if (patchId) { + const commandArgs = ['build', repoDir, '--output', `${repoDir}/bundle.zip`]; + + if (patchId && commitHash) { commandArgs.push('--commit'); commandArgs.push(commitHash); commandArgs.push('--patch'); commandArgs.push(patchId); } + commandArgs.push(RSTSPEC_FLAG); // Not currently used in production builds, adding functionality // now so that it is available when it is. if (isProd) { commandArgs.push('--no-caching'); } - - return executeCliCommand({ command: 'snooty', args: commandArgs }); + try { + const result = await executeCliCommand({ + command: 'snooty', + args: commandArgs, + options: { cwd: repoDir }, + }); + return result; + } catch (error) { + throw new Error(`next-gen-parse failed. \n ${error}`); + } } diff --git a/src/commands/src/shared/next-gen-stage.ts b/src/commands/src/shared/next-gen-stage.ts index ff1acffdf..9c12dc66a 100644 --- a/src/commands/src/shared/next-gen-stage.ts +++ b/src/commands/src/shared/next-gen-stage.ts @@ -1,46 +1,74 @@ -import { executeCliCommand } from '../helpers'; +import { Job } from '../../../entities/job'; +import { CommandExecutorResponse, CommandExecutorResponseStatus } from '../../../services/commandExecutor'; +import { executeCliCommand, getRepoDir } from '../helpers'; const DOCS_WORKER_USER = 'docsworker-xlarge'; interface StageParams { - repoDir: string; - mutPrefix: string; - projectName: string; - bucket: string; - url: string; - patchId?: string; - commitBranch: string; - commitHash: string; + job: Job; + bucket?: string; + url?: string; } -export async function nextGenStage({ - mutPrefix, - projectName, - bucket, - url, - patchId, - commitBranch, - commitHash, -}: StageParams) { - let hostedAtUrl = `${url}/${mutPrefix}/${DOCS_WORKER_USER}/${commitBranch}/`; - let prefix = mutPrefix; +export async function nextGenStage({ job, bucket, url }: StageParams): Promise { + const { mutPrefix, branchName, project, newHead, patchId } = job.payload; + + if (!bucket) { + console.log(`nextGenStage has failed. Variable for S3 bucket address was undefined.`); + return { + status: CommandExecutorResponseStatus.failed, + output: 'Failed in nextGenStage: No value present for S3 bucket', + error: 'ERROR: No value present for S3 bucket.', + }; + } + if (!url) { + console.log(`nextGenStage has failed. Variable for URL address was undefined.`); + return { + status: CommandExecutorResponseStatus.failed, + output: 'Failed in nextGenStage: No value present for target url.', + error: 'ERROR: No value present for URL.', + }; + } + + let prefix = mutPrefix || project; + let hostedAtUrl = `${url}/${prefix}/${DOCS_WORKER_USER}/${branchName}/`; const commandArgs = ['public', bucket, '--stage']; - if (patchId && projectName === mutPrefix) { - prefix = `${commitHash}/${patchId}/${mutPrefix}`; - hostedAtUrl = `${url}/${commitHash}/${patchId}/${mutPrefix}/${DOCS_WORKER_USER}/${commitBranch}/`; + if (patchId && newHead && project === mutPrefix) { + prefix = `${newHead}/${patchId}/${mutPrefix}`; + hostedAtUrl = `${url}/${newHead}/${patchId}/${mutPrefix}/${DOCS_WORKER_USER}/${branchName}/`; } - commandArgs.push(`--prefix="${prefix}"`); + commandArgs.push(`--prefix=${prefix}`); - const { outputText } = await executeCliCommand({ - command: 'mut-publish', - args: commandArgs, - options: { - cwd: `${process.cwd()}/snooty`, - }, - }); + const repoDir = getRepoDir(job.payload.repoName, job.payload.directory); + try { + await executeCliCommand({ + command: 'cp', + args: ['-r', `${process.cwd()}/snooty/public`, repoDir], + }); - const resultMessage = `${outputText}\n Hosted at ${hostedAtUrl}`; - return resultMessage; + const { outputText, errorText } = await executeCliCommand({ + command: 'mut-publish', + args: commandArgs, + options: { + cwd: repoDir, + }, + }); + + const resultMessage = `${outputText}\n Hosted at ${hostedAtUrl}\n\nHere are the commands: ${commandArgs}`; + + return { + status: CommandExecutorResponseStatus.success, + output: resultMessage, + error: errorText, + }; + } catch (error) { + console.log(`Failed in nextGenStage.`); + return { + status: CommandExecutorResponseStatus.failed, + output: 'Failed in nextGenStage', + error: 'ERROR: Failed in nextGenStage', + }; + } } diff --git a/src/commands/src/shared/oas-page-build.ts b/src/commands/src/shared/oas-page-build.ts index 5950a27f2..e51b235da 100644 --- a/src/commands/src/shared/oas-page-build.ts +++ b/src/commands/src/shared/oas-page-build.ts @@ -1,28 +1,38 @@ -import { executeCliCommand } from '../helpers'; +import { Job } from '../../../entities/job'; +import { CliCommandResponse, executeCliCommand, getRepoDir } from '../helpers'; interface OasPageBuildParams { - bundlePath: string; - repoDir: string; - siteUrl: string; + job: Job; + baseUrl: string; } -export async function oasPageBuild({ bundlePath, repoDir, siteUrl }: OasPageBuildParams) { - const { outputText } = await executeCliCommand({ - command: 'node', - args: [ - `${process.cwd()}/modules/oas-page-builder/dist/index.js`, - '--bundle', - bundlePath, - '--repo', - repoDir, - '--output', - `${repoDir}/public`, - '--redoc', - `${process.cwd()}/redoc/cli/index.js`, - '--site-url', - siteUrl, - ], - }); +export async function oasPageBuild({ job, baseUrl }: OasPageBuildParams): Promise { + const siteUrl = job.payload.mutPrefix + ? `${baseUrl}/${job.payload.mutPrefix}` + : `${baseUrl}/${job.payload.project}/docsworker-xlarge/${job.payload.branchName}`; + const repoDir = getRepoDir(job.payload.repoName, job.payload.directory); + const bundlePath = `${repoDir}/bundle.zip`; - return outputText; + try { + const result = await executeCliCommand({ + command: 'node', + args: [ + `${process.cwd()}/modules/oas-page-builder/index.js`, + '--bundle', + bundlePath, + '--output', + `${repoDir}/public`, + '--redoc', + `${process.cwd()}/redoc/cli/index.js`, + '--repo', + repoDir, + '--site-url', + siteUrl, + ], + }); + + return result; + } catch (error) { + throw new Error(`oas-page-build failed. \n ${error}`); + } } diff --git a/src/commands/src/shared/persistence-module.ts b/src/commands/src/shared/persistence-module.ts index e1b7851e9..2498a2b18 100644 --- a/src/commands/src/shared/persistence-module.ts +++ b/src/commands/src/shared/persistence-module.ts @@ -1,33 +1,36 @@ -import { executeCliCommand } from '../helpers'; +import { Job } from '../../../entities/job'; +import { CliCommandResponse, executeCliCommand, getRepoDir } from '../helpers'; interface PersistenceModuleParams { - bundlePath: string; - jobId?: string; - repoOwner?: string; + job: Job; } -export async function persistenceModule({ - bundlePath, - jobId, - repoOwner = 'docs-builder-bot', -}: PersistenceModuleParams) { +export async function persistenceModule({ job }: PersistenceModuleParams): Promise { + const githubUser = job.payload.repoOwner; + const repoDir = getRepoDir(job.payload.repoName, job.payload.directory); + const bundlePath = `${repoDir}/bundle.zip`; + const args = [ - `${process.cwd()}/modules/persistence/dist/index.js`, + `${process.cwd()}/modules/persistence/index.js`, '--unhandled-rejections=strict', '--path', bundlePath, '--githubUser', - repoOwner, + githubUser, ]; - if (jobId) { + if (job._id) { args.push('--jobId'); - args.push(jobId); + args.push(job._id); } - const { outputText } = await executeCliCommand({ - command: 'node', - args, - }); + try { + const result = await executeCliCommand({ + command: 'node', + args, + }); - return outputText; + return result; + } catch (error) { + throw new Error(`oas-page-build failed. \n ${error}`); + } } diff --git a/src/enhanced/enhancedApp.ts b/src/enhanced/enhancedApp.ts index e1963d472..07209d70b 100644 --- a/src/enhanced/enhancedApp.ts +++ b/src/enhanced/enhancedApp.ts @@ -42,7 +42,7 @@ async function cleanupJob(): Promise { * the `finally` block is always called after the try, even if an exception is thrown. If an exception is thrown, the cleanUp job is called, * and the exception is then thrown after. */ -async function handleJobAndCleanUp(jobId: string, db: mongodb.Db) { +export async function handleJobAndCleanUp(jobId: string, db: mongodb.Db) { try { await handleJob(jobId, db); } finally { diff --git a/src/entities/job.ts b/src/entities/job.ts index 2fcd0c27f..fc5be5c7b 100644 --- a/src/entities/job.ts +++ b/src/entities/job.ts @@ -56,6 +56,7 @@ export type Payload = { project: string; includeInGlobalSearch: boolean; directory?: string; + patchId?: string; }; export type EnhancedPayload = { @@ -84,6 +85,8 @@ export type EnhancedPayload = { prefix: string; project: string; includeInGlobalSearch?: boolean; + directory?: string; + patchId?: string; }; export type Job = { diff --git a/src/entrypoints/localApp.ts b/src/entrypoints/localApp.ts deleted file mode 100644 index 753f34904..000000000 --- a/src/entrypoints/localApp.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { - nextGenDeploy, - nextGenHtml, - nextGenParse, - nextGenStage, - oasPageBuild, - persistenceModule, - prepareBuildAndGetDependencies, -} from '../commands'; - -async function localApp() { - // TODO: Fetch this from repos_branches - const repoName = 'docs-java'; - const projectName = 'java'; - const baseUrl = 'https://www.mongodb.com'; - const bucket = 'docs-java-dotcomstg'; - const mutPrefix = 'docs/drivers/java/sync'; - const buildDependencies = [ - { - dependencies: [ - { - url: 'https://raw.githubusercontent.com/mongodb/docs-worker-pool/meta/publishedbranches/docs-mongodb-internal.yaml', - filename: 'published-branches.yaml', - }, - ], - }, - { - buildDir: 'source/driver-examples', - dependencies: [ - { - url: 'https://raw.githubusercontent.com/mongodb/mongo-python-driver/master/test/test_examples.py', - filename: 'test_examples.py', - }, - { - url: 'https://raw.githubusercontent.com/mongodb/motor/master/test/asyncio_tests/test_examples.py', - filename: 'test_examples_motor.py', - }, - ], - }, - ]; - - const { commitHash, patchId, bundlePath, commitBranch, hasRedirects, repoDir } = await prepareBuildAndGetDependencies( - repoName, - projectName, - baseUrl, - buildDependencies - ); - - console.log('Begin snooty build...'); - const snootyBuildRes = await nextGenParse({ repoDir, commitHash, patchId }); - - console.log(snootyBuildRes.errorText); - - console.log('snooty build complete'); - - console.log('Begin persistence-module'); - const persistenceModuleRes = await persistenceModule({ bundlePath }); - console.log(persistenceModuleRes); - console.log('persistence-module complete'); - - console.log('Begin next-gen-html...'); - - const nextGenHtmlRes = await nextGenHtml(); - console.log(nextGenHtmlRes.outputText); - - console.log('next-gen-html complete'); - - console.log('Begin oas-page-build...'); - const siteUrl = mutPrefix ? `${baseUrl}/${mutPrefix}` : `${baseUrl}`; - const oasPageBuildRes = await oasPageBuild({ repoDir, bundlePath, siteUrl }); - console.log('oas-page-build compelte'); - - console.log(oasPageBuildRes); - console.log('Begin next-gen-stage...'); - - const resultMessage = await nextGenStage({ - patchId, - commitBranch, - repoDir, - projectName, - bucket, - url: baseUrl, - mutPrefix, - commitHash, - }); - console.log(resultMessage); - console.log('next-gen-stage complete'); - - console.log('Begin next-gen-deploy...'); - const deployRes = await nextGenDeploy({ - bucket, - hasConfigRedirects: hasRedirects, - gitBranch: commitBranch, - mutPrefix, - url: baseUrl, - }); - console.log(deployRes); - console.log('next-gen-deploy complete'); -} - -localApp(); diff --git a/src/job/jobHandler.ts b/src/job/jobHandler.ts index 71558fc6b..947a5692d 100644 --- a/src/job/jobHandler.ts +++ b/src/job/jobHandler.ts @@ -1,3 +1,4 @@ +import path from 'path'; import axios, { AxiosResponse } from 'axios'; import { Payload, Job, JobStatus } from '../entities/job'; import { JobRepository } from '../repositories/jobRepository'; @@ -13,7 +14,15 @@ import { IJobValidator } from './jobValidator'; import { RepoEntitlementsRepository } from '../repositories/repoEntitlementsRepository'; import { DocsetsRepository } from '../repositories/docsetsRepository'; import { MONOREPO_NAME } from '../monorepo/utils/monorepo-constants'; +import { + nextGenHtml, + nextGenParse, + oasPageBuild, + persistenceModule, + prepareBuildAndGetDependencies, +} from '../commands'; import { downloadBuildDependencies } from '../commands/src/helpers/dependency-helpers'; +import { CliCommandResponse } from '../commands/src/helpers'; require('fs'); export abstract class JobHandler { @@ -204,9 +213,15 @@ export abstract class JobHandler { } @throwIfJobInterupted() - private async getAndBuildDependencies() { + private async getBuildDependencies() { const buildDependencies = await this._repoBranchesRepo.getBuildDependencies(this.currJob.payload.repoName); - if (!buildDependencies) return; + if (!buildDependencies) return []; + return buildDependencies; + } + + @throwIfJobInterupted() + private async getAndBuildDependencies() { + const buildDependencies = await this.getBuildDependencies(); const commands = await downloadBuildDependencies(buildDependencies, this.currJob.payload.repoName); this._logger.save(this._currJob._id, commands.join('\n')); } @@ -280,6 +295,26 @@ export abstract class JobHandler { } // call this method when we want benchmarks and uses cwd option to call command outside of a one liner. + private async wrapWithBenchmarks( + buildStepFunc: () => Promise, + stage: string + ): Promise { + const start = performance.now(); + + const resp = await buildStepFunc(); + + const end = performance.now(); + + const update = { + [`${stage}StartTime`]: start, + [`${stage}EndTime`]: end, + }; + + this._jobRepository.updateExecutionTime(this.currJob._id, update); + return resp; + } + + // call this method when we want benchmarks of Makefile commands and uses cwd option to call command outside of a one liner. private async callWithBenchmark(command: string, stage: string): Promise { const start = performance.now(); const pathToRepo = `repos/${getDirectory(this.currJob)}`; @@ -447,41 +482,67 @@ export abstract class JobHandler { ]; } - protected async setEnvironmentVariables(): Promise { + public async getEnvironmentVariables(): Promise<{ bucket?: string; url?: string; regression?: string }> { + let bucket: string | undefined, url: string | undefined, regression: string | undefined; + const repo_info = await this._docsetsRepo.getRepoBranchesByRepoName( this._currJob.payload.repoName, this._currJob.payload.project ); + let env = this._config.get('env'); this._logger.info( this._currJob._id, - `setEnvironmentVariables for ${getDirectory(this._currJob)} env ${env} jobType ${this._currJob.payload.jobType}` + `getEnvironmentVariables for ${getDirectory(this._currJob)} env ${env} jobType ${this._currJob.payload.jobType}` ); if (repo_info?.['bucket'] && repo_info?.['url']) { if (this._currJob.payload.regression) { env = 'regression'; - process.env.REGRESSION = 'true'; + regression = 'true'; } - process.env.BUCKET = repo_info['bucket'][env]; - process.env.URL = repo_info['url'][env]; + bucket = repo_info['bucket'][env]; + url = repo_info['url'][env]; // Writers are tying to stage it, so lets update the staging bucket. if (env == 'prd' && this._currJob.payload.jobType == 'githubPush') { - process.env.BUCKET = repo_info['bucket'][env] + '-staging'; - process.env.URL = repo_info['url']['stg']; + bucket = repo_info['bucket'][env] + '-staging'; + url = repo_info['url']['stg']; } } - if (process.env.BUCKET) { - this._logger.info(this._currJob._id, process.env.BUCKET); + if (!bucket || !url) { + this._logger.error( + this._currJob._id, + `getEnvironmentVariables failed to access AWS bucket and url necessary for ${getDirectory( + this._currJob + )} env ${env} jobType ${this._currJob.payload.jobType}` + ); + } + + if (bucket) { + this._logger.info(this._currJob._id, bucket); } - if (process.env.URL) { - this._logger.info(this._currJob._id, process.env.URL); + if (url) { + this._logger.info(this._currJob._id, url); } + + return { + bucket, + url, + regression, + }; + } + + protected async setEnvironmentVariables(): Promise { + const { bucket, url, regression } = await this.getEnvironmentVariables(); + + process.env.BUCKET = bucket; + process.env.URL = url; + process.env.REGRESSION = regression; } @throwIfJobInterupted() - protected async build(): Promise { + protected async buildWithMakefiles(): Promise { this.cleanup(); await this.cloneRepo(this._config.get('repo_dir')); this._logger.save(this._currJob._id, 'Cloned Repo'); @@ -495,7 +556,7 @@ export abstract class JobHandler { this._logger.save(this._currJob._id, 'Prepared Build commands'); await this.prepNextGenBuild(); this._logger.save(this._currJob._id, 'Prepared Next Gen build'); - await this._repoConnector.applyPatch(this.currJob); + await this._repoConnector.applyPatch(this._currJob); this._logger.save(this._currJob._id, 'Patch Applied'); await this.downloadMakeFile(); this._logger.save(this._currJob._id, 'Downloaded Makefile'); @@ -504,12 +565,82 @@ export abstract class JobHandler { return await this.executeBuild(); } + /* New build process without Makefiles */ + @throwIfJobInterupted() + protected async build(): Promise { + this.cleanup(); + const job = this._currJob; + + await this.cloneRepo(this._config.get('repo_dir')); + this._logger.save(job._id, 'Cloned Repo'); + + await this.commitCheck(); + this._logger.save(job._id, 'Checked Commit'); + await this.pullRepo(); + this._logger.save(job._id, 'Pulled Repo'); + await this.setEnvironmentVariables(); + this.logger.save(job._id, 'Prepared Environment variables'); + + const buildDependencies = await this.getBuildDependencies(); + this._logger.save(this._currJob._id, 'Identified Build dependencies'); + + const docset = await this._docsetsRepo.getRepo(this._currJob.payload.repoName, this._currJob.payload.directory); + let env = this._config.get('env'); + if (this._currJob.payload.regression) { + env = 'regression'; + } + const baseUrl = docset?.url?.[env] || 'https://mongodbcom-cdn.website.staging.corp.mongodb.com'; + + const { patchId } = await prepareBuildAndGetDependencies( + job.payload.repoName, + job.payload.project, + baseUrl, + buildDependencies, + job.payload.directory + ); + // Set patchId on payload for use in nextGenStage + this._currJob.payload.patchId = patchId; + this._logger.save(this._currJob._id, 'Downloaded Build dependencies'); + + let buildStepOutput: CliCommandResponse; + + const parseFunc = async () => nextGenParse({ job, patchId }); + buildStepOutput = await this.wrapWithBenchmarks(parseFunc, 'parseExe'); + this.logger.save(job._id, 'Repo Parsing Complete'); + this.logger.save(job._id, `${buildStepOutput.outputText}\n${buildStepOutput.errorText}`); + + const persistenceFunc = async () => persistenceModule({ job }); + buildStepOutput = await this.wrapWithBenchmarks(persistenceFunc, 'persistenceExe'); + await this.logger.save(job._id, 'Persistence Module Complete'); + await this.logger.save(job._id, `${buildStepOutput.outputText}\n${buildStepOutput.errorText}`); + + // Call Gatsby Cloud preview webhook after persistence module finishes for staging builds + const isFeaturePreviewWebhookEnabled = process.env.GATSBY_CLOUD_PREVIEW_WEBHOOK_ENABLED?.toLowerCase() === 'true'; + if (this.name === 'Staging' && isFeaturePreviewWebhookEnabled) { + await this.callGatsbyCloudWebhook(); + await this.logger.save(job._id, 'Gatsby Webhook Called'); + } + + const oasPageBuilderFunc = async () => oasPageBuild({ job, baseUrl }); + buildStepOutput = await this.wrapWithBenchmarks(oasPageBuilderFunc, 'oasPageBuildExe'); + await this.logger.save(job._id, 'OAS Page Build Complete'); + await this.logger.save(job._id, `${buildStepOutput.outputText}\n${buildStepOutput.errorText}`); + + const htmlFunc = async () => await nextGenHtml(); + buildStepOutput = await this.wrapWithBenchmarks(htmlFunc, 'htmlExe'); + await this.logger.save(job._id, 'NextGenHtml Complete'); + await this.logger.save(job._id, `${buildStepOutput.outputText}\n${buildStepOutput.errorText}`); + + return true; + } + @throwIfJobInterupted() protected async deployGeneric(): Promise { this.prepDeployCommands(); await this._logger.save(this.currJob._id, `${this._config.get('stage').padEnd(15)}Pushing to ${this.name}`); if ((this.currJob?.deployCommands?.length ?? 0) > 0) { + await this._logger.save(this.currJob._id, `deploy commands: ${this.currJob.deployCommands.join(' ')}`); // extract search deploy job to time and test const searchCommandIdx = this.currJob.deployCommands.findIndex((c) => c.match(/^mut\-index/)); let deployCmdsNoSearch = this.currJob.deployCommands; @@ -554,14 +685,24 @@ export abstract class JobHandler { this._currJob._id, `* Starting Job with ID: ${this._currJob._id} and type: ${this._currJob.payload.jobType}` ); + await this._logger.save(this._currJob._id, `* Starting Job with repo name: ${this._currJob.payload.repoName}`); try { - await this.build(); + if (process.env.FEATURE_FLAG_MONOREPO_PATH === 'true' && this._currJob.payload.repoName === MONOREPO_NAME) { + await this._logger.save(this._currJob._id, `* Using build without Makefiles`); + await this.build(); + } else { + await this._logger.save(this._currJob._id, `* Using build with Makefiles`); + await this.buildWithMakefiles(); + } + const resp = await this.deploy(); await this.update(resp); this.cleanup(); } catch (error) { + this.logger.save(this._currJob._id, `Error during the build process: ${error.stack}`); try { await this._jobRepository.updateWithErrorStatus(this._currJob._id, error.message); + this.cleanup(); } catch (error) { this._logger.error(this._currJob._id, error.message); diff --git a/src/job/jobManager.ts b/src/job/jobManager.ts index fe7b318c6..5bb315aaa 100644 --- a/src/job/jobManager.ts +++ b/src/job/jobManager.ts @@ -142,14 +142,14 @@ export class JobManager { async getQueuedJob(): Promise { return await this._jobRepository.getOneQueuedJobAndUpdate().catch((error) => { - this._logger.error('JobManager', `Error: ${error}`); + this._logger.error('JobManager', `Error: getQueuedJob: ${error}`); return null; }); } async getJob(jobId: string): Promise { return await this._jobRepository.getJobByIdAndUpdate(jobId).catch((error) => { - this._logger.error('JobManager', `Error: ${error}`); + this._logger.error('JobManager', `Error: getJob: ${error}`); return null; }); } diff --git a/src/job/stagingJobHandler.ts b/src/job/stagingJobHandler.ts index d4822d926..cb9eaae9b 100644 --- a/src/job/stagingJobHandler.ts +++ b/src/job/stagingJobHandler.ts @@ -11,6 +11,8 @@ import { IJobValidator } from './jobValidator'; import { RepoBranchesRepository } from '../repositories/repoBranchesRepository'; import { RepoEntitlementsRepository } from '../repositories/repoEntitlementsRepository'; import { DocsetsRepository } from '../repositories/docsetsRepository'; +import { nextGenStage } from '../commands'; +import { MONOREPO_NAME } from '../monorepo/utils/monorepo-constants'; export class StagingJobHandler extends JobHandler { constructor( @@ -75,10 +77,30 @@ export class StagingJobHandler extends JobHandler { } } async deploy(): Promise { + let resp; try { - const resp = await this.deployGeneric(); + if (process.env.FEATURE_FLAG_MONOREPO_PATH === 'true' && this.currJob.payload.repoName === MONOREPO_NAME) { + const repo_info = await this._docsetsRepo.getRepo( + this.currJob.payload.repoName, + this.currJob.payload.directory + ); + if (!repo_info) { + const errorMessage = ` + Docset Repo data not found in Atlas for repoName: ${this.currJob.payload.repoName}\n + ${this.currJob.payload.directory ? `directory: ${this.currJob.payload.directory}\n` : ''} + project: ${this.currJob.payload.project} + `; + throw Error(errorMessage); + } + + const { bucket, url } = await this.getEnvironmentVariables(); + resp = await nextGenStage({ job: this.currJob, bucket, url }); + await this.logger.save(this.currJob._id, `${'(stage)'.padEnd(15)} ${resp.output}`); + } else { + resp = await this.deployGeneric(); + } const summary = ''; - if (resp?.output?.includes('Summary')) { + if (resp.output?.includes('Summary')) { resp.output = resp.output.slice(resp.output.indexOf('Summary')); } await this.logger.save(this.currJob._id, `${'(stage)'.padEnd(15)}Finished pushing to staging`); diff --git a/src/monorepo/index.ts b/src/monorepo/index.ts index a561223be..044a8d98a 100644 --- a/src/monorepo/index.ts +++ b/src/monorepo/index.ts @@ -1,6 +1,7 @@ import { getSnootyDirSet } from './utils/path-utils'; import { GitCommitInfo } from './types/github-types'; import { getProjectDirFromPath } from './services/get-paths'; +import { ConsoleLogger } from '../services/logger'; interface FileUpdatePayload { ownerName: string; @@ -32,9 +33,7 @@ export async function getMonorepoPaths({ repoName, commitSha, }; - const snootyDirSet = await getSnootyDirSet(commitInfo); - const projects = updatedFilePaths.map((path) => getProjectDirFromPath(path, snootyDirSet)); // remove empty strings and remove duplicated values diff --git a/src/repositories/docsetsRepository.ts b/src/repositories/docsetsRepository.ts index 166483de1..9a04c1740 100644 --- a/src/repositories/docsetsRepository.ts +++ b/src/repositories/docsetsRepository.ts @@ -52,9 +52,11 @@ export class DocsetsRepository extends BaseRepository { ]; } - async getProjectByRepoName(repoName: string): Promise { + async getProjectByRepoName(repoName: string, directory?: string): Promise { + const matchConditions = { repoName }; + if (directory) matchConditions['directories.snooty_toml'] = `/${directory}`; const projection = { project: 1 }; - const aggregationPipeline = DocsetsRepository.getAggregationPipeline({ repoName }, projection); + const aggregationPipeline = DocsetsRepository.getAggregationPipeline(matchConditions, projection); const cursor = await this.aggregate(aggregationPipeline, `Error while getting project by repo name ${repoName}`); const res = await cursor.toArray(); if (!res.length) { @@ -72,7 +74,9 @@ export class DocsetsRepository extends BaseRepository { const cursor = await this.aggregate(aggregationPipeline, `Error while fetching repo by repo name ${repoName}`); const res = await cursor.toArray(); if (!res.length) { - const msg = `DocsetsRepository.getRepo - Could not find repo by repoName: ${repoName}`; + const msg = `DocsetsRepository.getRepo - Could not find repo by repoName: ${repoName} ${ + directory ? `with directory: /${directory}` : '' + }`; this._logger.info(this._repoName, msg); } return res?.[0]; diff --git a/src/services/commandExecutor.ts b/src/services/commandExecutor.ts index 9221cfc51..9dc2fe04d 100644 --- a/src/services/commandExecutor.ts +++ b/src/services/commandExecutor.ts @@ -14,8 +14,13 @@ const execWithOptions: ( // The expected return signature is a Promise<{stdout:string, stderr:string}> const exec = promisify(execWithOptions) as any; +export enum CommandExecutorResponseStatus { + success = 'success', + failed = 'failed', +} + export class CommandExecutorResponse { - status: string; + status: CommandExecutorResponseStatus; output: string; error: string; } @@ -57,12 +62,12 @@ export class ShellCommandExecutor implements ICommandExecutor { resp.output = stdout.trim(); resp.error = stderr; - resp.status = 'success'; + resp.status = CommandExecutorResponseStatus.success; return resp; } catch (error) { resp.output = ''; resp.error = error; - resp.status = 'failed'; + resp.status = CommandExecutorResponseStatus.failed; } return resp; } diff --git a/src/services/repo.ts b/src/services/repo.ts index b5e780b1b..77f177a03 100644 --- a/src/services/repo.ts +++ b/src/services/repo.ts @@ -5,7 +5,6 @@ import { IConfig } from 'config'; import { InvalidJobError } from '../errors/errors'; import { IFileSystemServices } from './fileServices'; import simpleGit, { SimpleGit } from 'simple-git'; -import { getDirectory } from '../job/jobHandler'; const git: SimpleGit = simpleGit(); export interface IRepoConnector { diff --git a/tests/unit/job/productionJobHandler.test.ts b/tests/unit/job/productionJobHandler.test.ts index 5db6fa31b..828455550 100644 --- a/tests/unit/job/productionJobHandler.test.ts +++ b/tests/unit/job/productionJobHandler.test.ts @@ -55,7 +55,7 @@ describe('ProductionJobHandler Tests', () => { 'Invalid RepoName' ); expect(jobHandlerTestHelper.jobRepo.updateWithErrorStatus).toBeCalledTimes(1); - expect(jobHandlerTestHelper.logger.save).toBeCalledTimes(3); + expect(jobHandlerTestHelper.logger.save).toBeCalledTimes(6); }); describe.each(TestDataProvider.getAllCommitCheckCases())('Validate all commit check error cases', (element) => {