diff --git a/.github/actions/ete-docs-bundle/action.yml b/.github/actions/ete-docs-bundle/action.yml index b5c61dc44d..6689c6906f 100644 --- a/.github/actions/ete-docs-bundle/action.yml +++ b/.github/actions/ete-docs-bundle/action.yml @@ -5,10 +5,19 @@ inputs: deployment_url: description: "The URL of the deployment to test" required: true + token: + description: "The Vercel token to use for the deployment" + required: true runs: using: "composite" steps: + - uses: ./.github/actions/install + + - shell: bash + name: Fetch domains + run: pnpm vercel-scripts domains.txt ${{ inputs.deployment_url }} --token=${{ inputs.token }} + - name: Install Playwright Browsers shell: bash run: pnpm exec playwright install --with-deps @@ -17,7 +26,8 @@ runs: shell: bash env: DEPLOYMENT_URL: ${{ inputs.deployment_url }} - run: PLAYWRIGHT_JSON_OUTPUT_NAME=results.json pnpm exec playwright test playwright/smoke --workers 6 --reporter json + PLAYWRIGHT_JSON_OUTPUT_NAME: results.json + run: pnpm exec playwright test playwright/smoke --workers 6 --reporter json - uses: daun/playwright-report-summary@v3 if: always() diff --git a/.github/actions/turbo-ignore/action.yml b/.github/actions/turbo-ignore/action.yml new file mode 100644 index 0000000000..327171d4cb --- /dev/null +++ b/.github/actions/turbo-ignore/action.yml @@ -0,0 +1,55 @@ +name: Turbo Ignore +description: Ignore unchanged files in a Vercel deployment + +inputs: + token: + description: "The Vercel token to use for the deployment" + required: true + project: + description: "The project to check for changes" + required: true + environment: + description: "The environment that turbo-ignore is checking against" + default: "preview" + package: + description: "The package to check for changes" + required: true + branch: + description: "The branch to check for changes" + required: false + +outputs: + continue: + value: ${{ steps.ignore.outputs.continue }} + description: "Whether to continue with the deployment or not" + +runs: + using: "composite" + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + fetch-depth: 10 + + - uses: ./.github/actions/install + + - name: Ignore unchanged files + shell: bash + id: ignore + run: | + # if ${{ inputs.branch }} is present, then we change the script to --branch=${{ inputs.branch }} + + if [ -n "${{ inputs.branch }}" ]; then + pnpm vercel-scripts last-deploy.txt ${{ inputs.project }} --token=${{ inputs.token }} --environment=${{ inputs.environment }} --branch=${{ inputs.branch }} + else + pnpm vercel-scripts last-deploy.txt ${{ inputs.project }} --token=${{ inputs.token }} --environment=${{ inputs.environment }} + fi + + if [ ! -f last-deploy.txt ]; then + echo "continue=1" >> $GITHUB_OUTPUT + exit 0 + fi + + set +e + pnpx turbo-ignore ${{ inputs.package }} --fallback=$(cat last-deploy.txt) + echo "continue=$?" >> $GITHUB_OUTPUT diff --git a/.github/workflows/deploy-docs-bundle-dev.yml b/.github/workflows/deploy-docs-bundle-dev.yml index 5240c20f07..9e7d74d86f 100644 --- a/.github/workflows/deploy-docs-bundle-dev.yml +++ b/.github/workflows/deploy-docs-bundle-dev.yml @@ -17,17 +17,15 @@ jobs: continue: ${{ steps.ignore.outputs.continue }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 2 # used for turbo-ignore - - - name: Install - uses: ./.github/actions/install - with: - run_install: false - - name: Ignore unchanged files id: ignore - run: set +e; pnpx turbo-ignore @fern-ui/docs-bundle --fallback=HEAD^1; echo "continue=$?" >> $GITHUB_OUTPUT + uses: ./.github/actions/turbo-ignore + with: + token: ${{ secrets.VERCEL_TOKEN }} + project: "app-dev.buildwithfern.com" + package: "@fern-ui/docs-bundle" + environment: "production" + branch: main deploy: needs: ignore @@ -44,11 +42,10 @@ jobs: with: ref: ${{ github.ref_name || github.ref }} - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy run: | - pnpm vercel-scripts deploy app-dev.buildwithfern.com --token=${{ secrets.VERCEL_TOKEN }} --environment=production --force + pnpm vercel-scripts deploy app-dev.buildwithfern.com --token=${{ secrets.VERCEL_TOKEN }} --environment=production echo "deployment_url=$(cat deployment-url.txt)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/deploy-docs-bundle-preview.yml b/.github/workflows/deploy-docs-bundle-preview.yml index 649862f1a2..73a546c8c6 100644 --- a/.github/workflows/deploy-docs-bundle-preview.yml +++ b/.github/workflows/deploy-docs-bundle-preview.yml @@ -7,6 +7,10 @@ on: - main workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} + cancel-in-progress: true + jobs: ignore: runs-on: ubuntu-latest @@ -14,17 +18,15 @@ jobs: continue: ${{ steps.ignore.outputs.continue }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 2 # used for turbo-ignore - - - name: Install - uses: ./.github/actions/install - with: - run_install: false - - name: Ignore unchanged files id: ignore - run: set +e; pnpx turbo-ignore @fern-ui/docs-bundle --fallback=HEAD^1; echo "continue=$?" >> $GITHUB_OUTPUT + uses: ./.github/actions/turbo-ignore + with: + token: ${{ secrets.VERCEL_TOKEN }} + project: "app.buildwithfern.com" + package: "@fern-ui/docs-bundle" + environment: "preview" + branch: ${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} deploy: needs: ignore @@ -43,8 +45,7 @@ jobs: fetch-depth: 2 # used for turbo-ignore ref: ${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy @@ -108,8 +109,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy @@ -118,20 +118,20 @@ jobs: echo "deployment_url=$(cat deployment-url.txt)" >> $GITHUB_OUTPUT ete: - needs: deploy # only runs on fern-prod - if: needs.deploy.outputs.deployment_url + needs: + - ignore + - deploy # only runs on fern-prod + if: always() runs-on: ubuntu-latest permissions: write-all # required for the playwright-report-summary action steps: + # if the job is ignored, skip the ETE test and exit 0 so that the this job can be used for merge protection - uses: actions/checkout@v4 - - - name: Install - uses: ./.github/actions/install - - - name: Fetch domains - run: pnpm vercel-scripts domains.txt ${{ needs.deploy.outputs.deployment_url }} --token=${{ secrets.VERCEL_TOKEN }} + if: needs.deploy.outputs.deployment_url - name: Run E2E tests uses: ./.github/actions/ete-docs-bundle + if: needs.deploy.outputs.deployment_url with: deployment_url: ${{ needs.deploy.outputs.deployment_url }} + token: ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/deploy-docs-bundle-prod.yml b/.github/workflows/deploy-docs-bundle-prod.yml index eb8096c492..74b55aff5c 100644 --- a/.github/workflows/deploy-docs-bundle-prod.yml +++ b/.github/workflows/deploy-docs-bundle-prod.yml @@ -19,11 +19,8 @@ jobs: outputs: deployment_url: ${{ steps.deploy.outputs.deployment_url }} steps: - # set the ref to a specific branch so that the deployment is scoped to that branch (instead of a headless ref) - uses: actions/checkout@v4 - - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy @@ -40,11 +37,8 @@ jobs: outputs: deployment_url: ${{ steps.deploy.outputs.deployment_url }} steps: - # set the ref to a specific branch so that the deployment is scoped to that branch (instead of a headless ref) - uses: actions/checkout@v4 - - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy @@ -61,11 +55,9 @@ jobs: outputs: deployment_url: ${{ steps.deploy.outputs.deployment_url }} steps: - # set the ref to a specific branch so that the deployment is scoped to that branch (instead of a headless ref) - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy @@ -79,16 +71,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - name: Install - uses: ./.github/actions/install - - - name: Fetch domains - run: pnpm vercel-scripts domains.txt app.buildwithfern.com --token ${{ secrets.VERCEL_TOKEN }} - - uses: ./github/actions/ete-docs-bundle with: deployment_url: ${{ needs.deploy_app_buildwithfern_com.outputs.deployment_url }} + token: ${{ secrets.VERCEL_TOKEN }} promote: needs: @@ -106,8 +92,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Promote Deployment run: pnpm vercel-scripts promote ${{ matrix.deployment_url }} --token ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/deploy-fern-dashboard-dev.yml b/.github/workflows/deploy-fern-dashboard-dev.yml index 0d8c8075c6..4b5ccd4ff3 100644 --- a/.github/workflows/deploy-fern-dashboard-dev.yml +++ b/.github/workflows/deploy-fern-dashboard-dev.yml @@ -17,7 +17,25 @@ concurrency: cancel-in-progress: true jobs: + ignore: + runs-on: ubuntu-latest + outputs: + continue: ${{ steps.ignore.outputs.continue }} + steps: + - uses: actions/checkout@v4 + - name: Ignore unchanged files + id: ignore + uses: ./.github/actions/turbo-ignore + with: + token: ${{ secrets.VERCEL_TOKEN }} + project: "dashboard-dev.buildwithfern.com" + package: "@fern-ui/dashboard" + environment: "production" + branch: main + deploy: + needs: ignore + if: needs.ignore.outputs.continue == 1 runs-on: ubuntu-latest environment: name: Production - dashboard-dev.buildwithfern.com @@ -28,8 +46,7 @@ jobs: with: ref: main - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy diff --git a/.github/workflows/deploy-fern-dashboard-preview.yml b/.github/workflows/deploy-fern-dashboard-preview.yml index 34f43b5ff2..a795072491 100644 --- a/.github/workflows/deploy-fern-dashboard-preview.yml +++ b/.github/workflows/deploy-fern-dashboard-preview.yml @@ -13,6 +13,10 @@ on: - main workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} + cancel-in-progress: true + jobs: ignore: runs-on: ubuntu-latest @@ -20,24 +24,22 @@ jobs: continue: ${{ steps.ignore.outputs.continue }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 2 # used for turbo-ignore - - - name: Install - uses: ./.github/actions/install - with: - run_install: false - - name: Ignore unchanged files id: ignore - run: set +e; pnpx turbo-ignore @fern-ui/dashboard --fallback=HEAD^1; echo "continue=$?" >> $GITHUB_OUTPUT + uses: ./.github/actions/turbo-ignore + with: + token: ${{ secrets.VERCEL_TOKEN }} + project: "dashboard-dev.buildwithfern.com" + package: "@fern-ui/dashboard" + environment: "preview" + branch: ${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} deploy: needs: ignore if: needs.ignore.outputs.continue == 1 runs-on: ubuntu-latest environment: - name: Preview - dashboard.buildwithfern.com + name: Preview - dashboard-dev.buildwithfern.com url: ${{ steps.deploy.outputs.deployment_url }} steps: # set the ref to a specific branch so that the deployment is scoped to that branch (instead of a headless ref) @@ -45,11 +47,10 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref || github.ref_name || github.ref }} - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy run: | - pnpm vercel-scripts deploy dashboard.buildwithfern.com --token=${{ secrets.VERCEL_TOKEN }} + pnpm vercel-scripts deploy dashboard-dev.buildwithfern.com --token=${{ secrets.VERCEL_TOKEN }} echo "deployment_url=$(cat deployment-url.txt)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/deploy-fern-dashboard-prod.yml b/.github/workflows/deploy-fern-dashboard-prod.yml index 9ba4f7eeb8..8d048a26cf 100644 --- a/.github/workflows/deploy-fern-dashboard-prod.yml +++ b/.github/workflows/deploy-fern-dashboard-prod.yml @@ -26,11 +26,8 @@ jobs: steps: # set the ref to a specific branch so that the deployment is scoped to that branch (instead of a headless ref) - uses: actions/checkout@v4 - with: - ref: main - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy diff --git a/.github/workflows/deploy-fontawesome-cdn.yml b/.github/workflows/deploy-fontawesome-cdn.yml index 54044e1f8d..59c3c5a4f1 100644 --- a/.github/workflows/deploy-fontawesome-cdn.yml +++ b/.github/workflows/deploy-fontawesome-cdn.yml @@ -17,17 +17,15 @@ jobs: continue: ${{ steps.ignore.outputs.continue }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 2 # used for turbo-ignore - - - name: Install - uses: ./.github/actions/install - with: - run_install: false - - name: Ignore unchanged files id: ignore - run: set +e; pnpx turbo-ignore @fern-ui/fontawesome-cdn --fallback=HEAD^1; echo "continue=$?" >> $GITHUB_OUTPUT + uses: ./.github/actions/turbo-ignore + with: + token: ${{ secrets.VERCEL_TOKEN }} + project: "icons.ferndocs.com" + package: "@fern-ui/fontawesome-cdn" + environment: "production" + branch: main deploy: needs: ignore @@ -42,8 +40,7 @@ jobs: with: ref: main - - name: Install - uses: ./.github/actions/install + - uses: ./.github/actions/install - name: Build & Deploy to Vercel id: deploy diff --git a/clis/vercel-scripts/last-deploy.txt b/clis/vercel-scripts/last-deploy.txt new file mode 100644 index 0000000000..1b80ce8707 --- /dev/null +++ b/clis/vercel-scripts/last-deploy.txt @@ -0,0 +1 @@ +bc1504f8676aba6e8473b44d59a5175afdc005f4 \ No newline at end of file diff --git a/clis/vercel-scripts/package.json b/clis/vercel-scripts/package.json index 35c84eac34..d6e969e62f 100644 --- a/clis/vercel-scripts/package.json +++ b/clis/vercel-scripts/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "type": "module", "scripts": { + "vercel-scripts": "pnpm tsx src/cli.ts", "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../.eslintignore", "lint:eslint:fix": "pnpm lint:eslint --fix", "lint:style": "stylelint 'src/**/*.scss' --allow-empty-input --max-warnings 0", @@ -20,12 +21,13 @@ "eslint": "^8.56.0", "organize-imports-cli": "^0.10.0", "prettier": "^3.3.2", + "tsx": "^4.7.1", "typescript": "4.9.5", "yargs": "^17.4.1" }, "dependencies": { "@fern-fern/fern-docs-sdk": "0.0.5", - "@fern-fern/vercel": "0.0.4650", + "@fern-fern/vercel": "0.0.4655", "ts-essentials": "^10.0.1" } } diff --git a/clis/vercel-scripts/src/cli.ts b/clis/vercel-scripts/src/cli.ts index f22a669c29..3404bb0c1c 100644 --- a/clis/vercel-scripts/src/cli.ts +++ b/clis/vercel-scripts/src/cli.ts @@ -1,18 +1,13 @@ import { VercelClient } from "@fern-fern/vercel"; -import { writeFileSync } from "fs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; +import { deployCommand } from "./commands/deploy.js"; +import { getLastDeployCommand } from "./commands/last-deploy.js"; import { promoteCommand } from "./commands/promote.js"; import { revalidateAllCommand } from "./commands/revalidate-all.js"; -import { cwd } from "./cwd.js"; +import { writefs } from "./cwd.js"; import { cleanDeploymentId } from "./utils/clean-id.js"; -import { VercelDeployer } from "./utils/deployer.js"; import { FernDocsRevalidator } from "./utils/revalidator.js"; -import { safeCommand } from "./utils/safeCommand.js"; - -function isValidEnvironment(environment: string): environment is "preview" | "production" { - return environment === "preview" || environment === "production"; -} void yargs(hideBin(process.argv)) .scriptName("vercel-scripts") @@ -59,26 +54,7 @@ void yargs(hideBin(process.argv)) default: "deployment-url.txt", }), async ({ project, environment, token, teamName, teamId, output, skipDeploy }) => { - if (!isValidEnvironment(environment)) { - throw new Error(`Invalid environment: ${environment}`); - } - - // eslint-disable-next-line no-console - console.log(`Deploying project ${project} to ${environment} environment`); - - const cli = new VercelDeployer({ - token, - teamName, - teamId, - environment, - cwd: cwd(), - }); - - const result = await cli.buildAndDeployToVercel(project, { skipDeploy }); - - if (result) { - writeFileSync(output, result.url); - } + await deployCommand({ project, environment, token, teamName, teamId, output, skipDeploy }); process.exit(0); }, @@ -91,15 +67,19 @@ void yargs(hideBin(process.argv)) type: "boolean", description: "Revalidate the deployment (if it's fern docs)", }), - async ({ deploymentUrl, token, teamId, revalidateAll }) => - safeCommand(() => promoteCommand({ deploymentIdOrUrl: deploymentUrl, token, teamId, revalidateAll })), + async ({ deploymentUrl, token, teamId, revalidateAll }) => { + await promoteCommand({ deploymentIdOrUrl: deploymentUrl, token, teamId, revalidateAll }); + process.exit(0); + }, ) .command( "revalidate-all ", "Revalidate all docs for a deployment", (argv) => argv.positional("deploymentUrl", { type: "string", demandOption: true }), - async ({ deploymentUrl, token, teamId }) => - safeCommand(() => revalidateAllCommand({ token, teamId, deploymentIdOrUrl: deploymentUrl })), + async ({ deploymentUrl, token, teamId }) => { + await revalidateAllCommand({ token, teamId, deploymentIdOrUrl: deploymentUrl }); + process.exit(0); + }, ) .command( "preview.txt ", @@ -124,7 +104,7 @@ void yargs(hideBin(process.argv)) const urls = await revalidator.getPreviewUrls(deploymentUrl); - writeFileSync(output, `## PR Preview\n\n${urls.map((d) => `- [ ] [${d.name}](${d.url})`).join("\n")}`); + writefs(output, `## PR Preview\n\n${urls.map((d) => `- [ ] [${d.name}](${d.url})`).join("\n")}`); process.exit(0); }, @@ -152,9 +132,37 @@ void yargs(hideBin(process.argv)) const urls = await revalidator.getDomains(); - writeFileSync(output, urls.join("\n")); + writefs(output, urls.join("\n")); process.exit(0); }, ) + .command( + "last-deploy.txt ", + "Get the last deployment", + (argv) => + argv + .positional("project", { type: "string", demandOption: true }) + .option("branch", { + type: "string", + description: "The branch to get the last deployment for", + }) + .options("environment", { + type: "string", + description: "The environment to deploy to", + demandOption: true, + default: "preview", + choices: ["preview" as const, "production" as const], + }) + .option("output", { + type: "string", + description: "The output file to write the preview URLs to", + default: "last-deploy.txt", + }), + async ({ project, token, branch, output, environment }) => { + await getLastDeployCommand({ project, token, branch, output, environment }); + process.exit(0); + }, + ) + .showHelpOnFail(false) .parse(); diff --git a/clis/vercel-scripts/src/commands/deploy.ts b/clis/vercel-scripts/src/commands/deploy.ts new file mode 100644 index 0000000000..90cdf302db --- /dev/null +++ b/clis/vercel-scripts/src/commands/deploy.ts @@ -0,0 +1,42 @@ +import { cwd, writefs } from "../cwd.js"; +import { VercelDeployer } from "../utils/deployer.js"; +import { assertValidEnvironment } from "../utils/valid-env.js"; + +interface DeployArgs { + project: string; + environment: string; + token: string; + teamName: string; + teamId: string; + output: string; + skipDeploy?: boolean; +} + +export async function deployCommand({ + project, + environment, + token, + teamName, + teamId, + output, + skipDeploy, +}: DeployArgs): Promise { + assertValidEnvironment(environment); + + // eslint-disable-next-line no-console + console.log(`Deploying project ${project} to ${environment} environment`); + + const cli = new VercelDeployer({ + token, + teamName, + teamId, + environment, + cwd: cwd(), + }); + + const result = await cli.buildAndDeployToVercel(project, { skipDeploy }); + + if (result) { + writefs(output, `https://${result.url}`); + } +} diff --git a/clis/vercel-scripts/src/commands/last-deploy.ts b/clis/vercel-scripts/src/commands/last-deploy.ts new file mode 100644 index 0000000000..fbbf69fea6 --- /dev/null +++ b/clis/vercel-scripts/src/commands/last-deploy.ts @@ -0,0 +1,49 @@ +import { VercelClient } from "@fern-fern/vercel"; +import { writefs } from "../cwd.js"; +import { assertValidEnvironment } from "../utils/valid-env.js"; + +interface LastDeployArgs { + project: string; + token: string; + environment: string; + output: string; + branch?: string; +} + +const GIT_COMMIT_REF = "githubCommitRef"; +const GIT_COMMIT_SHA = "githubCommitSha"; + +export async function getLastDeployCommand({ + project, + token, + environment, + branch, + output, +}: LastDeployArgs): Promise { + assertValidEnvironment(environment); + + const vercel = new VercelClient({ token }); + + const { deployments } = await vercel.deployments.getDeployments({ + projectId: project, + limit: 1, + state: "BUILDING,ERROR,INITIALIZING,QUEUED,READY", + target: environment, + branch, + }); + + const meta = deployments[0]?.meta; + const sha = meta?.[GIT_COMMIT_SHA]; + const ref = meta?.[GIT_COMMIT_REF]; + + if (sha) { + // eslint-disable-next-line no-console + console.log(`Last deploy ref: ${sha} (${ref ?? branch})`, deployments[0]); + writefs(output, sha); + } else { + // eslint-disable-next-line no-console + console.error( + `No ${environment} deployment found for project ${project} ${branch != null ? `on branch ${branch}` : ""}`, + ); + } +} diff --git a/clis/vercel-scripts/src/cwd.ts b/clis/vercel-scripts/src/cwd.ts index 0ae88a1c28..4fbf3394b6 100644 --- a/clis/vercel-scripts/src/cwd.ts +++ b/clis/vercel-scripts/src/cwd.ts @@ -1,6 +1,14 @@ +import { writeFileSync } from "fs"; +import { join } from "path"; import { exec } from "./utils/exec.js"; +let _cwd: string | undefined; + export function cwd(): string { + if (_cwd) { + return _cwd; + } + const cwd = exec("Get git project root", "git rev-parse --show-toplevel", { stdio: "pipe", }).trim(); @@ -9,8 +17,14 @@ export function cwd(): string { throw new Error("Could not detect git project root directory"); } + _cwd = cwd; + // eslint-disable-next-line no-console console.log("Detected monorepo root directory:", cwd); return cwd; } + +export function writefs(output: string, content: string): void { + writeFileSync(join(cwd(), output), content); +} diff --git a/clis/vercel-scripts/src/utils/deployer.ts b/clis/vercel-scripts/src/utils/deployer.ts index 2066a4c9e6..492466179f 100644 --- a/clis/vercel-scripts/src/utils/deployer.ts +++ b/clis/vercel-scripts/src/utils/deployer.ts @@ -91,7 +91,7 @@ export class VercelDeployer { const deployment = await this.vercel.deployments.getDeployment(cleanDeploymentId(deploymentUrl)); - logCommand(`[${this.environmentName}] Deployment URL: ${deployment.url}`); + logCommand(`[${this.environmentName}] Deployment URL: https://${deployment.url}`); if ("inspectorUrl" in deployment) { logCommand(`[${this.environmentName}] Inspector URL: ${deployment.inspectorUrl}`); diff --git a/clis/vercel-scripts/src/utils/safeCommand.ts b/clis/vercel-scripts/src/utils/safeCommand.ts deleted file mode 100644 index 8b082dc264..0000000000 --- a/clis/vercel-scripts/src/utils/safeCommand.ts +++ /dev/null @@ -1,10 +0,0 @@ -export async function safeCommand(fn: () => Promise): Promise { - try { - await fn(); - process.exit(0); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - process.exit(1); - } -} diff --git a/clis/vercel-scripts/src/utils/valid-env.ts b/clis/vercel-scripts/src/utils/valid-env.ts new file mode 100644 index 0000000000..7ea07eb23a --- /dev/null +++ b/clis/vercel-scripts/src/utils/valid-env.ts @@ -0,0 +1,11 @@ +type Environment = "preview" | "production"; + +function isValidEnvironment(environment: string): environment is Environment { + return environment === "preview" || environment === "production"; +} + +export function assertValidEnvironment(environment: string): asserts environment is Environment { + if (!isValidEnvironment(environment)) { + throw new Error(`Invalid environment: ${environment}`); + } +} diff --git a/fern/apis/vercel/openapi.json b/fern/apis/vercel/openapi.json index 51121e1fe8..fe1de20dad 100644 --- a/fern/apis/vercel/openapi.json +++ b/fern/apis/vercel/openapi.json @@ -47705,6 +47705,13 @@ "schema": { "type": "string" } + }, + { + "in": "query", + "name": "branch", + "schema": { + "type": "string" + } } ] } diff --git a/package.json b/package.json index 064be86326..ce5daa449c 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "format": "prettier --write --ignore-unknown --ignore-path ./shared/.prettierignore \"**\"", "format:check": "prettier --check --ignore-unknown --ignore-path ./shared/.prettierignore \"**\"", "publish": "pnpm -r --filter=!private --parallel exec -- npm publish --access public", - "vercel-scripts": "pnpm tsx clis/vercel-scripts/src/cli.ts", + "vercel-scripts": "pnpm --filter=@fern-platform/vercel-scripts vercel-scripts", "check-docs-release-blockers": "pnpm tsx packages/scripts/src/cli.ts -- fern-scripts check-docs-release-blockers", "root-package:check": "pnpm tsx packages/scripts/src/cli.ts -- fern-scripts check-root-package", "root-package:fix": "pnpm root-package:check --fix", diff --git a/packages/ui/fern-dashboard/vercel.json b/packages/ui/fern-dashboard/vercel.json index 7d3a2223d4..2052d42b21 100644 --- a/packages/ui/fern-dashboard/vercel.json +++ b/packages/ui/fern-dashboard/vercel.json @@ -2,7 +2,7 @@ "$schema": "https://openapi.vercel.sh/vercel.json", "framework": "vite", "rewrites": [{ "source": "/(.*)", "destination": "/" }], - "installCommand": "pnpm --filter=@fern-ui/dashboard install", + "installCommand": "pnpm install", "buildCommand": "pnpm turbo build", "devCommand": "pnpm turbo dev", "git": { diff --git a/packages/ui/fontawesome-cdn/vercel.json b/packages/ui/fontawesome-cdn/vercel.json index 3f2fe84f57..e9dbd9d9af 100644 --- a/packages/ui/fontawesome-cdn/vercel.json +++ b/packages/ui/fontawesome-cdn/vercel.json @@ -3,7 +3,7 @@ "git": { "deploymentEnabled": false }, - "installCommand": "pnpm --filter=@fern-ui/fontawesome-cdn install", + "installCommand": "pnpm install", "buildCommand": "pnpm turbo build", "devCommand": "pnpm turbo dev", "ignoreCommand": "exit 0" diff --git a/playwright/inclusions.yml b/playwright/inclusions.yml index daba0cdcdb..59cf3dc4ff 100644 --- a/playwright/inclusions.yml +++ b/playwright/inclusions.yml @@ -54,7 +54,6 @@ favicon: - docs.cable.tech - docs.givechariot.com - developers.awork.com - - www.intern.mavenagi.com - docs.schematichq.com - plantstore.dev - docs.boundaryml.com diff --git a/playwright/smoke/existence.spec.ts b/playwright/smoke/existence.spec.ts index 71d88e8390..d0b8765454 100644 --- a/playwright/smoke/existence.spec.ts +++ b/playwright/smoke/existence.spec.ts @@ -1,10 +1,17 @@ import { expect, test } from "@playwright/test"; import { getPlaywrightTestUrls } from "../test-runner"; +import { addPreviewCookie, generatePreviewContext } from "../utils"; const existenceUrls = getPlaywrightTestUrls("existence"); -existenceUrls.forEach((testUrl) => { - test(`Check if ${testUrl} is online`, async ({ page }) => { - const response = await page.goto(testUrl); +existenceUrls.map(generatePreviewContext).forEach((preview) => { + test(`Check if ${preview.originalUrl} homepage exists`, async ({ page, context }) => { + // 1. Set the preview cookie + await addPreviewCookie(context, preview); + + // 2. Navigate to the preview URL + const response = await page.goto(preview.previewUrl); + + // 3. Check if the response status is 200 expect(response?.status()).toBe(200); }); }); diff --git a/playwright/smoke/favicon.spec.ts b/playwright/smoke/favicon.spec.ts index 91abd0a99c..e53f7a4d19 100644 --- a/playwright/smoke/favicon.spec.ts +++ b/playwright/smoke/favicon.spec.ts @@ -1,10 +1,16 @@ import test, { expect } from "@playwright/test"; import { getPlaywrightTestUrls } from "../test-runner"; +import { addPreviewCookie, generatePreviewContext } from "../utils"; const faviconUrls = getPlaywrightTestUrls("favicon"); -faviconUrls.forEach((testUrl) => { - test(`Check if favicon exists and URL does not return 404 for ${testUrl}`, async ({ page }) => { - await page.goto(testUrl); +faviconUrls.map(generatePreviewContext).forEach((testUrl) => { + test(`Check if favicon exists and URL does not return 404 for ${testUrl.originalHost}`, async ({ + page, + context, + }) => { + await addPreviewCookie(context, testUrl); + + await page.goto(testUrl.previewUrl); const faviconUrl = await page.getAttribute('link[rel="icon"]', "href", { timeout: 5000, diff --git a/playwright/smoke/versioned-docs.spec.ts b/playwright/smoke/versioned-docs.spec.ts index 05ff68599a..0630f86248 100644 --- a/playwright/smoke/versioned-docs.spec.ts +++ b/playwright/smoke/versioned-docs.spec.ts @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { generatePreviewContext } from "../utils"; +import { addPreviewCookie, generatePreviewContext } from "../utils"; /** * This test will run on a sample of urls from customer docs using versions. @@ -38,9 +38,9 @@ const samples = [ ].map(generatePreviewContext); samples.forEach((sample) => { - test(`Check if ${sample.url} is online`, async ({ page }) => { + test(`Check if ${sample.originalUrl} is online`, async ({ page, context }) => { // 1. set the preview cookie - await page.goto(sample.previewCookieApiRoute); + await addPreviewCookie(context, sample); // 2. navigate to the page and check if it is online const response = await page.goto(sample.previewUrl, { waitUntil: "domcontentloaded" }); diff --git a/playwright/utils.ts b/playwright/utils.ts index 6d961c7b93..72a567a33f 100644 --- a/playwright/utils.ts +++ b/playwright/utils.ts @@ -1,3 +1,5 @@ +import { BrowserContext } from "@playwright/test"; + // let previewDeploymentUrl: string | null = null; export const getPreviewDeploymentUrl = (): string => { if (!process.env.DEPLOYMENT_URL) { @@ -7,45 +9,40 @@ export const getPreviewDeploymentUrl = (): string => { }; export interface PreviewContext { - /** - * The original URL to be previewed. - */ - url: string; - - /** - * The URL to navigate to after setting the preview cookie. - */ - previewUrl: string; - - /** - * The api route that will set the _fern_docs_preview=<> cookie. - */ - previewCookieApiRoute: string; + originalUrl: string; + previewUrl: string; // url to visit - /** - * The preview deployment URL, which will be used to replace the host of the original URL. - */ - deploymentUrl: string; + originalHost: string; // set to _fern_docs_preview + deploymentHost: string; // set to the deployment host createPreviewUrl(url: string): string; } -export function generatePreviewContext(url: string): PreviewContext { - const deploymentUrl = getPreviewDeploymentUrl(); +export function generatePreviewContext(uri: string): PreviewContext { + const deploymentUrl = new URL(getPreviewDeploymentUrl()); + const url = new URL(uri); return { - url, - previewUrl: toPreviewUrl(deploymentUrl, url), - previewCookieApiRoute: `${deploymentUrl}/api/fern-docs/preview?host=${encodeURIComponent(new URL(url).host)}`, - deploymentUrl, - createPreviewUrl: (url: string) => toPreviewUrl(deploymentUrl, url), + originalUrl: uri, + previewUrl: toPreviewUrl(deploymentUrl.host, uri), + originalHost: url.host, + deploymentHost: deploymentUrl.host, + createPreviewUrl: (url: string) => toPreviewUrl(deploymentUrl.host, url), }; } -export function toPreviewUrl(deploymentUrl: string, url: string): string { - if (url.startsWith("http")) { - return `${deploymentUrl}${new URL(url).pathname}`; - } else if (url.startsWith("/")) { - return `${deploymentUrl}${url}`; - } - throw new Error(`Invalid URL: ${url}`); +export function addPreviewCookie(context: BrowserContext, previewContext: PreviewContext): Promise { + return context.addCookies([ + { + name: "_fern_docs_preview", + value: previewContext.originalHost, + domain: previewContext.deploymentHost, + path: "/", + }, + ]); +} + +export function toPreviewUrl(deploymentHost: string, url: string): string { + const urlObj = new URL(url, url.startsWith("/") ? "https://n" : undefined); + urlObj.host = deploymentHost; + return urlObj.toString(); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 543f801eeb..45f3377f8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -300,8 +300,8 @@ importers: specifier: 0.0.5 version: 0.0.5 '@fern-fern/vercel': - specifier: 0.0.4650 - version: 0.0.4650 + specifier: 0.0.4655 + version: 0.0.4655 ts-essentials: specifier: ^10.0.1 version: 10.0.1(typescript@4.9.5) @@ -327,6 +327,9 @@ importers: prettier: specifier: ^3.3.2 version: 3.3.2 + tsx: + specifier: ^4.7.1 + version: 4.9.3 typescript: specifier: 4.9.5 version: 4.9.5 @@ -486,7 +489,7 @@ importers: version: 3.3.2 simple-git: specifier: ^3.24.0 - version: 3.24.0 + version: 3.24.0(supports-color@8.1.1) stylelint: specifier: ^16.1.0 version: 16.5.0(typescript@5.4.3) @@ -2612,7 +2615,7 @@ importers: version: 3.21.0(serverless@3.38.0) simple-git: specifier: ^3.24.0 - version: 3.24.0 + version: 3.24.0(supports-color@8.1.1) tmp-promise: specifier: ^3.0.3 version: 3.0.3 @@ -4006,8 +4009,8 @@ packages: '@fern-fern/generators-sdk@0.109.0-21be2e5be': resolution: {integrity: sha512-McFSFWNqfZBC7E0gUQfhj45tTl8Eu+6bahqD6FHf0fQm+TXI/oQf8mhPJw/TVqzAGxP/2kOzSYNqkDg1DwkIFQ==} - '@fern-fern/vercel@0.0.4650': - resolution: {integrity: sha512-gsbr84KmAIEWCxjMAZ0f57NrthEp1keAApEOK37r5Q/haATb3zR2JLM4FEeVsMclwF3u2N05eODyWBkSQAcaUw==} + '@fern-fern/vercel@0.0.4655': + resolution: {integrity: sha512-twz/gFcQo9Gk38byYLFsJDbHnvvBsOHfofdef15vzIeFCIr1yPsTWYmNoPllBeRLc4RjMel6T06afFZJMc8JSg==} '@fern-fern/vercel@0.0.7': resolution: {integrity: sha512-k3ioiJifaX1WYJzbEHHdtg/aIfBVTz5eMOtHoyvl7+qY/IdmYczDtpa+NSYzdfxOM5uAAoVxTGWCvAlagVv+Fg==} @@ -17069,7 +17072,7 @@ snapshots: '@babel/traverse': 7.24.5 '@babel/types': 7.24.5 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -17868,7 +17871,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.5 '@babel/parser': 7.24.5 '@babel/types': 7.24.5 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -17883,7 +17886,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.5 '@babel/parser': 7.24.5 '@babel/types': 7.24.5 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -18005,7 +18008,7 @@ snapshots: '@esbuild-plugins/node-resolve@0.2.2(esbuild@0.20.2)': dependencies: '@types/resolve': 1.20.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) esbuild: 0.20.2 escape-string-regexp: 4.0.0 resolve: 1.22.8 @@ -18091,7 +18094,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -18206,7 +18209,7 @@ snapshots: transitivePeerDependencies: - encoding - '@fern-fern/vercel@0.0.4650': + '@fern-fern/vercel@0.0.4655': dependencies: form-data: 4.0.0 js-base64: 3.7.2 @@ -18331,7 +18334,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -18764,12 +18767,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@kwsites/file-exists@1.1.1': - dependencies: - debug: 4.3.4(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - '@kwsites/file-exists@1.1.1(supports-color@8.1.1)': dependencies: debug: 4.3.4(supports-color@8.1.1) @@ -20335,7 +20332,7 @@ snapshots: '@sentry/cli@1.77.3': dependencies: - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.1(supports-color@8.1.1) mkdirp: 0.5.6 node-fetch: 2.7.0 progress: 2.0.3 @@ -20347,7 +20344,7 @@ snapshots: '@sentry/cli@2.31.2': dependencies: - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.1(supports-color@8.1.1) node-fetch: 2.7.0 progress: 2.0.3 proxy-from-env: 1.1.0 @@ -23031,7 +23028,7 @@ snapshots: '@typescript-eslint/type-utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) '@typescript-eslint/visitor-keys': 7.3.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -23049,7 +23046,7 @@ snapshots: '@typescript-eslint/types': 7.17.0 '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.4.3) '@typescript-eslint/visitor-keys': 7.17.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 optionalDependencies: typescript: 5.4.3 @@ -23062,7 +23059,7 @@ snapshots: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.3) '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 optionalDependencies: typescript: 5.4.3 @@ -23075,7 +23072,7 @@ snapshots: '@typescript-eslint/types': 7.3.1 '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.3) '@typescript-eslint/visitor-keys': 7.3.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 optionalDependencies: typescript: 5.4.3 @@ -23116,7 +23113,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.4.3) '@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.4.3) - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.3) optionalDependencies: @@ -23128,7 +23125,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.3) '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.3) optionalDependencies: @@ -23181,7 +23178,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 @@ -23211,7 +23208,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.3.1 '@typescript-eslint/visitor-keys': 7.3.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -26247,7 +26244,7 @@ snapshots: callsite: 1.0.0 camelcase: 6.3.0 cosmiconfig: 7.1.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) deps-regex: 0.2.0 findup-sync: 5.0.0 ignore: 5.3.1 @@ -26737,7 +26734,7 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) enhanced-resolve: 5.16.1 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) @@ -26951,7 +26948,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -28238,7 +28235,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -28249,13 +28246,6 @@ snapshots: https-browserify@1.0.0: {} - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2(supports-color@8.1.1) - debug: 4.3.4(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - https-proxy-agent@5.0.1(supports-color@8.1.1): dependencies: agent-base: 6.0.2(supports-color@8.1.1) @@ -28266,7 +28256,7 @@ snapshots: https-proxy-agent@7.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -28424,7 +28414,7 @@ snapshots: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -29367,7 +29357,7 @@ snapshots: dependencies: chalk: 5.3.0 commander: 11.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) execa: 7.2.0 lilconfig: 2.1.0 listr2: 6.6.1 @@ -30302,7 +30292,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -32706,14 +32696,6 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 - simple-git@3.24.0: - dependencies: - '@kwsites/file-exists': 1.1.1 - '@kwsites/promise-deferred': 1.1.1 - debug: 4.3.4(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - simple-git@3.24.0(supports-color@8.1.1): dependencies: '@kwsites/file-exists': 1.1.1(supports-color@8.1.1) @@ -33151,7 +33133,7 @@ snapshots: cosmiconfig: 9.0.0(typescript@5.4.3) css-functions-list: 3.2.2 css-tree: 2.3.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 8.0.0 @@ -33189,7 +33171,7 @@ snapshots: stylus@0.62.0: dependencies: '@adobe/css-tools': 4.3.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) glob: 7.2.3 sax: 1.3.0 source-map: 0.7.4 @@ -33740,7 +33722,7 @@ snapshots: bundle-require: 4.1.0(esbuild@0.20.2) cac: 6.7.14 chokidar: 3.6.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) esbuild: 0.20.2 execa: 5.1.1 globby: 11.1.0 @@ -34257,7 +34239,7 @@ snapshots: vite-node@1.6.0(@types/node@18.19.33)(less@4.2.0)(sass@1.77.0)(stylus@0.62.0)(terser@5.31.0): dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) pathe: 1.1.2 picocolors: 1.0.0 vite: 5.2.11(@types/node@18.19.33)(less@4.2.0)(sass@1.77.0)(stylus@0.62.0)(terser@5.31.0) @@ -34274,7 +34256,7 @@ snapshots: vite-node@1.6.0(@types/node@20.12.12)(less@4.2.0)(sass@1.77.0)(stylus@0.62.0)(terser@5.31.0): dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) pathe: 1.1.2 picocolors: 1.0.0 vite: 5.2.11(@types/node@20.12.12)(less@4.2.0)(sass@1.77.0)(stylus@0.62.0)(terser@5.31.0) @@ -34383,7 +34365,7 @@ snapshots: '@vitest/utils': 1.6.0 acorn-walk: 8.3.2 chai: 4.4.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 local-pkg: 0.5.0 magic-string: 0.30.10 @@ -34418,7 +34400,7 @@ snapshots: '@vitest/utils': 1.6.0 acorn-walk: 8.3.2 chai: 4.4.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 local-pkg: 0.5.0 magic-string: 0.30.10