From 11b9f708d67d381a0e493da2a2d618d67e5e6bca Mon Sep 17 00:00:00 2001 From: Rashad Karanouh <11599358+rashad@users.noreply.github.com> Date: Thu, 21 May 2026 23:14:20 +0400 Subject: [PATCH] feat(twenty-partners): add partners app (#20792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Adds `twenty-partners`, a Twenty app that manages the partner matching pipeline: intake partner-eligible deals, assign vetted marketplace partners, and track the full funnel - Custom `Partner` object with availability, geo/language coverage, deployment expertise, and Calendly link - `matchStatus` SELECT field on Opportunity — 10 non-nullable states from `TO_BE_MATCHED` through `WON`/`LOST`, replacing a legacy boolean approach - Auto-match logic function: when `matchStatus` → `AUTO_MATCH`, assigns the longest-idle available partner and advances to `MATCHED`; falls back to `MANUAL_MATCH` with an audit note if no partner is free - Views: Waiting for match, Matches overview (Kanban by `matchStatus`), All matched deals, Partners, Opportunities - Roles: Partner Ops (internal, full CRUD) and Partner (external placeholder) - Idempotent seed scripts for demo partners and pipeline data ## Test plan - [ ] App installs cleanly on a fresh workspace (`yarn twenty dev`) - [ ] `matchStatus` Kanban grouping renders correctly in Matches overview - [ ] Waiting for match view filters to `TO_BE_MATCHED` and `MANUAL_MATCH` only - [ ] Auto-match logic assigns a partner and advances status - [ ] Seed scripts run without errors and are safe to re-run --- .../internal/twenty-partners/.env.example | 6 + .../twenty-partners/.github/workflows/cd.yml | 42 + .../twenty-partners/.github/workflows/ci.yml | 48 + .../internal/twenty-partners/.gitignore | 43 + .../internal/twenty-partners/.nvmrc | 1 + .../internal/twenty-partners/.oxlintrc.json | 37 + .../internal/twenty-partners/.yarnrc.yml | 1 + .../internal/twenty-partners/README.md | 101 + .../internal/twenty-partners/package.json | 38 + .../00-seed-partners.integration-test.ts | 74 + .../src/__tests__/global-setup.ts | 87 + .../src/__tests__/schema.integration-test.ts | 46 + .../twenty-partners/src/application-config.ts | 13 + .../src/constants/universal-identifiers.ts | 41 + .../twenty-partners/src/default-role.ts | 16 + .../fields/opportunities-on-partner.field.ts | 18 + .../opportunity-design-doc-status.field.ts | 15 + .../opportunity-design-doc-url.field.ts | 10 + .../fields/opportunity-hosting-type.field.ts | 14 + .../fields/opportunity-intro-sent-at.field.ts | 11 + .../fields/opportunity-lost-reason.field.ts | 10 + .../fields/opportunity-match-status.field.ts | 26 + .../opportunity-number-of-seats.field.ts | 10 + ...pportunity-subscription-frequency.field.ts | 14 + .../opportunity-subscription-type.field.ts | 15 + .../src/fields/opportunity-tft-id.field.ts | 10 + .../src/fields/opportunity-use-case.field.ts | 10 + .../src/fields/partner-company.field.ts | 22 + .../fields/partner-on-opportunity.field.ts | 22 + .../src/fields/partner-on-person.field.ts | 22 + .../fields/partner-quote-opportunity.field.ts | 22 + .../src/fields/partner-quote-partner.field.ts | 22 + .../partner-quotes-on-opportunity.field.ts | 18 + .../fields/partner-quotes-on-partner.field.ts | 18 + .../src/fields/partners-on-company.field.ts | 18 + .../src/fields/person-discord.field.ts | 10 + .../src/fields/persons-on-partner.field.ts | 18 + ...opportunity-auto-match.integration-test.ts | 220 + .../list-available-partners.logic-function.ts | 75 + .../on-opportunity-auto-match.ts | 105 + .../src/logic-functions/post-install.ts | 48 + .../all-opportunities.navigation-menu-item.ts | 15 + .../matches-overview.navigation-menu-item.ts | 15 + ...rtner-applications.navigation-menu-item.ts | 15 + .../partner-deals.navigation-menu-item.ts | 15 + .../partner-quotes.navigation-menu-item.ts | 15 + .../partners-folder.navigation-menu-item.ts | 10 + .../partners.navigation-menu-item.ts | 15 + .../pipeline-folder.navigation-menu-item.ts | 9 + ...validated-partners.navigation-menu-item.ts | 15 + .../waiting-for-match.navigation-menu-item.ts | 15 + .../src/objects/partner-quote.object.ts | 65 + .../src/objects/partner.object.ts | 483 ++ .../twenty-partners/src/roles/partner.role.ts | 56 + .../src/roles/twenty-partner-ops.role.ts | 55 + .../src/scripts/import-from-tft.ts | 420 ++ .../twenty-partners/src/scripts/seed.ts | 195 + .../src/views/all-matched-deals.view.ts | 36 + .../src/views/all-opportunities.view.ts | 31 + .../src/views/all-partners.view.ts | 22 + .../src/views/matches-overview.view.ts | 29 + .../src/views/partner-applications.view.ts | 29 + .../src/views/partner-quotes.view.ts | 21 + .../src/views/validated-partners.view.ts | 30 + .../src/views/waiting-for-match.view.ts | 48 + .../internal/twenty-partners/tsconfig.json | 42 + .../twenty-partners/tsconfig.spec.json | 9 + .../internal/twenty-partners/vitest.config.ts | 40 + .../internal/twenty-partners/yarn.lock | 4607 +++++++++++++++++ 69 files changed, 7754 insertions(+) create mode 100644 packages/twenty-apps/internal/twenty-partners/.env.example create mode 100644 packages/twenty-apps/internal/twenty-partners/.github/workflows/cd.yml create mode 100644 packages/twenty-apps/internal/twenty-partners/.github/workflows/ci.yml create mode 100644 packages/twenty-apps/internal/twenty-partners/.gitignore create mode 100644 packages/twenty-apps/internal/twenty-partners/.nvmrc create mode 100644 packages/twenty-apps/internal/twenty-partners/.oxlintrc.json create mode 100644 packages/twenty-apps/internal/twenty-partners/.yarnrc.yml create mode 100644 packages/twenty-apps/internal/twenty-partners/README.md create mode 100644 packages/twenty-apps/internal/twenty-partners/package.json create mode 100644 packages/twenty-apps/internal/twenty-partners/src/__tests__/00-seed-partners.integration-test.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/__tests__/global-setup.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/__tests__/schema.integration-test.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/application-config.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/constants/universal-identifiers.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/default-role.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunities-on-partner.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-status.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-url.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-hosting-type.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-intro-sent-at.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-lost-reason.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-match-status.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-number-of-seats.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-frequency.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-type.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-tft-id.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-use-case.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-company.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-opportunity.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-person.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-opportunity.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-partner.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-opportunity.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-partner.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/partners-on-company.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/person-discord.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/fields/persons-on-partner.field.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/logic-functions/__tests__/on-opportunity-auto-match.integration-test.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/logic-functions/list-available-partners.logic-function.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/logic-functions/on-opportunity-auto-match.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/logic-functions/post-install.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/all-opportunities.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/matches-overview.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-applications.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-deals.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-quotes.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners-folder.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/pipeline-folder.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/validated-partners.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/waiting-for-match.navigation-menu-item.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/objects/partner-quote.object.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/objects/partner.object.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/roles/partner.role.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/roles/twenty-partner-ops.role.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/scripts/import-from-tft.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/scripts/seed.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/all-matched-deals.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/all-opportunities.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/all-partners.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/matches-overview.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/partner-applications.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/partner-quotes.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/validated-partners.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/src/views/waiting-for-match.view.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/tsconfig.json create mode 100644 packages/twenty-apps/internal/twenty-partners/tsconfig.spec.json create mode 100644 packages/twenty-apps/internal/twenty-partners/vitest.config.ts create mode 100644 packages/twenty-apps/internal/twenty-partners/yarn.lock diff --git a/packages/twenty-apps/internal/twenty-partners/.env.example b/packages/twenty-apps/internal/twenty-partners/.env.example new file mode 100644 index 0000000000..2996471ae6 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.env.example @@ -0,0 +1,6 @@ +# Credentials for integration tests (vitest.config.ts) and seed scripts +# (vitest.seed.config.ts). Copy this file to .env.local and fill in the key. +# Get an API key from the Twenty UI: Settings -> APIs & Webhooks. +# .env.local is gitignored; never commit a real key. +TWENTY_API_URL=http://localhost:2020 +TWENTY_API_KEY= diff --git a/packages/twenty-apps/internal/twenty-partners/.github/workflows/cd.yml b/packages/twenty-apps/internal/twenty-partners/.github/workflows/cd.yml new file mode 100644 index 0000000000..0ec483fc57 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.github/workflows/cd.yml @@ -0,0 +1,42 @@ +name: CD + +on: + push: + branches: + - main + pull_request: + types: [labeled] + +permissions: + contents: read + +env: + TWENTY_DEPLOY_URL: http://localhost:2020 + +concurrency: + group: cd-${{ github.ref }} + cancel-in-progress: true + +jobs: + deploy-and-install: + if: >- + github.event_name == 'push' || + (github.event_name == 'pull_request' && github.event.label.name == 'deploy') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Deploy + uses: twentyhq/twenty/.github/actions/deploy-twenty-app@main + with: + api-url: ${{ env.TWENTY_DEPLOY_URL }} + api-key: ${{ secrets.TWENTY_DEPLOY_API_KEY }} + + - name: Install + uses: twentyhq/twenty/.github/actions/install-twenty-app@main + with: + api-url: ${{ env.TWENTY_DEPLOY_URL }} + api-key: ${{ secrets.TWENTY_DEPLOY_API_KEY }} diff --git a/packages/twenty-apps/internal/twenty-partners/.github/workflows/ci.yml b/packages/twenty-apps/internal/twenty-partners/.github/workflows/ci.yml new file mode 100644 index 0000000000..9112ecb495 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: CI + +on: + push: + branches: + - main + pull_request: {} + +permissions: + contents: read + +env: + TWENTY_VERSION: latest + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Spawn Twenty test instance + id: twenty + uses: twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main + with: + twenty-version: ${{ env.TWENTY_VERSION }} + + - name: Enable Corepack + run: corepack enable + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: yarn + + - name: Install dependencies + run: yarn install --immutable + + - name: Run integration tests + run: yarn test + env: + TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }} + TWENTY_API_KEY: ${{ steps.twenty.outputs.api-key }} diff --git a/packages/twenty-apps/internal/twenty-partners/.gitignore b/packages/twenty-apps/internal/twenty-partners/.gitignore new file mode 100644 index 0000000000..ff704a82b0 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.gitignore @@ -0,0 +1,43 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn + +# codegen +generated + +# testing +/coverage + +# dev +/dist/ + +.twenty + +# production +/build + +# misc +.DS_Store + +# internal planning docs +docs/superpowers/ +**/docs/superpowers/ +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* +!.env.example + +# typescript +*.tsbuildinfo +*.d.ts diff --git a/packages/twenty-apps/internal/twenty-partners/.nvmrc b/packages/twenty-apps/internal/twenty-partners/.nvmrc new file mode 100644 index 0000000000..341cb50613 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.nvmrc @@ -0,0 +1 @@ +24.5.0 diff --git a/packages/twenty-apps/internal/twenty-partners/.oxlintrc.json b/packages/twenty-apps/internal/twenty-partners/.oxlintrc.json new file mode 100644 index 0000000000..369b9cfd76 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.oxlintrc.json @@ -0,0 +1,37 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript"], + "categories": { + "correctness": "off" + }, + "ignorePatterns": ["node_modules", "dist"], + "rules": { + "no-unused-vars": "off", + + "typescript/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_" + } + ], + "typescript/no-explicit-any": "off" + }, + "overrides": [ + { + "files": ["**/*.logic-function.ts", "**/logic-functions/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "group": ["twenty-shared", "twenty-shared/*"], + "message": "Logic functions must not import from twenty-shared directly. Import runtime types and helpers from `twenty-sdk/logic-function` instead so the logic-function bundle stays minimal." + } + ] + } + ] + } + } + ] +} diff --git a/packages/twenty-apps/internal/twenty-partners/.yarnrc.yml b/packages/twenty-apps/internal/twenty-partners/.yarnrc.yml new file mode 100644 index 0000000000..3186f3f079 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/packages/twenty-apps/internal/twenty-partners/README.md b/packages/twenty-apps/internal/twenty-partners/README.md new file mode 100644 index 0000000000..f41fe44bbd --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/README.md @@ -0,0 +1,101 @@ +# twenty-partners + +A Twenty app that turns the CRM into the operating system for the Twenty partner program: +intake partner-eligible deals, match them to vetted marketplace partners, and track the +matching pipeline end-to-end. + +Built on [Twenty](https://twenty.com) with [`twenty-sdk`](https://www.npmjs.com/package/twenty-sdk) v2.5. + +## What's inside + +- **Custom object: `Partner`** — slug, status, availability, served geos, languages spoken, + deployment expertise, Calendly link, last-match timestamp. See `src/objects/partner.object.ts`. +- **Opportunity extensions** — `matchStatus`, `designDocStatus`, + `introSentAt`, `lastRelanceSentAt`, `tftId`, plus a `partner` relation. +- **Logic functions** + - `on-opportunity-auto-match` — fires when `matchStatus` is set to `AUTO_MATCH`. Assigns the longest-idle available partner and flips status to `MATCHED`. If no partner is available, hands off to `MANUAL_MATCH` with an audit Note explaining why. + - `list-available-partners` — surfaces matchable partners for a given opportunity. + - `post-install` — first-run setup. +- **Roles** (`src/roles/`) + - **Twenty Partner Ops** — internal team role, full CRUD on Partner/Company/Person/Opportunity. + - **Partner** — placeholder external-partner role. *Do not assign until Twenty ships + row-level permissions* — it currently grants access to every record. +- **Views** (`src/views/`) + - `Waiting for match` — opportunities awaiting human action (`matchStatus` is `TO_BE_MATCHED` or `MANUAL_MATCH`). + - `Matches overview` — full matching funnel grouped by `matchStatus` (configure Kanban + grouping manually in the UI). + - `Opportunities` — replacement of the native opportunities view with the partner columns. + - `Partners` and `All matched deals` — partner-side index and deal log. +- **Sidebar nav** — surfaced in workflow order: `Waiting for match`, `All partner deals`, + `Matches overview`, `Partners`, `Opportunities`. +- **Seed scripts** (`src/scripts/`) — populate a fresh workspace with realistic demo data. + +## Match status pipeline + +`matchStatus` is a non-nullable SELECT field with a default of `TO_BE_MATCHED`. The 10 states follow the deal lifecycle: + +| Status | Meaning | +| --- | --- | +| `TO_BE_MATCHED` | Default — deal entered, awaiting assignment | +| `MANUAL_MATCH` | Needs a human to pick a partner | +| `AUTO_MATCH` | Triggers automatic partner assignment | +| `MATCHED` | Partner assigned | +| `INTRODUCED_TO_A_PARTNER` | Customer intro sent | +| `WORKING_WITH_A_PARTNER` | Engagement underway | +| `IMPLEMENTING` | Active implementation | +| `WON` | Deal closed won | +| `RECONNECT_LATER` | Paused — reconnect in future | +| `LOST` | Deal closed lost | + +## Getting started + +Requires a local Twenty server at `http://localhost:2020` and Node `^24.5`. + +```bash +yarn install +yarn twenty dev +``` + +Default dev credentials: `tim@apple.dev` / `tim@apple.dev`. + +Run `yarn twenty help` for the full CLI reference. + +## Common commands + +| Command | What it does | +| --- | --- | +| `yarn twenty dev` | Start the dev server and sync the app on file changes | +| `yarn twenty server status` | Check the local Twenty server | +| `yarn lint` / `yarn lint:fix` | Run oxlint | +| `yarn test` | Run integration tests (`vitest.config.ts`) | + +## Seeding demo data + +Two idempotent seed scripts. Both run via the `vitest.seed.config.ts` config that skips +the global app uninstall/reinstall. + +```bash +# 1. Marketplace partners (run first — pipeline seed wires opportunities to these by slug) +yarn vitest run --config vitest.seed.config.ts src/scripts/seed-marketplace-partners.ts + +# 2. Pipeline demo: 3 companies, 3 people, 15 opportunities spread across matchStatus values +yarn vitest run --config vitest.seed.config.ts src/scripts/seed-pipeline-demo.ts +``` + +Both scripts skip records that already exist (by `slug`, `name`, or `firstName+lastName`), +so they are safe to re-run. + +## Known limitations + +Current SDK gaps blocking further polish: + +- Custom Partner record page layout (RECORD_TABLE has no relation scoping). +- Native Opportunities view column-order override. +- Kanban view configuration from app code (`ViewType.KANBAN` is currently ignored). +- App and field descriptions. + +## Learn more + +- [Twenty Apps documentation](https://docs.twenty.com/developers/extend/apps/getting-started/quick-start) +- [`twenty-sdk` on npm](https://www.npmjs.com/package/twenty-sdk) +- [Discord](https://discord.gg/cx5n4Jzs57) diff --git a/packages/twenty-apps/internal/twenty-partners/package.json b/packages/twenty-apps/internal/twenty-partners/package.json new file mode 100644 index 0000000000..93c2f18d26 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/package.json @@ -0,0 +1,38 @@ +{ + "name": "twenty-partners", + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": "^24.5.0", + "npm": "please-use-yarn", + "yarn": ">=4.0.2" + }, + "keywords": [], + "packageManager": "yarn@4.9.2", + "scripts": { + "twenty": "twenty", + "lint": "oxlint -c .oxlintrc.json .", + "lint:fix": "oxlint --fix -c .oxlintrc.json .", + "test": "vitest run", + "test:watch": "vitest", + "seed": "tsx src/scripts/seed.ts", + "import:dryrun": "tsx src/scripts/import-from-tft.ts", + "import:apply": "IMPORT_APPLY=1 tsx src/scripts/import-from-tft.ts" + }, + "dependencies": { + "twenty-client-sdk": "2.4.0", + "twenty-sdk": "2.4.0" + }, + "devDependencies": { + "@types/node": "^24.7.2", + "@types/react": "^19.0.0", + "dotenv": "^16.0.0", + "oxlint": "^0.16.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tsx": "^4.0.0", + "typescript": "^5.9.3", + "vite-tsconfig-paths": "^4.2.1", + "vitest": "^3.1.1" + } +} diff --git a/packages/twenty-apps/internal/twenty-partners/src/__tests__/00-seed-partners.integration-test.ts b/packages/twenty-apps/internal/twenty-partners/src/__tests__/00-seed-partners.integration-test.ts new file mode 100644 index 0000000000..5a1063f9aa --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/__tests__/00-seed-partners.integration-test.ts @@ -0,0 +1,74 @@ +// Seed file: ensures at least one ACTIVE + AVAILABLE partner exists before +// the matching integration tests run. Idempotent — skips if already seeded. +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { beforeAll, describe, it } from 'vitest'; + +describe('seed: marketplace partners', () => { + let client: CoreApiClient; + + beforeAll(() => { + client = new CoreApiClient(); + }); + + it('ensures at least one ACTIVE AVAILABLE partner exists', async () => { + const existingResult = await client.query({ + partners: { + __args: { + filter: { validationStage: { eq: 'VALIDATED' }, availability: { eq: 'AVAILABLE' } }, + first: 1, + }, + edges: { node: { id: true } }, + }, + } as any); + + const existing = (existingResult as any).partners.edges; + if (existing.length > 0) { + console.log('[seed] partner already exists, skipping'); + return; + } + + const PARTNERS = [ + { + slug: 'nine-dots-ventures', + name: 'Nine Dots Ventures', + introduction: 'Boutique CRM implementer specialising in real-estate workflows.', + calendlyLink: 'https://calendly.com/placeholder', + deploymentExpertise: ['CLOUD', 'SELF_HOST'], + servedGeos: ['EUROPE', 'MENA'], + languagesSpoken: ['ENGLISH', 'FRENCH'], + }, + { + slug: 'elevate-consulting', + name: 'Elevate Consulting', + introduction: 'Revenue-operations partner for B2B SaaS teams.', + calendlyLink: 'https://calendly.com/placeholder', + deploymentExpertise: ['CLOUD'], + servedGeos: ['US', 'LATAM'], + languagesSpoken: ['ENGLISH', 'SPANISH'], + }, + ]; + + for (const p of PARTNERS) { + const r = await client.mutation({ + createPartner: { + __args: { + data: { + name: p.name, + slug: p.slug, + introduction: p.introduction, + calendarLink: { primaryLinkUrl: p.calendlyLink }, + deploymentExpertise: p.deploymentExpertise, + region: p.servedGeos, + languagesSpoken: p.languagesSpoken, + validationStage: 'VALIDATED', + availability: 'AVAILABLE', + }, + }, + id: true, + name: true, + }, + } as any); + console.log('[seed] created', (r as any).createPartner.name); + } + }); +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/__tests__/global-setup.ts b/packages/twenty-apps/internal/twenty-partners/src/__tests__/global-setup.ts new file mode 100644 index 0000000000..76d5993737 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/__tests__/global-setup.ts @@ -0,0 +1,87 @@ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; + +import { appDevOnce, appUninstall } from 'twenty-sdk/cli'; + +const APP_PATH = process.cwd(); +const CONFIG_DIR = path.join(os.homedir(), '.twenty'); + +function validateEnv(): { apiUrl: string; apiKey: string } { + const apiUrl = process.env.TWENTY_API_URL; + const apiKey = process.env.TWENTY_API_KEY; + + if (!apiUrl || !apiKey) { + throw new Error( + 'TWENTY_API_URL and TWENTY_API_KEY must be set.\n' + + 'Start a local server: yarn twenty server start\n' + + 'Or set them in vitest env config.', + ); + } + + return { apiUrl, apiKey }; +} + +async function checkServer(apiUrl: string) { + let response: Response; + + try { + response = await fetch(`${apiUrl}/healthz`); + } catch { + throw new Error( + `Twenty server is not reachable at ${apiUrl}. ` + + 'Make sure the server is running before executing integration tests.', + ); + } + + if (!response.ok) { + throw new Error(`Server at ${apiUrl} returned ${response.status}`); + } +} + +function writeConfig(apiUrl: string, apiKey: string) { + const payload = JSON.stringify( + { + remotes: { + local: { apiUrl, apiKey, accessToken: apiKey }, + }, + defaultRemote: 'local', + }, + null, + 2, + ); + + fs.mkdirSync(CONFIG_DIR, { recursive: true }); + fs.writeFileSync(path.join(CONFIG_DIR, 'config.test.json'), payload); +} + +export async function setup() { + const { apiUrl, apiKey } = validateEnv(); + + await checkServer(apiUrl); + + writeConfig(apiUrl, apiKey); + + await appUninstall({ appPath: APP_PATH }).catch(() => {}); + + const result = await appDevOnce({ + appPath: APP_PATH, + onProgress: (message: string) => console.log(`[dev] ${message}`), + }); + + if (!result.success) { + throw new Error( + `Dev sync failed: ${result.error?.message ?? 'Unknown error'}`, + ); + } +} + +export async function teardown() { + const uninstallResult = await appUninstall({ appPath: APP_PATH }); + + if (!uninstallResult.success) { + console.warn( + `App uninstall failed: ${uninstallResult.error?.message ?? 'Unknown error'}`, + ); + } +} diff --git a/packages/twenty-apps/internal/twenty-partners/src/__tests__/schema.integration-test.ts b/packages/twenty-apps/internal/twenty-partners/src/__tests__/schema.integration-test.ts new file mode 100644 index 0000000000..31007e28e9 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/__tests__/schema.integration-test.ts @@ -0,0 +1,46 @@ +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; +import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { describe, expect, it } from 'vitest'; + +describe('App installation', () => { + it('should find the installed app in the applications list', async () => { + const client = new MetadataApiClient(); + + const result = await client.query({ + findManyApplications: { + id: true, + name: true, + universalIdentifier: true, + }, + }); + + const app = result.findManyApplications.find( + (a: { universalIdentifier: string }) => + a.universalIdentifier === APPLICATION_UNIVERSAL_IDENTIFIER, + ); + + expect(app).toBeDefined(); + }); +}); + +describe('CoreApiClient', () => { + it('should support CRUD on standard objects', async () => { + const client = new CoreApiClient(); + + const created = await client.mutation({ + createNote: { + __args: { data: { title: 'Integration test note' } }, + id: true, + }, + }); + expect(created.createNote.id).toBeDefined(); + + await client.mutation({ + destroyNote: { + __args: { id: created.createNote.id }, + id: true, + }, + }); + }); +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/application-config.ts b/packages/twenty-apps/internal/twenty-partners/src/application-config.ts new file mode 100644 index 0000000000..088f9d1ea9 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/application-config.ts @@ -0,0 +1,13 @@ +import { defineApplication } from 'twenty-sdk/define'; + +import { + APP_DESCRIPTION, + APP_DISPLAY_NAME, + APPLICATION_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineApplication({ + universalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER, + displayName: APP_DISPLAY_NAME, + description: APP_DESCRIPTION, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/constants/universal-identifiers.ts b/packages/twenty-apps/internal/twenty-partners/src/constants/universal-identifiers.ts new file mode 100644 index 0000000000..a5c5d00384 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/constants/universal-identifiers.ts @@ -0,0 +1,41 @@ +export const APP_DISPLAY_NAME = 'Twenty partners'; +export const APP_DESCRIPTION = ''; +export const APPLICATION_UNIVERSAL_IDENTIFIER = 'e662fc1f-02c1-41ff-b8ba-c95a447b3965'; +export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER = 'ee18c3f3-ebe7-4c56-ad6d-aad555cc32db'; +export const PARTNER_OBJECT_UNIVERSAL_IDENTIFIER = '39101b39-1c16-4148-9e82-45dc271bb90d'; +export const PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER = '65172140-d377-41c1-a2ae-190e96fb79dd'; +export const ALL_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER = '379b11d5-44d5-476b-ba7d-31d5f515c9b4'; +export const ALL_MATCHED_DEALS_VIEW_UNIVERSAL_IDENTIFIER = '7a34da39-a8e1-44c7-88b4-91ceaa064920'; +export const PARTNERS_NAV_UNIVERSAL_IDENTIFIER = '3fe15ab5-e38b-4914-af17-2270b210aeb2'; +export const PARTNER_DEALS_NAV_UNIVERSAL_IDENTIFIER = 'c5e4ac36-bede-4f4b-bfe8-bbd09518abae'; +export const ON_OPP_AUTO_MATCH_FN_UNIVERSAL_IDENTIFIER = 'eb8d4d26-8103-4b66-9026-6a86556f7ca5'; +export const POST_INSTALL_FN_UNIVERSAL_IDENTIFIER = 'f92bad2e-5905-4757-96ee-af9869d4ca0c'; +export const MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER = 'd8dd0623-3a4c-4ab3-a1e0-4ece7df24fb2'; +export const INTRO_SENT_AT_FIELD_UNIVERSAL_IDENTIFIER = 'fcf39b0c-0547-415e-806d-b238131ad7cc'; + +// Roles (Task 2) +export const TWENTY_PARTNER_OPS_ROLE_UNIVERSAL_IDENTIFIER = '3340ca65-863d-4cdc-95c9-8abdec13d0f6'; +export const PARTNER_ROLE_UNIVERSAL_IDENTIFIER = 'c3c1dc2e-1a08-4de5-abb7-2139b3d99343'; + +// Views (Task 3) +export const WAITING_FOR_MATCH_VIEW_UNIVERSAL_IDENTIFIER = 'fe11e738-6bf3-4714-929c-51c76a3fd050'; +export const MATCHES_OVERVIEW_VIEW_UNIVERSAL_IDENTIFIER = '5a8fd51a-cf9e-4a6a-b1b4-b833b215fc1c'; + +// Nav items (Task 5) +export const WAITING_FOR_MATCH_NAV_UNIVERSAL_IDENTIFIER = '00be7449-8927-47c8-a6a1-212d9106587f'; +export const MATCHES_OVERVIEW_NAV_UNIVERSAL_IDENTIFIER = '0cf349c9-fcbf-40f8-8e91-142c02bbde9c'; + +// Page layout (Task 6) +export const PARTNER_RECORD_PAGE_UNIVERSAL_IDENTIFIER = 'a888b39e-d64a-48ba-a044-d8cb685fad74'; + +// All Opportunities view + nav +export const ALL_OPPORTUNITIES_VIEW_UNIVERSAL_IDENTIFIER = '6ce1300b-6e91-4c28-83bb-6f692dbc7a98'; +export const ALL_OPPORTUNITIES_NAV_UNIVERSAL_IDENTIFIER = '37944f52-cbe5-4814-a1e6-be5b21425870'; + +// Partner views + nav (harmonization) +export const PARTNER_APPLICATIONS_VIEW_UNIVERSAL_IDENTIFIER = 'b57a84ed-d7c1-420d-b0eb-348db0dac612'; +export const VALIDATED_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER = '13cca6a7-b9f1-4103-b011-ea2e39430899'; +export const PARTNER_QUOTES_VIEW_UNIVERSAL_IDENTIFIER = 'd9db705c-795a-4a14-b891-6201149510b3'; +export const PARTNER_APPLICATIONS_NAV_UNIVERSAL_IDENTIFIER = '13e2334a-6b1e-4080-8c74-d11109990cc1'; +export const VALIDATED_PARTNERS_NAV_UNIVERSAL_IDENTIFIER = '6aed30c6-d80f-4ac6-aab0-db5bc59e5c4b'; +export const PARTNER_QUOTES_NAV_UNIVERSAL_IDENTIFIER = '3543723d-80c1-466a-ac35-86f7b284917b'; diff --git a/packages/twenty-apps/internal/twenty-partners/src/default-role.ts b/packages/twenty-apps/internal/twenty-partners/src/default-role.ts new file mode 100644 index 0000000000..a6abf65445 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/default-role.ts @@ -0,0 +1,16 @@ +import { defineApplicationRole } from 'twenty-sdk/define'; + +import { + APP_DISPLAY_NAME, + DEFAULT_ROLE_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineApplicationRole({ + universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER, + label: `${APP_DISPLAY_NAME} default function role`, + description: `${APP_DISPLAY_NAME} default function role`, + canReadAllObjectRecords: true, + canUpdateAllObjectRecords: true, + canSoftDeleteAllObjectRecords: true, + canDestroyAllObjectRecords: false, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunities-on-partner.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunities-on-partner.field.ts new file mode 100644 index 0000000000..3a88674b3b --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunities-on-partner.field.ts @@ -0,0 +1,18 @@ +import { FieldType, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { OPPORTUNITIES_ON_PARTNER_FIELD_ID, PARTNER_ON_OPPORTUNITY_FIELD_ID } from './partner-on-opportunity.field'; + +export default defineField({ + universalIdentifier: OPPORTUNITIES_ON_PARTNER_FIELD_ID, + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'opportunities', + label: 'Opportunities', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_ON_OPPORTUNITY_FIELD_ID, + universalSettings: { + relationType: RelationType.ONE_TO_MANY, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-status.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-status.field.ts new file mode 100644 index 0000000000..b5ca6a39e5 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-status.field.ts @@ -0,0 +1,15 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: 'cc6b8a59-f860-493f-8b9a-f138c078fbf1', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.SELECT, + name: 'designDocStatus', + label: 'Design Doc Status', + defaultValue: "'DRAFT'", + options: [ + { id: '1901c790-22af-4149-a792-09374d67acfd', value: 'DRAFT', label: 'Draft', position: 0, color: 'gray' }, + { id: '02cbe191-cc96-4b42-9d8e-f85cd47bed24', value: 'DONE', label: 'Done', position: 1, color: 'green' }, + { id: '943e1389-12cd-4605-8066-db27ba68a50a', value: 'SHARED_WITH_PARTNER', label: 'Shared with Partner', position: 2, color: 'blue' }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-url.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-url.field.ts new file mode 100644 index 0000000000..9d1869a427 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-design-doc-url.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '37e5428c-6c8c-4616-b626-f0ea1caa443d', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.LINKS, + name: 'designDocUrl', + label: 'Design Doc URL', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-hosting-type.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-hosting-type.field.ts new file mode 100644 index 0000000000..21e21547c9 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-hosting-type.field.ts @@ -0,0 +1,14 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '7ac7517f-bbca-4b4c-8996-6f864f71219b', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.SELECT, + name: 'hostingType', + label: 'Hosting Type', + isNullable: true, + options: [ + { id: '42c108d7-a874-4d1f-be4c-e87edd08f3c7', value: 'CLOUD', label: 'Cloud', position: 0, color: 'sky' }, + { id: '0fe995f4-42de-4160-96af-b3e7d542dfdd', value: 'SELF_HOSTING', label: 'Self-hosting', position: 1, color: 'purple' }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-intro-sent-at.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-intro-sent-at.field.ts new file mode 100644 index 0000000000..acc5097d84 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-intro-sent-at.field.ts @@ -0,0 +1,11 @@ +import { INTRO_SENT_AT_FIELD_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: INTRO_SENT_AT_FIELD_UNIVERSAL_IDENTIFIER, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.DATE_TIME, + name: 'introSentAt', + label: 'Intro Sent At', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-lost-reason.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-lost-reason.field.ts new file mode 100644 index 0000000000..570a3d107b --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-lost-reason.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '834e233d-b171-409e-825f-77ac49b0f19d', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.TEXT, + name: 'lostReason', + label: 'Lost Reason', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-match-status.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-match-status.field.ts new file mode 100644 index 0000000000..5ef62648d3 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-match-status.field.ts @@ -0,0 +1,26 @@ +import { MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.SELECT, + name: 'matchStatus', + label: 'Match Status', + isNullable: false, + defaultValue: "'TO_BE_MATCHED'", + options: [ + // Pre-match (new). NEW UUIDs generated with `uuidgen` (v4). + { id: '8b3a1c0e-2f64-4a87-9d2b-1e3c4f5a6b78', value: 'TO_BE_MATCHED', label: 'To Be Matched', position: 0, color: 'grey' }, + { id: '4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f', value: 'MANUAL_MATCH', label: 'Manual Match', position: 1, color: 'grey' }, + { id: '7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b', value: 'AUTO_MATCH', label: 'Auto Match', position: 2, color: 'yellow' }, + // Post-match. Reuse DELIVERED's UUID for MATCHED so existing rows auto-relabel. + { id: '095428d8-4680-4a2c-af83-7809dcb3f194', value: 'MATCHED', label: 'Matched', position: 3, color: 'blue' }, + { id: '2f1c79a1-ca91-4937-a4c0-6422f6534d34', value: 'INTRODUCED_TO_A_PARTNER', label: 'Introduced to a partner', position: 4, color: 'sky' }, + { id: '45cdf6ef-8672-40d5-b71f-1e5687ba5776', value: 'WORKING_WITH_A_PARTNER', label: 'Working with a partner', position: 5, color: 'turquoise' }, + { id: '7189b18d-b0f7-435a-9272-f812cba5d13d', value: 'IMPLEMENTING', label: 'Implementing', position: 6, color: 'green' }, + { id: '54cd33bc-11ea-42f1-87c8-cd9d32d2c266', value: 'WON', label: 'Won', position: 7, color: 'purple' }, + { id: '505433e8-5367-4dfb-a89a-708d5182165b', value: 'RECONNECT_LATER', label: 'Reconnect later', position: 8, color: 'orange' }, + { id: '572a9ad2-e0a6-49f2-b1f5-e36c75cc5176', value: 'LOST', label: 'Lost', position: 9, color: 'red' }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-number-of-seats.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-number-of-seats.field.ts new file mode 100644 index 0000000000..a087f1ee90 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-number-of-seats.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '90c683ec-2365-4533-a187-7b9ae162b753', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.NUMBER, + name: 'numberOfSeats', + label: 'Number of Seats', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-frequency.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-frequency.field.ts new file mode 100644 index 0000000000..accee28b0c --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-frequency.field.ts @@ -0,0 +1,14 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '59d5de53-202f-4913-a417-8a08970d87cc', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.SELECT, + name: 'subscriptionFrequency', + label: 'Subscription Frequency', + isNullable: true, + options: [ + { id: 'e53a9ebb-11d6-40de-93f2-6bcb6ab7141c', value: 'MONTHLY', label: 'Monthly', position: 0, color: 'blue' }, + { id: '6eca9f01-f891-4c9d-bef6-9238c8e67392', value: 'ANNUAL', label: 'Annual', position: 1, color: 'green' }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-type.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-type.field.ts new file mode 100644 index 0000000000..c11bd2f920 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-subscription-type.field.ts @@ -0,0 +1,15 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: 'a58214e9-38f9-4faf-8927-09b3980fd8c3', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.SELECT, + name: 'subscriptionType', + label: 'Subscription Type', + isNullable: true, + options: [ + { id: '6d91b477-5bf1-4f5c-8aef-577b6c21fe45', value: 'PRO', label: 'Pro', position: 0, color: 'blue' }, + { id: '7b64f281-3445-4429-a5f0-af9484dff8b4', value: 'ORG', label: 'Org', position: 1, color: 'green' }, + { id: 'bf202f8f-caf9-45bf-a80c-65b344b2798d', value: 'ENT', label: 'Enterprise', position: 2, color: 'purple' }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-tft-id.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-tft-id.field.ts new file mode 100644 index 0000000000..1d1ff67ce1 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-tft-id.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '2e3e1d04-2719-4e0d-9a6b-ec73acf896c5', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.TEXT, + name: 'tftOpportunityId', + label: 'TfT Opportunity ID', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-use-case.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-use-case.field.ts new file mode 100644 index 0000000000..a72a471e5b --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/opportunity-use-case.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: '1bc57f52-a621-4243-ae3e-05c3f504b90c', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.TEXT, + name: 'useCase', + label: 'Use Case', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-company.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-company.field.ts new file mode 100644 index 0000000000..4c045570e1 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-company.field.ts @@ -0,0 +1,22 @@ +import { FieldType, OnDeleteAction, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export const PARTNER_COMPANY_FIELD_ID = '2779015b-28fa-4117-8ce1-b0c98cf16de2'; +export const PARTNERS_ON_COMPANY_FIELD_ID = '2896d888-a4ab-4c29-bf63-e8bfdbd1924f'; + +export default defineField({ + universalIdentifier: PARTNER_COMPANY_FIELD_ID, + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'company', + label: 'Company', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier, + relationTargetFieldMetadataUniversalIdentifier: PARTNERS_ON_COMPANY_FIELD_ID, + universalSettings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: OnDeleteAction.SET_NULL, + joinColumnName: 'companyId', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-opportunity.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-opportunity.field.ts new file mode 100644 index 0000000000..d6c0374207 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-opportunity.field.ts @@ -0,0 +1,22 @@ +import { FieldType, OnDeleteAction, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export const PARTNER_ON_OPPORTUNITY_FIELD_ID = 'd9eeacaa-2f9e-44cc-b5f6-5e1526256d49'; +export const OPPORTUNITIES_ON_PARTNER_FIELD_ID = '8c04a5d4-c423-487e-bd78-7142a75b2896'; + +export default defineField({ + universalIdentifier: PARTNER_ON_OPPORTUNITY_FIELD_ID, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.RELATION, + name: 'partner', + label: 'Partner', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: OPPORTUNITIES_ON_PARTNER_FIELD_ID, + universalSettings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: OnDeleteAction.SET_NULL, + joinColumnName: 'partnerId', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-person.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-person.field.ts new file mode 100644 index 0000000000..55563651e2 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-on-person.field.ts @@ -0,0 +1,22 @@ +import { FieldType, OnDeleteAction, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export const PARTNER_ON_PERSON_FIELD_ID = 'b49eeaa3-c7ef-4a5c-8c47-d2c234b5122f'; +export const PERSONS_ON_PARTNER_FIELD_ID = '2c0e2035-db52-434b-9706-cd2210009a86'; + +export default defineField({ + universalIdentifier: PARTNER_ON_PERSON_FIELD_ID, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier, + type: FieldType.RELATION, + name: 'partner', + label: 'Partner', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: PERSONS_ON_PARTNER_FIELD_ID, + universalSettings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: OnDeleteAction.SET_NULL, + joinColumnName: 'partnerId', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-opportunity.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-opportunity.field.ts new file mode 100644 index 0000000000..ebb76ce893 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-opportunity.field.ts @@ -0,0 +1,22 @@ +import { FieldType, OnDeleteAction, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export const PARTNER_QUOTE_OPPORTUNITY_FIELD_ID = '36684f3e-f01a-4270-8f34-78966747dd64'; +export const PARTNER_QUOTES_ON_OPPORTUNITY_FIELD_ID = '4857f339-a051-4cdb-bd8a-6219b933d1ce'; + +export default defineField({ + universalIdentifier: PARTNER_QUOTE_OPPORTUNITY_FIELD_ID, + objectUniversalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'opportunity', + label: 'Opportunity', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_QUOTES_ON_OPPORTUNITY_FIELD_ID, + universalSettings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: OnDeleteAction.SET_NULL, + joinColumnName: 'opportunityId', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-partner.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-partner.field.ts new file mode 100644 index 0000000000..5be6eaf4f8 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quote-partner.field.ts @@ -0,0 +1,22 @@ +import { FieldType, OnDeleteAction, RelationType, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export const PARTNER_QUOTE_PARTNER_FIELD_ID = '1774738e-96a1-43e2-aca4-d3c7cc794c50'; +export const PARTNER_QUOTES_ON_PARTNER_FIELD_ID = 'ac7995f1-7ccf-4607-827b-0788eeacaee0'; + +export default defineField({ + universalIdentifier: PARTNER_QUOTE_PARTNER_FIELD_ID, + objectUniversalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'partner', + label: 'Partner', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_QUOTES_ON_PARTNER_FIELD_ID, + universalSettings: { + relationType: RelationType.MANY_TO_ONE, + onDelete: OnDeleteAction.SET_NULL, + joinColumnName: 'partnerId', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-opportunity.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-opportunity.field.ts new file mode 100644 index 0000000000..7fca6961cd --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-opportunity.field.ts @@ -0,0 +1,18 @@ +import { FieldType, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { PARTNER_QUOTES_ON_OPPORTUNITY_FIELD_ID, PARTNER_QUOTE_OPPORTUNITY_FIELD_ID } from './partner-quote-opportunity.field'; + +export default defineField({ + universalIdentifier: PARTNER_QUOTES_ON_OPPORTUNITY_FIELD_ID, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: FieldType.RELATION, + name: 'partnerQuotes', + label: 'Partner Quotes', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_QUOTE_OPPORTUNITY_FIELD_ID, + universalSettings: { + relationType: RelationType.ONE_TO_MANY, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-partner.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-partner.field.ts new file mode 100644 index 0000000000..afcf1f3386 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partner-quotes-on-partner.field.ts @@ -0,0 +1,18 @@ +import { FieldType, RelationType, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { PARTNER_QUOTES_ON_PARTNER_FIELD_ID, PARTNER_QUOTE_PARTNER_FIELD_ID } from './partner-quote-partner.field'; + +export default defineField({ + universalIdentifier: PARTNER_QUOTES_ON_PARTNER_FIELD_ID, + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'partnerQuotes', + label: 'Partner Quotes', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_QUOTE_PARTNER_FIELD_ID, + universalSettings: { + relationType: RelationType.ONE_TO_MANY, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/partners-on-company.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/partners-on-company.field.ts new file mode 100644 index 0000000000..f326e29ad8 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/partners-on-company.field.ts @@ -0,0 +1,18 @@ +import { FieldType, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { PARTNERS_ON_COMPANY_FIELD_ID, PARTNER_COMPANY_FIELD_ID } from './partner-company.field'; + +export default defineField({ + universalIdentifier: PARTNERS_ON_COMPANY_FIELD_ID, + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier, + type: FieldType.RELATION, + name: 'partners', + label: 'Partners', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_COMPANY_FIELD_ID, + universalSettings: { + relationType: RelationType.ONE_TO_MANY, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/person-discord.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/person-discord.field.ts new file mode 100644 index 0000000000..86f3dec2ef --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/person-discord.field.ts @@ -0,0 +1,10 @@ +import { FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +export default defineField({ + universalIdentifier: 'c6862035-bf2e-42ea-86c4-bf46636f7859', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier, + type: FieldType.TEXT, + name: 'discord', + label: 'Discord', + isNullable: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/fields/persons-on-partner.field.ts b/packages/twenty-apps/internal/twenty-partners/src/fields/persons-on-partner.field.ts new file mode 100644 index 0000000000..c93b4a0197 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/fields/persons-on-partner.field.ts @@ -0,0 +1,18 @@ +import { FieldType, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineField } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; +import { PARTNER_ON_PERSON_FIELD_ID, PERSONS_ON_PARTNER_FIELD_ID } from './partner-on-person.field'; + +export default defineField({ + universalIdentifier: PERSONS_ON_PARTNER_FIELD_ID, + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: FieldType.RELATION, + name: 'persons', + label: 'Persons', + isNullable: true, + relationTargetObjectMetadataUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier, + relationTargetFieldMetadataUniversalIdentifier: PARTNER_ON_PERSON_FIELD_ID, + universalSettings: { + relationType: RelationType.ONE_TO_MANY, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/logic-functions/__tests__/on-opportunity-auto-match.integration-test.ts b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/__tests__/on-opportunity-auto-match.integration-test.ts new file mode 100644 index 0000000000..762f15f245 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/__tests__/on-opportunity-auto-match.integration-test.ts @@ -0,0 +1,220 @@ +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'; + +// Helpers +async function createOpp(client: CoreApiClient, name: string) { + const r = await client.mutation({ + createOpportunity: { + __args: { data: { name } }, + id: true, + matchStatus: true, + }, + } as any); + return (r as any).createOpportunity as { id: string; matchStatus: string }; +} + +async function destroyOpp(client: CoreApiClient, id: string) { + await client + .mutation({ destroyOpportunity: { __args: { id }, id: true } } as any) + .catch(() => {}); +} + +async function getOpp(client: CoreApiClient, id: string) { + const r = await client.query({ + opportunity: { + __args: { filter: { id: { eq: id } } }, + id: true, + matchStatus: true, + partner: { id: true }, + }, + } as any); + return (r as any).opportunity as { + id: string; + matchStatus: string; + partner: { id: string } | null; + }; +} + +async function sleep(ms: number) { + return new Promise((r) => setTimeout(r, ms)); +} + +describe('on-opportunity-auto-match (success path)', () => { + let client: CoreApiClient; + const created: string[] = []; + let seededPartnerId: string | null = null; + + beforeAll(async () => { + client = new CoreApiClient(); + // Ensure at least one ACTIVE+AVAILABLE partner exists for the function to pick. + const existing = await client.query({ + partners: { + __args: { + filter: { validationStage: { eq: 'VALIDATED' }, availability: { eq: 'AVAILABLE' } }, + first: 1, + }, + edges: { node: { id: true } }, + }, + } as any); + if ((existing as any).partners.edges.length === 0) { + const r = await client.mutation({ + createPartner: { + __args: { + data: { + name: '[test] auto-match seed partner', + slug: 'test-auto-match-seed', + validationStage: 'VALIDATED', + availability: 'AVAILABLE', + }, + }, + id: true, + }, + } as any); + seededPartnerId = (r as any).createPartner.id; + } + }); + + afterAll(async () => { + if (seededPartnerId) { + await client + .mutation({ destroyPartner: { __args: { id: seededPartnerId }, id: true } } as any) + .catch(() => {}); + } + }); + + beforeEach(() => { + client = new CoreApiClient(); + }); + + afterEach(async () => { + for (const id of created) await destroyOpp(client, id); + created.length = 0; + }); + + it('defaults a new opportunity to TO_BE_MATCHED', async () => { + const opp = await createOpp(client, `[test] default status ${Date.now()}`); + created.push(opp.id); + expect(opp.matchStatus).toBe('TO_BE_MATCHED'); + }); + + it('assigns a partner and flips to MATCHED when set to AUTO_MATCH', async () => { + const opp = await createOpp(client, `[test] auto match ${Date.now()}`); + created.push(opp.id); + + await client.mutation({ + updateOpportunity: { + __args: { id: opp.id, data: { matchStatus: 'AUTO_MATCH' } }, + id: true, + }, + } as any); + + // Logic function runs async (~2s per spec). Poll up to 10s. + let final = await getOpp(client, opp.id); + for (let i = 0; i < 20 && final.matchStatus === 'AUTO_MATCH'; i++) { + await sleep(500); + final = await getOpp(client, opp.id); + } + + expect(final.matchStatus).toBe('MATCHED'); + expect(final.partner?.id).toBeDefined(); + }); +}); + +describe('on-opportunity-auto-match (failure path)', () => { + let client: CoreApiClient; + const createdOpps: string[] = []; + const flippedPartners: Array<{ id: string; prevAvailability: string }> = []; + + beforeEach(() => { + client = new CoreApiClient(); + }); + + afterEach(async () => { + // Restore partner availabilities first so other tests find a partner. + for (const p of flippedPartners) { + await client + .mutation({ + updatePartner: { + __args: { id: p.id, data: { availability: p.prevAvailability } }, + id: true, + }, + } as any) + .catch(() => {}); + } + flippedPartners.length = 0; + + for (const id of createdOpps) await destroyOpp(client, id); + createdOpps.length = 0; + }); + + it('hands off to MANUAL_MATCH with a Note when no partner is available', async () => { + // Make every AVAILABLE partner UNAVAILABLE for the duration of this test. + const all = await client.query({ + partners: { + __args: { + filter: { availability: { eq: 'AVAILABLE' } }, + first: 100, + }, + edges: { node: { id: true, availability: true } }, + }, + } as any); + + const edges = ((all as any)?.partners?.edges ?? []) as Array<{ + node: { id: string; availability: string }; + }>; + + for (const e of edges) { + flippedPartners.push({ id: e.node.id, prevAvailability: e.node.availability }); + await client.mutation({ + updatePartner: { + __args: { id: e.node.id, data: { availability: 'UNAVAILABLE' } }, + id: true, + }, + } as any); + } + + const opp = await createOpp(client, `[test] no-partner ${Date.now()}`); + createdOpps.push(opp.id); + + await client.mutation({ + updateOpportunity: { + __args: { id: opp.id, data: { matchStatus: 'AUTO_MATCH' } }, + id: true, + }, + } as any); + + let final = await getOpp(client, opp.id); + for (let i = 0; i < 20 && final.matchStatus === 'AUTO_MATCH'; i++) { + await sleep(500); + final = await getOpp(client, opp.id); + } + + expect(final.matchStatus).toBe('MANUAL_MATCH'); + expect(final.partner).toBeNull(); + + // Confirm a Note was attached. + const notes = await client.query({ + noteTargets: { + __args: { + filter: { targetOpportunityId: { eq: opp.id } }, + first: 10, + }, + edges: { + node: { + id: true, + note: { id: true, title: true, bodyV2: { markdown: true } }, + }, + }, + }, + } as any); + const noteEdges = ((notes as any)?.noteTargets?.edges ?? []) as Array<{ + node: { note: { title: string; bodyV2: { markdown: string } } }; + }>; + + const autoMatchNote = noteEdges.find((e) => + e.node.note.title.toLowerCase().includes('auto-match'), + ); + expect(autoMatchNote).toBeDefined(); + expect(autoMatchNote!.node.note.bodyV2.markdown).toContain('No partners'); + }); +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/logic-functions/list-available-partners.logic-function.ts b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/list-available-partners.logic-function.ts new file mode 100644 index 0000000000..ad0ea3f92a --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/list-available-partners.logic-function.ts @@ -0,0 +1,75 @@ +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { defineLogicFunction } from 'twenty-sdk/define'; + +export const LIST_AVAILABLE_PARTNERS_LOGIC_FUNCTION_ID = + '0f91164f-f492-41e8-9bb0-481be5a3d5b9'; + +type Partner = { + id: string; + name: string | null; + slug: string | null; + introduction: string | null; + languagesSpoken: string[] | null; + deploymentExpertise: string[] | null; + region: string[] | null; + calendarLink: { primaryLinkUrl: string | null } | null; +}; + +type ListAvailablePartnersResult = + | { ok: true; count: number; partners: Partner[] } + | { ok: false; reason: string }; + +const handler = async (): Promise => { + try { + const client = new CoreApiClient(); + + const result = await client.query({ + partners: { + __args: { + filter: { + validationStage: { eq: 'VALIDATED' }, + availability: { eq: 'AVAILABLE' }, + }, + orderBy: [{ name: 'AscNullsLast' }], + first: 100, + }, + edges: { + node: { + id: true, + name: true, + slug: true, + introduction: true, + languagesSpoken: true, + deploymentExpertise: true, + region: true, + calendarLink: { primaryLinkUrl: true }, + }, + }, + }, + } as any); + + const partners = ( + (result?.partners?.edges ?? []) as Array<{ node: Partner }> + ).map((edge) => edge.node); + + return { ok: true, count: partners.length, partners }; + } catch (err) { + return { + ok: false, + reason: err instanceof Error ? err.message : String(err), + }; + } +}; + +export default defineLogicFunction({ + universalIdentifier: LIST_AVAILABLE_PARTNERS_LOGIC_FUNCTION_ID, + name: 'list-available-partners', + description: 'Returns all partners with validationStage=VALIDATED and availability=AVAILABLE.', + timeoutSeconds: 10, + handler, + httpRouteTriggerSettings: { + path: '/partners', + httpMethod: 'GET', + isAuthRequired: false, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/logic-functions/on-opportunity-auto-match.ts b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/on-opportunity-auto-match.ts new file mode 100644 index 0000000000..5825c4b8a2 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/on-opportunity-auto-match.ts @@ -0,0 +1,105 @@ +import { DatabaseEventPayload, defineLogicFunction } from 'twenty-sdk/define'; +import { CoreApiClient } from 'twenty-client-sdk/core'; + +import { ON_OPP_AUTO_MATCH_FN_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +// Fires when an opportunity's matchStatus is set to 'AUTO_MATCH'. +// Happy path: picks the longest-idle ACTIVE+AVAILABLE partner, assigns it, flips to 'MATCHED'. +// Failure path: no partner available → flips to 'MANUAL_MATCH' and creates an audit Note. +const handler = async (payload: DatabaseEventPayload) => { + const props = payload.properties as { + after?: { id: string; matchStatus?: string; partnerId?: string | null }; + before?: { matchStatus?: string }; + updatedFields?: string[]; + }; + + if (!props.updatedFields?.includes('matchStatus')) return {}; + if (props.after?.matchStatus !== 'AUTO_MATCH') return {}; + if (props.before?.matchStatus === 'AUTO_MATCH') return {}; + if (props.after.partnerId) return {}; + + const client = new CoreApiClient(); + + const partnersResult = await client.query({ + partners: { + __args: { + filter: { + validationStage: { eq: 'VALIDATED' }, + availability: { eq: 'AVAILABLE' }, + }, + orderBy: [{ lastMatchAt: 'AscNullsFirst' }], + first: 1, + }, + edges: { node: { id: true, lastMatchAt: true } }, + }, + } as any); + + const topPartner = (partnersResult.partners as any).edges[0]?.node; + if (!topPartner) { + const noteBody = + `Auto-match attempted ${new Date().toISOString()}.\n` + + `No partners matched (status=ACTIVE, availability=AVAILABLE).\n` + + `Status moved to Manual Match — pick a partner manually or ` + + `update partner availability and retry by setting status back to Auto Match.`; + + try { + const noteResult = await client.mutation({ + createNote: { + __args: { data: { title: 'Auto-match failed', bodyV2: { markdown: noteBody } } }, + id: true, + }, + } as any); + const noteId = (noteResult as any).createNote.id as string; + + await client.mutation({ + createNoteTarget: { + __args: { data: { noteId, targetOpportunityId: props.after.id } }, + id: true, + }, + } as any); + } catch { + // Note creation is best-effort; status flip is the critical action. + } + + await client.mutation({ + updateOpportunity: { + __args: { id: props.after.id, data: { matchStatus: 'MANUAL_MATCH' } }, + id: true, + }, + } as any); + + return { matched: false, reason: 'no_partner_available' }; + } + + await client.mutation({ + updateOpportunity: { + __args: { + id: props.after.id, + data: { partnerId: topPartner.id, matchStatus: 'MATCHED' }, + }, + id: true, + }, + } as any); + + await client.mutation({ + updatePartner: { + __args: { + id: topPartner.id, + data: { lastMatchAt: new Date().toISOString() }, + }, + id: true, + }, + } as any); + + return { matched: true, partnerId: topPartner.id }; +}; + +export default defineLogicFunction({ + universalIdentifier: ON_OPP_AUTO_MATCH_FN_UNIVERSAL_IDENTIFIER, + name: 'on-opportunity-auto-match', + timeoutSeconds: 10, + handler, + databaseEventTriggerSettings: { + eventName: 'opportunity.updated', + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/logic-functions/post-install.ts b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/post-install.ts new file mode 100644 index 0000000000..87f57f0424 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/logic-functions/post-install.ts @@ -0,0 +1,48 @@ +import { InstallPayload, definePostInstallLogicFunction } from 'twenty-sdk/define'; +import { CoreApiClient } from 'twenty-client-sdk/core'; + +const handler = async (_payload: InstallPayload) => { + const client = new CoreApiClient(); + + const partnerResult = await client.mutation({ + createPartner: { + __args: { + data: { + name: 'Test Partner Alpha', + validationStage: 'VALIDATED', + availability: 'AVAILABLE', + languagesSpoken: ['ENGLISH', 'FRENCH'], + deploymentExpertise: ['CLOUD', 'SELF_HOST'], + region: 'EUROPE', + }, + }, + id: true, + }, + } as any); + + const partnerId = (partnerResult.createPartner as any).id; + + await client.mutation({ + createPerson: { + __args: { + data: { + name: { + firstName: 'Test Partner', + lastName: 'Contact', + }, + partnerId, + }, + }, + id: true, + }, + } as any); + + return { seeded: true, partnerId }; +}; + +export default definePostInstallLogicFunction({ + universalIdentifier: 'f92bad2e-5905-4757-96ee-af9869d4ca0c', + name: 'post-install', + handler, + shouldRunSynchronously: true, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/all-opportunities.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/all-opportunities.navigation-menu-item.ts new file mode 100644 index 0000000000..6728a99188 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/all-opportunities.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + ALL_OPPORTUNITIES_NAV_UNIVERSAL_IDENTIFIER, + ALL_OPPORTUNITIES_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: ALL_OPPORTUNITIES_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconTargetArrow', + position: 3, + folderUniversalIdentifier: '0b2e499a-ae74-45e0-af08-243e19fc56aa', + viewUniversalIdentifier: ALL_OPPORTUNITIES_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/matches-overview.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/matches-overview.navigation-menu-item.ts new file mode 100644 index 0000000000..c08a8f8c5f --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/matches-overview.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + MATCHES_OVERVIEW_NAV_UNIVERSAL_IDENTIFIER, + MATCHES_OVERVIEW_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: MATCHES_OVERVIEW_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconLayoutKanban', + position: 1, + folderUniversalIdentifier: '0b2e499a-ae74-45e0-af08-243e19fc56aa', + viewUniversalIdentifier: MATCHES_OVERVIEW_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-applications.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-applications.navigation-menu-item.ts new file mode 100644 index 0000000000..fc1e3dea27 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-applications.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + PARTNER_APPLICATIONS_NAV_UNIVERSAL_IDENTIFIER, + PARTNER_APPLICATIONS_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: PARTNER_APPLICATIONS_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconUserPlus', + position: 1, + folderUniversalIdentifier: '857be3b5-82c6-45f7-b546-e20a8a97be8d', + viewUniversalIdentifier: PARTNER_APPLICATIONS_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-deals.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-deals.navigation-menu-item.ts new file mode 100644 index 0000000000..1eaf616b49 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-deals.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + ALL_MATCHED_DEALS_VIEW_UNIVERSAL_IDENTIFIER, + PARTNER_DEALS_NAV_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: PARTNER_DEALS_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconHandshake', + position: 2, + folderUniversalIdentifier: '0b2e499a-ae74-45e0-af08-243e19fc56aa', + viewUniversalIdentifier: ALL_MATCHED_DEALS_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-quotes.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-quotes.navigation-menu-item.ts new file mode 100644 index 0000000000..187ead55f6 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partner-quotes.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + PARTNER_QUOTES_NAV_UNIVERSAL_IDENTIFIER, + PARTNER_QUOTES_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: PARTNER_QUOTES_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconFileDollar', + position: 3, + folderUniversalIdentifier: '857be3b5-82c6-45f7-b546-e20a8a97be8d', + viewUniversalIdentifier: PARTNER_QUOTES_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners-folder.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners-folder.navigation-menu-item.ts new file mode 100644 index 0000000000..aba7ffed0d --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners-folder.navigation-menu-item.ts @@ -0,0 +1,10 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +export default defineNavigationMenuItem({ + universalIdentifier: '857be3b5-82c6-45f7-b546-e20a8a97be8d', + type: NavigationMenuItemType.FOLDER, + name: 'Partners', + icon: 'IconBuildingStore', + color: 'purple', + position: -1, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners.navigation-menu-item.ts new file mode 100644 index 0000000000..9d30a43473 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/partners.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + ALL_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, + PARTNERS_NAV_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: PARTNERS_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconBuildingStore', + position: 0, + folderUniversalIdentifier: '857be3b5-82c6-45f7-b546-e20a8a97be8d', + viewUniversalIdentifier: ALL_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/pipeline-folder.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/pipeline-folder.navigation-menu-item.ts new file mode 100644 index 0000000000..820a293f45 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/pipeline-folder.navigation-menu-item.ts @@ -0,0 +1,9 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +export default defineNavigationMenuItem({ + universalIdentifier: '0b2e499a-ae74-45e0-af08-243e19fc56aa', + type: NavigationMenuItemType.FOLDER, + name: 'Pipeline', + icon: 'IconTargetArrow', + position: -2, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/validated-partners.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/validated-partners.navigation-menu-item.ts new file mode 100644 index 0000000000..01ebd1c20a --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/validated-partners.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + VALIDATED_PARTNERS_NAV_UNIVERSAL_IDENTIFIER, + VALIDATED_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: VALIDATED_PARTNERS_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconCircleCheck', + position: 2, + folderUniversalIdentifier: '857be3b5-82c6-45f7-b546-e20a8a97be8d', + viewUniversalIdentifier: VALIDATED_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/waiting-for-match.navigation-menu-item.ts b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/waiting-for-match.navigation-menu-item.ts new file mode 100644 index 0000000000..e4ae610ab3 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/navigation-menu-items/waiting-for-match.navigation-menu-item.ts @@ -0,0 +1,15 @@ +import { NavigationMenuItemType, defineNavigationMenuItem } from 'twenty-sdk/define'; + +import { + WAITING_FOR_MATCH_NAV_UNIVERSAL_IDENTIFIER, + WAITING_FOR_MATCH_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineNavigationMenuItem({ + universalIdentifier: WAITING_FOR_MATCH_NAV_UNIVERSAL_IDENTIFIER, + type: NavigationMenuItemType.VIEW, + icon: 'IconClockHour4', + position: 0, + folderUniversalIdentifier: '0b2e499a-ae74-45e0-af08-243e19fc56aa', + viewUniversalIdentifier: WAITING_FOR_MATCH_VIEW_UNIVERSAL_IDENTIFIER, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/objects/partner-quote.object.ts b/packages/twenty-apps/internal/twenty-partners/src/objects/partner-quote.object.ts new file mode 100644 index 0000000000..7fa789948f --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/objects/partner-quote.object.ts @@ -0,0 +1,65 @@ +import { FieldType, defineObject } from 'twenty-sdk/define'; + +import { PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export default defineObject({ + universalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + nameSingular: 'partnerQuote', + namePlural: 'partnerQuotes', + labelSingular: 'Partner Quote', + labelPlural: 'Partner Quotes', + description: 'A quote a partner submitted for a customer deal', + icon: 'IconFileDollar', + isSearchable: true, + labelIdentifierFieldMetadataUniversalIdentifier: '9e688624-83d2-4715-8b18-80492a6de2b6', + fields: [ + { + universalIdentifier: '9e688624-83d2-4715-8b18-80492a6de2b6', + type: FieldType.TEXT, + name: 'name', + label: 'Name', + icon: 'IconTag', + defaultValue: "''", + }, + { + universalIdentifier: 'a0fe09c4-c1f4-4b96-93c6-d7ec38f1166a', + type: FieldType.SELECT, + name: 'status', + label: 'Status', + icon: 'IconProgressCheck', + defaultValue: "'WIP'", + options: [ + { id: '5d41450b-8efb-41e8-81b7-b534429ec1b4', value: 'WIP', label: 'WIP', position: 0, color: 'gray' }, + { id: '6611ae9a-4253-4638-9c47-d8bf2ec54368', value: 'INTERVIEW_SCHEDULED', label: 'Interview scheduled', position: 1, color: 'blue' }, + { id: 'ae3d91e4-96ea-4687-b71f-d2d80088f28a', value: 'UNDER_CUSTOMER_PARTNER_REVIEW', label: 'Under review', position: 2, color: 'orange' }, + { id: '91fe48a3-7950-4cdd-8c52-8d9b2cc03f0b', value: 'APPROVED', label: 'Approved', position: 3, color: 'green' }, + { id: 'fa640b71-862e-4c64-80fa-37ab8b50d254', value: 'REJECTED', label: 'Rejected', position: 4, color: 'red' }, + ], + }, + { + universalIdentifier: 'b52d263e-423e-40b0-b82c-29214597c005', + type: FieldType.DATE_TIME, + name: 'approvalDate', + label: 'Approval Date', + icon: 'IconCalendarCheck', + isNullable: true, + }, + { + universalIdentifier: '2cbe67e3-24ec-421b-bab5-50f3306c2391', + type: FieldType.CURRENCY, + name: 'amount', + label: 'Amount', + icon: 'IconCoin', + isNullable: true, + }, + { + universalIdentifier: 'f303369e-288c-4a48-9920-c1de0ad9a159', + type: FieldType.FILES, + name: 'quoteFile', + label: 'Quote File', + icon: 'IconPaperclip', + isNullable: true, + universalSettings: { maxNumberOfValues: 1 }, + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/objects/partner.object.ts b/packages/twenty-apps/internal/twenty-partners/src/objects/partner.object.ts new file mode 100644 index 0000000000..aa7d098285 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/objects/partner.object.ts @@ -0,0 +1,483 @@ +import { FieldType, defineObject } from 'twenty-sdk/define'; + +import { PARTNER_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +export default defineObject({ + universalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + nameSingular: 'partner', + namePlural: 'partners', + labelSingular: 'Partner', + labelPlural: 'Partners', + description: 'A certified implementation partner', + icon: 'IconBuildingStore', + isSearchable: true, + labelIdentifierFieldMetadataUniversalIdentifier: 'a0000001-0000-4000-8000-000000000001', + fields: [ + { + universalIdentifier: 'a0000001-0000-4000-8000-000000000001', + type: FieldType.TEXT, + name: 'name', + label: 'Name', + icon: 'IconTag', + defaultValue: "''", + }, + { + universalIdentifier: 'a0000002-0000-4000-8000-000000000002', + type: FieldType.TEXT, + name: 'slug', + label: 'Slug', + icon: 'IconLink', + isNullable: true, + }, + { + universalIdentifier: '2ca9856f-f54a-4326-9ff3-668fd7da0b50', + type: FieldType.SELECT, + name: 'validationStage', + label: 'Validation Stage', + icon: 'IconProgressCheck', + defaultValue: "'APPLICATION'", + options: [ + { id: '1b4f8b0b-68ec-4c02-a7e6-fbd0cda2f3b9', value: 'APPLICATION', label: 'Application', position: 0, color: 'gray' }, + { id: '901181af-b2cb-4052-9ac8-3c84281671f8', value: 'POTENTIAL', label: 'Potential partner', position: 1, color: 'blue' }, + { id: '3ebbc425-e5e3-412d-93df-5f70fefa1798', value: 'VALIDATED', label: 'Validated partner', position: 2, color: 'green' }, + { id: '3d0ec027-0d51-4df7-932e-13c60d4b4382', value: 'FORMER', label: 'Former partner', position: 3, color: 'orange' }, + { id: '19dc4929-735a-4b64-8f57-f34f3eaa3a73', value: 'REJECTED', label: 'Rejected', position: 4, color: 'red' }, + ], + }, + { + universalIdentifier: '5af4e57e-7fa7-4c4f-b40f-37549361459a', + type: FieldType.BOOLEAN, + name: 'reviewed', + label: 'Reviewed', + icon: 'IconChecks', + isNullable: true, + }, + { + universalIdentifier: '5412e4ca-cc96-4be8-8652-b73dace7673b', + type: FieldType.RATING, + name: 'ranking', + label: 'Ranking', + icon: 'IconStar', + isNullable: true, + options: [ + { id: 'e4c784f0-7e2b-4eca-94dc-fc447266f252', value: 'RATING_1', label: '1', position: 0 }, + { id: '79d033bd-4189-4f69-a9d1-a54d7cbbc5bc', value: 'RATING_2', label: '2', position: 1 }, + { id: '1206bdcc-a804-4649-a3ce-bd001a3abc2c', value: 'RATING_3', label: '3', position: 2 }, + { id: '1c195738-d823-415e-b4db-44a6cdc09ec5', value: 'RATING_4', label: '4', position: 3 }, + { id: '92cd3a72-8d5b-4077-a369-ddfe429aa2aa', value: 'RATING_5', label: '5', position: 4 }, + ], + }, + { + universalIdentifier: 'd4fa6461-37b6-49ee-9181-dd482e74a70b', + type: FieldType.SELECT, + name: 'partnerTier', + label: 'Partner Tier', + icon: 'IconMedal', + isNullable: true, + options: [ + { id: '63806cc0-02a8-4fe9-b2ba-0efe43a33109', value: 'NEW', label: 'New', position: 0, color: 'gray' }, + { id: '1ea6f5ba-6a4a-4e64-9b56-11e9ae56c97e', value: 'INTERMEDIATE', label: 'Intermediate', position: 1, color: 'blue' }, + { id: 'b44de8b4-caea-4ca6-94cd-fb67221b5fdb', value: 'ADVANCED', label: 'Advanced', position: 2, color: 'green' }, + ], + }, + { + universalIdentifier: '500021ad-ca42-4fd3-8727-392dd26b722a', + type: FieldType.MULTI_SELECT, + name: 'partnerScope', + label: 'Partner Scope', + icon: 'IconListCheck', + isNullable: true, + options: [ + { id: '00f05e1c-0fd9-4214-a461-554b7c9e7eb5', value: 'APPS', label: 'Apps', position: 0, color: 'blue' }, + { id: 'e0f789d5-a3bc-4ecb-8bc2-5aa018468d83', value: 'DATA_MODEL', label: 'Data model', position: 1, color: 'green' }, + { id: 'c88bf189-8be4-4431-aa03-85928f8b2a52', value: 'DATA_MIGRATION', label: 'Data migration', position: 2, color: 'turquoise' }, + { id: 'a7fd9429-c26f-49ab-bf52-4d591f5ca7a0', value: 'HOSTING_ENVIRONMENT', label: 'Hosting environment', position: 3, color: 'purple' }, + { id: '9e416a39-05c6-4c80-9f36-99b5b60c26ec', value: 'WORKFLOWS', label: 'Workflows', position: 4, color: 'orange' }, + ], + }, + { + universalIdentifier: 'a451e557-a488-470a-8b35-6f9b8cfb1a10', + type: FieldType.SELECT, + name: 'typeOfTeam', + label: 'Type of Team', + icon: 'IconUsersGroup', + isNullable: true, + options: [ + { id: '0f59b781-5a81-4025-92ad-4b93b2c62df0', value: 'SOLO', label: 'Solo', position: 0, color: 'blue' }, + { id: 'db47bc44-93db-4cbf-8d0f-3057cf01d11e', value: 'AGENCY', label: 'Agency', position: 1, color: 'green' }, + ], + }, + { + universalIdentifier: '6f260cc0-a860-41e6-ad40-a2ef32ecffbe', + type: FieldType.ARRAY, + name: 'skills', + label: 'Skills', + icon: 'IconTags', + isNullable: true, + }, + { + universalIdentifier: 'a0000004-0000-4000-8000-000000000004', + type: FieldType.SELECT, + name: 'availability', + label: 'Availability', + icon: 'IconCalendarCheck', + defaultValue: "'AVAILABLE'", + options: [ + { id: '639d74c3-5d38-407b-b0e4-81f3930db451', value: 'AVAILABLE', label: 'Available', position: 0, color: 'green' }, + { id: '6a921479-559a-4446-892a-d4a1b5a3abb4', value: 'UNAVAILABLE', label: 'Unavailable', position: 1, color: 'gray' }, + ], + }, + { + universalIdentifier: 'a0000005-0000-4000-8000-000000000005', + type: FieldType.MULTI_SELECT, + name: 'deploymentExpertise', + label: 'Deployment Expertise', + icon: 'IconCloud', + isNullable: true, + options: [ + { id: 'f2f53365-d909-4a97-bb81-efab43f0a17e', value: 'CLOUD', label: 'Cloud', position: 0, color: 'sky' }, + { id: '5e47226b-4e60-413f-80ee-b8f1d9ee6ad6', value: 'SELF_HOST', label: 'Self-host', position: 1, color: 'purple' }, + ], + }, + { + universalIdentifier: 'a0000007-0000-4000-8000-000000000007', + type: FieldType.MULTI_SELECT, + name: 'languagesSpoken', + label: 'Languages Spoken', + icon: 'IconLanguage', + isNullable: true, + options: [ + { id: '3fe94a92-5f64-46f4-8697-1a44e06e939f', value: 'ENGLISH', label: 'English', position: 0, color: 'blue' }, + { id: 'fdfe8adf-b2f1-4ef9-97c1-449302932698', value: 'FRENCH', label: 'French', position: 1, color: 'red' }, + { id: '820c120a-17ba-4e9a-8dd7-9724ac41d7ca', value: 'GERMAN', label: 'German', position: 2, color: 'yellow' }, + { id: '28171507-753d-4a8e-b9c2-44c698c2a26b', value: 'CHINESE', label: 'Chinese', position: 3, color: 'orange' }, + { id: 'd9111720-26c1-47c3-85bb-a30699737cce', value: 'SPANISH', label: 'Spanish', position: 4, color: 'green' }, + { id: '7dbfcb38-4255-4fe8-91dc-ce0686191521', value: 'ARABIC', label: 'Arabic', position: 5, color: 'sky' }, + { id: 'd4e0e54b-2c57-498a-9ccc-9cfe64f09a36', value: 'BENGALI', label: 'Bengali', position: 6, color: 'purple' }, + { id: '34e765d2-5b03-4a63-a6e6-6c3c75fd8d75', value: 'CATALAN', label: 'Catalan', position: 7, color: 'pink' }, + { id: 'b042b1d3-19d6-4094-b53e-85f9727360b1', value: 'CZECH', label: 'Czech', position: 8, color: 'turquoise' }, + { id: '0a8ebe74-dcfa-44f5-abde-1af3a8dd8879', value: 'DANISH', label: 'Danish', position: 9, color: 'gray' }, + { id: '385e0db5-ab16-4a59-94fd-98921fa367d5', value: 'DUTCH', label: 'Dutch', position: 10, color: 'blue' }, + { id: 'f8ec118f-6652-4fe4-a7dc-a77c079f473e', value: 'FARSI', label: 'Farsi', position: 11, color: 'red' }, + { id: 'cd58db19-6be6-4deb-8f1b-4cd9bdbcacdf', value: 'FINNISH', label: 'Finnish', position: 12, color: 'yellow' }, + { id: 'c20be129-8a93-479c-99f1-89dad2177c0a', value: 'GREEK', label: 'Greek', position: 13, color: 'orange' }, + { id: '7faaec05-22d1-4b37-a700-9dc4733effb6', value: 'HINDI', label: 'Hindi', position: 14, color: 'green' }, + { id: '3400d7db-312f-4d54-ac19-04a2f6fed6e0', value: 'INDONESIAN', label: 'Indonesian', position: 15, color: 'sky' }, + { id: 'd1eb3870-2938-4c87-9596-3980b31df293', value: 'ITALIAN', label: 'Italian', position: 16, color: 'purple' }, + { id: '7a854dd9-6c81-4d16-8b76-79b3571638ec', value: 'JAPANESE', label: 'Japanese', position: 17, color: 'pink' }, + { id: '51be3b14-195c-45e2-815e-a6591d0946b1', value: 'KOREAN', label: 'Korean', position: 18, color: 'turquoise' }, + { id: 'c31168a0-276c-45dc-bd39-a498d39a44d8', value: 'MALAY', label: 'Malay', position: 19, color: 'gray' }, + { id: '7719d197-9e91-41d3-a66f-728cfce32c33', value: 'NORWEGIAN', label: 'Norwegian', position: 20, color: 'blue' }, + { id: '115c5e11-2462-4371-92ca-c4835649de15', value: 'POLISH', label: 'Polish', position: 21, color: 'red' }, + { id: '018e3663-3de8-4110-aceb-48c8083ebb9a', value: 'PORTUGUESE', label: 'Portuguese', position: 22, color: 'yellow' }, + { id: 'ca97987f-4f43-43d0-b7a0-490bc566b42f', value: 'PUNJABI', label: 'Punjabi', position: 23, color: 'orange' }, + { id: '05215653-4d32-49e2-9ff3-73e66e14d97d', value: 'ROMANIAN', label: 'Romanian', position: 24, color: 'green' }, + { id: 'a14e341e-a266-407f-b4c7-936cfa608500', value: 'RUSSIAN', label: 'Russian', position: 25, color: 'sky' }, + { id: '1190a9eb-bd06-4d77-ab59-c619f4e2faa3', value: 'SWAHILI', label: 'Swahili', position: 26, color: 'purple' }, + { id: '0fedffb0-c0d7-47b7-ac5f-0b166d24d670', value: 'SWEDISH', label: 'Swedish', position: 27, color: 'pink' }, + { id: '8205bc44-b2a0-4211-9fe5-1bc64efaa844', value: 'TAGALOG', label: 'Tagalog', position: 28, color: 'turquoise' }, + { id: '866b6438-c172-4c72-b69e-b1ca89342526', value: 'TAMIL', label: 'Tamil', position: 29, color: 'gray' }, + { id: 'a2c4851b-302b-4420-aff2-6d7dc614fa6c', value: 'THAI', label: 'Thai', position: 30, color: 'blue' }, + { id: '0a5672dd-ebe5-48bc-b8ab-7d2bf6a605e2', value: 'TURKISH', label: 'Turkish', position: 31, color: 'red' }, + { id: '36324fb0-5ea2-4e9f-845c-ac65b977ab20', value: 'UKRAINIAN', label: 'Ukrainian', position: 32, color: 'yellow' }, + { id: 'b1aad243-fc85-4df3-a83e-07796ae01d6c', value: 'URDU', label: 'Urdu', position: 33, color: 'orange' }, + { id: '922895f8-3a8a-45b8-a70e-0ae7b0c8ff32', value: 'VIETNAMESE', label: 'Vietnamese', position: 34, color: 'green' }, + ], + }, + { + universalIdentifier: '0a1ce916-4df5-469a-b793-30f19e45b38d', + type: FieldType.TEXT, + name: 'city', + label: 'City', + icon: 'IconMapPin', + isNullable: true, + }, + { + universalIdentifier: 'a77d7fa6-c398-47db-af0f-036a5c719f20', + type: FieldType.SELECT, + name: 'country', + label: 'Country', + icon: 'IconFlag', + isNullable: true, + options: [ + { id: '03332728-50b1-49ec-bdec-a938cb97ca74', value: 'AFGHANISTAN', label: 'Afghanistan 🇦🇫', position: 0, color: 'blue' }, + { id: 'c39c7baa-6f52-4349-bc28-97b59f2a9a3a', value: 'ALBANIA', label: 'Albania 🇦🇱', position: 1, color: 'turquoise' }, + { id: '1bce0427-d693-451a-9a6b-a50c0c502c85', value: 'ALGERIA', label: 'Algeria 🇩🇿', position: 2, color: 'green' }, + { id: '634fb580-4f12-4a5b-b43c-5787330d4b60', value: 'ANDORRA', label: 'Andorra 🇦🇩', position: 3, color: 'sky' }, + { id: '545797b9-16df-40d5-ab9b-037d3d875263', value: 'ANGOLA', label: 'Angola 🇦🇴', position: 4, color: 'purple' }, + { id: '83b58c61-8b0d-42e1-9d4f-9a530ace7899', value: 'ANTIGUA_AND_BARBUDA', label: 'Antigua & Barbuda 🇦🇬', position: 5, color: 'orange' }, + { id: '58fd4e0d-b48d-4b22-81d8-de6db6bd22ed', value: 'ARGENTINA', label: 'Argentina 🇦🇷', position: 6, color: 'yellow' }, + { id: '7091a2e3-2095-4693-bd53-366df4ba5c75', value: 'ARMENIA', label: 'Armenia 🇦🇲', position: 7, color: 'red' }, + { id: '479725e7-f185-46c6-9e8b-605fbbb392f8', value: 'AUSTRALIA', label: 'Australia 🇦🇺', position: 8, color: 'pink' }, + { id: 'b7993e1b-5f7d-47b9-a84d-41795160393a', value: 'AUSTRIA', label: 'Austria 🇦🇹', position: 9, color: 'gray' }, + { id: 'e2d324df-2baa-49a2-a016-2c7cab0d0e95', value: 'AZERBAIJAN', label: 'Azerbaijan 🇦🇿', position: 10, color: 'blue' }, + { id: '87dc4b54-c4f7-4813-a0e4-d2214e659a77', value: 'BAHAMAS', label: 'Bahamas 🇧🇸', position: 11, color: 'turquoise' }, + { id: '32149c4f-3319-42a6-a0ca-6afb42bdf3b9', value: 'BAHRAIN', label: 'Bahrain 🇧🇭', position: 12, color: 'green' }, + { id: 'c74d1f90-e17f-4e9a-9341-5c6ffda2d3ac', value: 'BANGLADESH', label: 'Bangladesh 🇧🇩', position: 13, color: 'sky' }, + { id: '61c2e8c4-06af-4daa-ac52-34f4b47e2aad', value: 'BARBADOS', label: 'Barbados 🇧🇧', position: 14, color: 'purple' }, + { id: '1c7dfa46-72e0-4ba3-8af5-3b2d1d46fd4b', value: 'BELARUS', label: 'Belarus 🇧🇾', position: 15, color: 'orange' }, + { id: '771258e5-b16f-47d4-aaed-47a4c931b72d', value: 'BELGIUM', label: 'Belgium 🇧🇪', position: 16, color: 'yellow' }, + { id: 'f3910b68-3f3f-4afb-9f90-5561376e5098', value: 'BELIZE', label: 'Belize 🇧🇿', position: 17, color: 'red' }, + { id: 'b06f1bc7-2058-44fc-b868-631559de7d11', value: 'BENIN', label: 'Benin 🇧🇯', position: 18, color: 'pink' }, + { id: 'acff20b8-b865-47de-9049-c660866f5218', value: 'BHUTAN', label: 'Bhutan 🇧🇹', position: 19, color: 'gray' }, + { id: 'bee20647-c283-40af-9733-37753e42b464', value: 'BOLIVIA', label: 'Bolivia 🇧🇴', position: 20, color: 'blue' }, + { id: '4dd91769-c713-47af-bf48-aed0251115b1', value: 'BOSNIA_AND_HERZEGOVINA', label: 'Bosnia & Herzegovina 🇧🇦', position: 21, color: 'turquoise' }, + { id: 'a6997427-007f-42b4-b6ea-892f7ce58dff', value: 'BOTSWANA', label: 'Botswana 🇧🇼', position: 22, color: 'green' }, + { id: '3ff1f170-d3f0-4ce6-9490-bfc20aadf470', value: 'BRAZIL', label: 'Brazil 🇧🇷', position: 23, color: 'sky' }, + { id: '7b2d6911-4676-433d-93f1-6eca2530d89d', value: 'BRUNEI', label: 'Brunei 🇧🇳', position: 24, color: 'purple' }, + { id: '767c72f3-f951-4b00-958d-856d2a8bda7a', value: 'BULGARIA', label: 'Bulgaria 🇧🇬', position: 25, color: 'orange' }, + { id: 'e16ce6af-86b0-4448-8008-c5efa2ce3fe9', value: 'BURKINA_FASO', label: 'Burkina Faso 🇧🇫', position: 26, color: 'yellow' }, + { id: 'dd7e7b2a-8367-482d-99d4-7877d883c2e3', value: 'BURUNDI', label: 'Burundi 🇧🇮', position: 27, color: 'red' }, + { id: 'd9d6eea9-7724-4c65-be48-e861075121f1', value: 'CAMBODIA', label: 'Cambodia 🇰🇭', position: 28, color: 'pink' }, + { id: '49178472-0bdd-4797-be6c-e0a1ac6e4147', value: 'CAMEROON', label: 'Cameroon 🇨🇲', position: 29, color: 'gray' }, + { id: '849b6361-a83b-48fb-a3e5-2ac6e9089c7f', value: 'CANADA', label: 'Canada 🇨🇦', position: 30, color: 'blue' }, + { id: 'ca22a230-01b1-4099-b7c2-29fd3b8d09de', value: 'CAPE_VERDE', label: 'Cape Verde 🇨🇻', position: 31, color: 'turquoise' }, + { id: '360bef1e-34a9-4467-9ffe-5ebeb6427711', value: 'CENTRAL_AFRICAN_REPUBLIC', label: 'Central African Republic 🇨🇫', position: 32, color: 'green' }, + { id: 'deba0ee2-3027-4646-afc6-24410bf68198', value: 'CHAD', label: 'Chad 🇹🇩', position: 33, color: 'sky' }, + { id: 'd0bf04d5-a40c-45f0-8e82-4d5905c00131', value: 'CHILE', label: 'Chile 🇨🇱', position: 34, color: 'purple' }, + { id: '60522b37-dded-4f18-a25b-05b51a8c9aa7', value: 'CHINA', label: 'China 🇨🇳', position: 35, color: 'orange' }, + { id: '3b2c58f1-4efc-4c0f-9d43-f3a5b5b577cf', value: 'COLOMBIA', label: 'Colombia 🇨🇴', position: 36, color: 'yellow' }, + { id: 'cbea73ba-8a9d-47ee-a38b-b7c3d89d3922', value: 'COMOROS', label: 'Comoros 🇰🇲', position: 37, color: 'red' }, + { id: '895ed0d4-6a00-482a-840e-44edef034d2b', value: 'CONGO', label: 'Congo 🇨🇬', position: 38, color: 'pink' }, + { id: '13db3209-398c-474c-b5f9-269ccf27adc5', value: 'DR_CONGO', label: 'DR Congo 🇨🇩', position: 39, color: 'gray' }, + { id: '150c4227-ce67-420b-bb6c-82d5a4fb9c70', value: 'COSTA_RICA', label: 'Costa Rica 🇨🇷', position: 40, color: 'blue' }, + { id: 'ad1853e2-753d-4245-b9a7-88a29281ca0a', value: 'CROATIA', label: 'Croatia 🇭🇷', position: 41, color: 'turquoise' }, + { id: 'e42cad17-f7ea-450b-8c7f-a0ac0dc31dac', value: 'CUBA', label: 'Cuba 🇨🇺', position: 42, color: 'green' }, + { id: '9035a680-5962-48c3-8d79-ee805a2c8b1c', value: 'CYPRUS', label: 'Cyprus 🇨🇾', position: 43, color: 'sky' }, + { id: 'facb14c9-40e9-47f6-bc4b-b29178761210', value: 'CZECH_REPUBLIC', label: 'Czech Republic 🇨🇿', position: 44, color: 'purple' }, + { id: '47026695-ee4b-47f2-97c1-9d1ea9854cd5', value: 'DENMARK', label: 'Denmark 🇩🇰', position: 45, color: 'orange' }, + { id: '335e3877-1f8b-4f2b-a409-ec74596dd779', value: 'DJIBOUTI', label: 'Djibouti 🇩🇯', position: 46, color: 'yellow' }, + { id: 'ee17957f-f692-495b-a664-61284fa723f2', value: 'DOMINICA', label: 'Dominica 🇩🇲', position: 47, color: 'red' }, + { id: '4114c313-27d7-4f5a-a381-38daca143642', value: 'DOMINICAN_REPUBLIC', label: 'Dominican Republic 🇩🇴', position: 48, color: 'pink' }, + { id: 'ffcfae44-e1b7-4739-87dd-0d957062646d', value: 'ECUADOR', label: 'Ecuador 🇪🇨', position: 49, color: 'gray' }, + { id: '1f4e8ee4-3be1-42cd-96d4-3e5686dee153', value: 'EGYPT', label: 'Egypt 🇪🇬', position: 50, color: 'blue' }, + { id: 'cf98813f-2a7e-4426-b97f-d3f1ac044bb8', value: 'EL_SALVADOR', label: 'El Salvador 🇸🇻', position: 51, color: 'turquoise' }, + { id: '0e787d6e-e864-4ee3-b4c7-20fa873e8649', value: 'EQUATORIAL_GUINEA', label: 'Equatorial Guinea 🇬🇶', position: 52, color: 'green' }, + { id: 'f68b6554-4ed5-4161-933f-a321b41391ea', value: 'ERITREA', label: 'Eritrea 🇪🇷', position: 53, color: 'sky' }, + { id: '7a4387dc-198c-46db-9536-7bc73de4e1b0', value: 'ESTONIA', label: 'Estonia 🇪🇪', position: 54, color: 'purple' }, + { id: '7e0fec86-e04f-499c-a814-72ac9b4cc5ce', value: 'ESWATINI', label: 'Eswatini 🇸🇿', position: 55, color: 'orange' }, + { id: 'a7768d57-5bf2-401e-a82d-ec36e3f3a419', value: 'ETHIOPIA', label: 'Ethiopia 🇪🇹', position: 56, color: 'yellow' }, + { id: '1b9e15c3-4fa5-4cd8-9bfb-8262518665fa', value: 'FIJI', label: 'Fiji 🇫🇯', position: 57, color: 'red' }, + { id: '828a6fe2-3c50-4da3-97c9-11f3b80fbb0d', value: 'FINLAND', label: 'Finland 🇫🇮', position: 58, color: 'pink' }, + { id: '03a1c597-65cf-440f-a20d-9d6bef0540c2', value: 'FRANCE', label: 'France 🇫🇷', position: 59, color: 'gray' }, + { id: 'ab2edd1f-6353-4de8-863f-4b28e774be8e', value: 'GABON', label: 'Gabon 🇬🇦', position: 60, color: 'blue' }, + { id: '12a50b82-c2f8-4d0b-b5f4-e52dfe01ba13', value: 'GAMBIA', label: 'Gambia 🇬🇲', position: 61, color: 'turquoise' }, + { id: '2adf673e-8367-4eaf-83f0-41199718f0ee', value: 'GEORGIA', label: 'Georgia 🇬🇪', position: 62, color: 'green' }, + { id: 'bd61021e-c25b-453e-b0cc-afb3942b063f', value: 'GERMANY', label: 'Germany 🇩🇪', position: 63, color: 'sky' }, + { id: '1c45b7ae-9489-4714-b21e-8c717e6599ab', value: 'GHANA', label: 'Ghana 🇬🇭', position: 64, color: 'purple' }, + { id: 'cc47d864-cd78-4cdd-a711-d679f0cbc133', value: 'GREECE', label: 'Greece 🇬🇷', position: 65, color: 'orange' }, + { id: '2a2c3ca6-611e-49a4-9639-e8f60172c1b3', value: 'GRENADA', label: 'Grenada 🇬🇩', position: 66, color: 'yellow' }, + { id: 'da2024e5-a1a0-49ab-8cf0-0d9e3f10ff9d', value: 'GUATEMALA', label: 'Guatemala 🇬🇹', position: 67, color: 'red' }, + { id: '086c9969-1911-4aa4-8d67-3abdc12b2ce7', value: 'GUINEA', label: 'Guinea 🇬🇳', position: 68, color: 'pink' }, + { id: 'a648d1d3-4d3f-4fc6-a1ea-40f98283df75', value: 'GUINEA_BISSAU', label: 'Guinea-Bissau 🇬🇼', position: 69, color: 'gray' }, + { id: 'b567e119-4dcb-4f8a-b012-febe72262d85', value: 'GUYANA', label: 'Guyana 🇬🇾', position: 70, color: 'blue' }, + { id: '26801d38-c0e6-468a-8c78-a0aed06c16fd', value: 'HAITI', label: 'Haiti 🇭🇹', position: 71, color: 'turquoise' }, + { id: '2e31c5ff-da0a-4c82-b7bc-7a8c18b54f1e', value: 'HONDURAS', label: 'Honduras 🇭🇳', position: 72, color: 'green' }, + { id: 'a78bd322-ac40-4ab3-a46f-6204e42b0712', value: 'HUNGARY', label: 'Hungary 🇭🇺', position: 73, color: 'sky' }, + { id: '0026e951-225d-4e8c-8e64-289ead339bd3', value: 'ICELAND', label: 'Iceland 🇮🇸', position: 74, color: 'purple' }, + { id: 'f5101d7d-9b81-4d2e-a9aa-e20dfab52c58', value: 'INDIA', label: 'India 🇮🇳', position: 75, color: 'orange' }, + { id: '11b30046-58f3-42e5-a3e2-5d4761675056', value: 'INDONESIA', label: 'Indonesia 🇮🇩', position: 76, color: 'yellow' }, + { id: '7345db23-db33-45cb-b8cc-e4d4a1f1b90e', value: 'IRAN', label: 'Iran 🇮🇷', position: 77, color: 'red' }, + { id: '899d0eb1-9f04-4a88-b7f3-351e998b5979', value: 'IRAQ', label: 'Iraq 🇮🇶', position: 78, color: 'pink' }, + { id: 'e45e8143-14c1-4184-84db-c11212cb8e25', value: 'IRELAND', label: 'Ireland 🇮🇪', position: 79, color: 'gray' }, + { id: 'a208dac3-455e-41ed-9db0-aa7352d420ab', value: 'ISRAEL', label: 'Israel 🇮🇱', position: 80, color: 'blue' }, + { id: '4537862d-0565-47a0-8759-ef522996881f', value: 'ITALY', label: 'Italy 🇮🇹', position: 81, color: 'turquoise' }, + { id: '988630a1-dd19-476b-a0dc-cf8904ec5f68', value: 'IVORY_COAST', label: 'Ivory Coast 🇨🇮', position: 82, color: 'green' }, + { id: '30c755e0-61f2-4590-9969-f3150c3b5aff', value: 'JAMAICA', label: 'Jamaica 🇯🇲', position: 83, color: 'sky' }, + { id: '9ca39ab6-e0fb-4bbb-80bc-cbffa48682da', value: 'JAPAN', label: 'Japan 🇯🇵', position: 84, color: 'purple' }, + { id: 'f71aefd9-1dc0-4370-8a31-2a329d8ab15d', value: 'JORDAN', label: 'Jordan 🇯🇴', position: 85, color: 'orange' }, + { id: '7f230c15-2745-4e78-ab35-8ae5bec7bcc6', value: 'KAZAKHSTAN', label: 'Kazakhstan 🇰🇿', position: 86, color: 'yellow' }, + { id: '9e745903-4ac7-432f-bfd2-d0d78e76f3e9', value: 'KENYA', label: 'Kenya 🇰🇪', position: 87, color: 'red' }, + { id: 'ee448c0f-8b3b-4666-bbbb-19e8b62ecbcc', value: 'KIRIBATI', label: 'Kiribati 🇰🇮', position: 88, color: 'pink' }, + { id: '6de78d0a-7a2b-48bb-97b5-2a86c8bab3b6', value: 'KOSOVO', label: 'Kosovo 🇽🇰', position: 89, color: 'gray' }, + { id: '48e160eb-1fdf-4456-99f7-4e97e7d16cfa', value: 'KUWAIT', label: 'Kuwait 🇰🇼', position: 90, color: 'blue' }, + { id: '7d318293-6378-4a02-af49-23d48d887a8f', value: 'KYRGYZSTAN', label: 'Kyrgyzstan 🇰🇬', position: 91, color: 'turquoise' }, + { id: 'dc540210-83bb-40c5-ab0d-585f4648df1b', value: 'LAOS', label: 'Laos 🇱🇦', position: 92, color: 'green' }, + { id: 'fe2c5828-330f-45b8-991c-180723d5bed6', value: 'LATVIA', label: 'Latvia 🇱🇻', position: 93, color: 'sky' }, + { id: 'cff1390a-7548-401b-bfa1-5e062e1e2cd3', value: 'LEBANON', label: 'Lebanon 🇱🇧', position: 94, color: 'purple' }, + { id: '2a1d40fd-a633-4bb0-890a-1009a2126ff9', value: 'LESOTHO', label: 'Lesotho 🇱🇸', position: 95, color: 'orange' }, + { id: 'dee0303d-11c9-4bf9-913b-c5fedfc93766', value: 'LIBERIA', label: 'Liberia 🇱🇷', position: 96, color: 'yellow' }, + { id: '57713732-bd4e-4888-a4e3-ad7761e76dd9', value: 'LIBYA', label: 'Libya 🇱🇾', position: 97, color: 'red' }, + { id: '5ed4e5fd-31dc-4adc-a875-b5036ef5eac6', value: 'LIECHTENSTEIN', label: 'Liechtenstein 🇱🇮', position: 98, color: 'pink' }, + { id: '8facad69-2b22-47a4-a324-75773bd7d4f8', value: 'LITHUANIA', label: 'Lithuania 🇱🇹', position: 99, color: 'gray' }, + { id: 'fb1b4543-7f22-4c44-a953-7c68e2790e27', value: 'LUXEMBOURG', label: 'Luxembourg 🇱🇺', position: 100, color: 'blue' }, + { id: '80009115-d98c-4e63-8401-285f82d94921', value: 'MADAGASCAR', label: 'Madagascar 🇲🇬', position: 101, color: 'turquoise' }, + { id: 'b32ed1f2-3d12-4255-a39a-3a5ab64b425c', value: 'MALAWI', label: 'Malawi 🇲🇼', position: 102, color: 'green' }, + { id: 'd7c744b0-23d2-4dd4-a9f9-3298cfce0d1b', value: 'MALAYSIA', label: 'Malaysia 🇲🇾', position: 103, color: 'sky' }, + { id: 'a878865c-a73f-47d7-bf52-29c1b7b947d7', value: 'MALDIVES', label: 'Maldives 🇲🇻', position: 104, color: 'purple' }, + { id: '2d5e9644-11b6-4b55-8f9a-ed33da2de6ac', value: 'MALI', label: 'Mali 🇲🇱', position: 105, color: 'orange' }, + { id: 'e2fa091a-0e78-41da-937b-42b55e501226', value: 'MALTA', label: 'Malta 🇲🇹', position: 106, color: 'yellow' }, + { id: 'e36301e0-1d79-4540-87c7-4de2bfeface6', value: 'MARSHALL_ISLANDS', label: 'Marshall Islands 🇲🇭', position: 107, color: 'red' }, + { id: '8dc782e6-3578-4d7a-a6ba-a29e48f3cc11', value: 'MAURITANIA', label: 'Mauritania 🇲🇷', position: 108, color: 'pink' }, + { id: 'edf63c87-d621-40fe-b653-a0f7764c8961', value: 'MAURITIUS', label: 'Mauritius 🇲🇺', position: 109, color: 'gray' }, + { id: '86233df1-6c71-4ffb-9298-c61c65dcc79c', value: 'MEXICO', label: 'Mexico 🇲🇽', position: 110, color: 'blue' }, + { id: 'c41c35ff-118b-4119-b12f-93be635fbae3', value: 'MICRONESIA', label: 'Micronesia 🇫🇲', position: 111, color: 'turquoise' }, + { id: '8466a06e-a34f-4dd4-b660-8e9ad2aa5998', value: 'MOLDOVA', label: 'Moldova 🇲🇩', position: 112, color: 'green' }, + { id: '948e9117-486d-40c1-847c-de6cc64b9730', value: 'MONACO', label: 'Monaco 🇲🇨', position: 113, color: 'sky' }, + { id: 'ee33ddb8-3219-4fdb-8a71-8a6f8fdf93d3', value: 'MONGOLIA', label: 'Mongolia 🇲🇳', position: 114, color: 'purple' }, + { id: 'b5c1fa55-0b1a-43d8-a871-ebd004952d0b', value: 'MONTENEGRO', label: 'Montenegro 🇲🇪', position: 115, color: 'orange' }, + { id: '9e98cb68-666e-4116-b35f-bb9711fd7546', value: 'MOROCCO', label: 'Morocco 🇲🇦', position: 116, color: 'yellow' }, + { id: '86c4b5f8-d4bc-4639-a5bf-00a84601b911', value: 'MOZAMBIQUE', label: 'Mozambique 🇲🇿', position: 117, color: 'red' }, + { id: '8b3bcfa4-1797-492e-83d7-7d939e479b1d', value: 'MYANMAR', label: 'Myanmar 🇲🇲', position: 118, color: 'pink' }, + { id: 'b8d01fef-4061-4e8c-bc38-f8226b4be6be', value: 'NAMIBIA', label: 'Namibia 🇳🇦', position: 119, color: 'gray' }, + { id: '71dd1ad1-af94-4cfb-973d-33f87b4ef0cd', value: 'NAURU', label: 'Nauru 🇳🇷', position: 120, color: 'blue' }, + { id: 'dc692171-3adc-4a73-8b45-a25cf659c546', value: 'NEPAL', label: 'Nepal 🇳🇵', position: 121, color: 'turquoise' }, + { id: '3e161b4b-be95-4a6a-910d-628ad32691e1', value: 'NETHERLANDS', label: 'Netherlands 🇳🇱', position: 122, color: 'green' }, + { id: 'b86be59e-a1ae-4df4-937f-ad97c641e0df', value: 'NEW_ZEALAND', label: 'New Zealand 🇳🇿', position: 123, color: 'sky' }, + { id: '4674abdd-0548-4317-8af5-865e4d11327d', value: 'NICARAGUA', label: 'Nicaragua 🇳🇮', position: 124, color: 'purple' }, + { id: '85ff2ce7-ddd8-4be6-b740-d79e70a3d103', value: 'NIGER', label: 'Niger 🇳🇪', position: 125, color: 'orange' }, + { id: 'a69ab8cf-5a59-4879-92da-7cd2dea6b9e6', value: 'NIGERIA', label: 'Nigeria 🇳🇬', position: 126, color: 'yellow' }, + { id: '28736977-b21f-4678-8e22-363be28a8e94', value: 'NORTH_KOREA', label: 'North Korea 🇰🇵', position: 127, color: 'red' }, + { id: '11f87414-633d-48f8-a99d-0b407c281dbd', value: 'NORTH_MACEDONIA', label: 'North Macedonia 🇲🇰', position: 128, color: 'pink' }, + { id: '9637c5aa-d405-4414-a56b-b983ed0bfa51', value: 'NORWAY', label: 'Norway 🇳🇴', position: 129, color: 'gray' }, + { id: '70f79652-7f95-4836-ab2d-4373631910ec', value: 'OMAN', label: 'Oman 🇴🇲', position: 130, color: 'blue' }, + { id: '50e4ae80-79d8-4cdf-aa0a-a2675e6e26fb', value: 'PAKISTAN', label: 'Pakistan 🇵🇰', position: 131, color: 'turquoise' }, + { id: '08d27180-4861-4937-b04e-6cbcd33f507d', value: 'PALAU', label: 'Palau 🇵🇼', position: 132, color: 'green' }, + { id: '6aa50196-ea4b-42cd-b890-8d7d56cc9731', value: 'PALESTINE', label: 'Palestine 🇵🇸', position: 133, color: 'sky' }, + { id: '5663124d-f2fc-4374-8734-f3c53f9ea4f5', value: 'PANAMA', label: 'Panama 🇵🇦', position: 134, color: 'purple' }, + { id: '8bde7cc7-fa6c-4f52-b9df-16c99928f50f', value: 'PAPUA_NEW_GUINEA', label: 'Papua New Guinea 🇵🇬', position: 135, color: 'orange' }, + { id: '3eed4b21-1009-4dd2-bdac-53b11df8400c', value: 'PARAGUAY', label: 'Paraguay 🇵🇾', position: 136, color: 'yellow' }, + { id: 'fbc734c9-63ae-4d2e-af0f-8e2abd874dda', value: 'PERU', label: 'Peru 🇵🇪', position: 137, color: 'red' }, + { id: '211555bc-8f26-4d4d-94f1-c83884c32e20', value: 'PHILIPPINES', label: 'Philippines 🇵🇭', position: 138, color: 'pink' }, + { id: '6d69e1a3-270e-4e36-9a55-40daed5b10ef', value: 'POLAND', label: 'Poland 🇵🇱', position: 139, color: 'gray' }, + { id: '23b1ae16-f00f-4844-8871-ed2b46c1cb51', value: 'PORTUGAL', label: 'Portugal 🇵🇹', position: 140, color: 'blue' }, + { id: '4dc69f6b-b0ee-48ea-95d3-517dc4ec7b91', value: 'QATAR', label: 'Qatar 🇶🇦', position: 141, color: 'turquoise' }, + { id: '8dcd82ce-98b2-45cb-a76d-f1503509035f', value: 'ROMANIA', label: 'Romania 🇷🇴', position: 142, color: 'green' }, + { id: '7e18e241-4fd6-4303-b390-0a9dea9c16bd', value: 'RUSSIA', label: 'Russia 🇷🇺', position: 143, color: 'sky' }, + { id: '966e45fb-7ed8-478e-9c26-25b7d59ae4f4', value: 'RWANDA', label: 'Rwanda 🇷🇼', position: 144, color: 'purple' }, + { id: '22ddf2d7-f1f8-46e9-8eb9-248c02652ad0', value: 'SAINT_KITTS_AND_NEVIS', label: 'Saint Kitts & Nevis 🇰🇳', position: 145, color: 'orange' }, + { id: '3312359a-b9fd-4a95-9db2-ad3e1f67f2b2', value: 'SAINT_LUCIA', label: 'Saint Lucia 🇱🇨', position: 146, color: 'yellow' }, + { id: '159c06c1-14a5-407f-af16-b84ba14f16be', value: 'SAINT_VINCENT', label: 'Saint Vincent 🇻🇨', position: 147, color: 'red' }, + { id: '0dd1cf79-89e2-4442-bd83-c65b43a3a544', value: 'SAMOA', label: 'Samoa 🇼🇸', position: 148, color: 'pink' }, + { id: 'e16851a7-97de-4e17-aeac-0cb828655406', value: 'SAN_MARINO', label: 'San Marino 🇸🇲', position: 149, color: 'gray' }, + { id: '6415861d-5fa9-46b5-a2cd-d58587c9dd03', value: 'SAO_TOME_AND_PRINCIPE', label: 'São Tomé & Príncipe 🇸🇹', position: 150, color: 'blue' }, + { id: '5831720a-3ce0-409c-9694-1b1d12394599', value: 'SAUDI_ARABIA', label: 'Saudi Arabia 🇸🇦', position: 151, color: 'turquoise' }, + { id: '89155d75-e4d0-4115-916c-8b77b9ddc5f3', value: 'SENEGAL', label: 'Senegal 🇸🇳', position: 152, color: 'green' }, + { id: 'f0c3e0e0-8106-4921-a02e-0497c1318efa', value: 'SERBIA', label: 'Serbia 🇷🇸', position: 153, color: 'sky' }, + { id: 'd8633c5d-1c65-44c5-bc71-7eb65cb988c3', value: 'SEYCHELLES', label: 'Seychelles 🇸🇨', position: 154, color: 'purple' }, + { id: '64b9fd47-a748-4add-bacf-a7dc1f1aa0c7', value: 'SIERRA_LEONE', label: 'Sierra Leone 🇸🇱', position: 155, color: 'orange' }, + { id: '5bd24cd5-a233-4d8f-930d-27f15d493c92', value: 'SINGAPORE', label: 'Singapore 🇸🇬', position: 156, color: 'yellow' }, + { id: '63c5df12-b203-4627-91b2-0526a56452d4', value: 'SLOVAKIA', label: 'Slovakia 🇸🇰', position: 157, color: 'red' }, + { id: 'b0deeef1-767a-4730-8743-588bfeb856e6', value: 'SLOVENIA', label: 'Slovenia 🇸🇮', position: 158, color: 'pink' }, + { id: '9274cd87-3400-4ccd-9192-3239b5126691', value: 'SOLOMON_ISLANDS', label: 'Solomon Islands 🇸🇧', position: 159, color: 'gray' }, + { id: '67dc7930-eaa4-4ef0-9fc4-af996eaaae09', value: 'SOMALIA', label: 'Somalia 🇸🇴', position: 160, color: 'blue' }, + { id: '19d96578-107c-4286-9504-5d59077b8290', value: 'SOUTH_AFRICA', label: 'South Africa 🇿🇦', position: 161, color: 'turquoise' }, + { id: '11cb5cb6-d67d-47ae-adf1-ecba3635fe20', value: 'SOUTH_KOREA', label: 'South Korea 🇰🇷', position: 162, color: 'green' }, + { id: '8293e893-0d7d-4002-9929-fea536a9a73c', value: 'SOUTH_SUDAN', label: 'South Sudan 🇸🇸', position: 163, color: 'sky' }, + { id: 'e0b9ba99-d891-4f6c-95df-1f92a0a7e12e', value: 'SPAIN', label: 'Spain 🇪🇸', position: 164, color: 'purple' }, + { id: '18378ce8-e480-4fd9-b90d-379d5daf7ecb', value: 'SRI_LANKA', label: 'Sri Lanka 🇱🇰', position: 165, color: 'orange' }, + { id: '10943324-5ae5-47db-bb2f-5d4bdeafd0b0', value: 'SUDAN', label: 'Sudan 🇸🇩', position: 166, color: 'yellow' }, + { id: 'bfd244e4-87c0-4dca-89b0-a1b581f1aa65', value: 'SURINAME', label: 'Suriname 🇸🇷', position: 167, color: 'red' }, + { id: '6a8f9119-c413-4ece-b432-2ce2e80580a1', value: 'SWEDEN', label: 'Sweden 🇸🇪', position: 168, color: 'pink' }, + { id: '866a8e2d-60a7-40a0-8541-35a9cfa20c09', value: 'SWITZERLAND', label: 'Switzerland 🇨🇭', position: 169, color: 'gray' }, + { id: '93758334-0ebc-4884-bfac-c0dbeec23a35', value: 'SYRIA', label: 'Syria 🇸🇾', position: 170, color: 'blue' }, + { id: 'c785e424-7a6f-4f27-91bc-aadb617525b0', value: 'TAIWAN', label: 'Taiwan 🇹🇼', position: 171, color: 'turquoise' }, + { id: '15ab8a5b-5989-4e3b-92cb-00b88cf7b7f6', value: 'TAJIKISTAN', label: 'Tajikistan 🇹🇯', position: 172, color: 'green' }, + { id: '476a55dd-8c69-4711-8e40-54cbe41d5c3a', value: 'TANZANIA', label: 'Tanzania 🇹🇿', position: 173, color: 'sky' }, + { id: 'bfcbef16-36c4-4350-a614-7ad065276104', value: 'THAILAND', label: 'Thailand 🇹🇭', position: 174, color: 'purple' }, + { id: '6872c804-9baa-498f-9dc6-b5894b64dece', value: 'TIMOR_LESTE', label: 'Timor-Leste 🇹🇱', position: 175, color: 'orange' }, + { id: 'b6429782-b6e1-4404-a5c4-8a44f3818147', value: 'TOGO', label: 'Togo 🇹🇬', position: 176, color: 'yellow' }, + { id: 'f4a7b7f9-aa58-4d23-adac-a96ed2c61ba1', value: 'TONGA', label: 'Tonga 🇹🇴', position: 177, color: 'red' }, + { id: 'a1377467-7a21-40af-861f-4b362b30fcb4', value: 'TRINIDAD_AND_TOBAGO', label: 'Trinidad & Tobago 🇹🇹', position: 178, color: 'pink' }, + { id: '7779c7d6-c7e1-4d6c-8282-31f659988c22', value: 'TUNISIA', label: 'Tunisia 🇹🇳', position: 179, color: 'gray' }, + { id: '5858f81e-629a-4b04-98e8-6441f3984044', value: 'TURKEY', label: 'Turkey 🇹🇷', position: 180, color: 'blue' }, + { id: 'cfdae353-6782-4dde-b229-d4e2c577fbed', value: 'TURKMENISTAN', label: 'Turkmenistan 🇹🇲', position: 181, color: 'turquoise' }, + { id: '755d859a-a8d4-45e0-aa6e-77afcedb29d0', value: 'TUVALU', label: 'Tuvalu 🇹🇻', position: 182, color: 'green' }, + { id: '3b325d46-b8e8-4cb9-9318-53f20baf50bd', value: 'UGANDA', label: 'Uganda 🇺🇬', position: 183, color: 'sky' }, + { id: '10f32cd9-0a6b-4829-913d-50f519dcfc3a', value: 'UKRAINE', label: 'Ukraine 🇺🇦', position: 184, color: 'purple' }, + { id: '0776427b-0dc1-49ef-b1c8-bb7dbba5a1e9', value: 'UNITED_ARAB_EMIRATES', label: 'UAE 🇦🇪', position: 185, color: 'orange' }, + { id: 'edaf21dc-60d4-4550-8b58-2f7a19eedc92', value: 'UNITED_KINGDOM', label: 'UK 🇬🇧', position: 186, color: 'yellow' }, + { id: '553004cd-aeed-4025-aa71-574efcade200', value: 'UNITED_STATES', label: 'USA 🇺🇸', position: 187, color: 'red' }, + { id: 'f925d857-5cb7-467d-bc65-e5c04ae5a238', value: 'URUGUAY', label: 'Uruguay 🇺🇾', position: 188, color: 'pink' }, + { id: '9b50ea41-2b8f-44d1-beeb-f4f4428289c4', value: 'UZBEKISTAN', label: 'Uzbekistan 🇺🇿', position: 189, color: 'gray' }, + { id: 'a7a7cbfd-6999-42e8-874e-c2bfbe6ca567', value: 'VANUATU', label: 'Vanuatu 🇻🇺', position: 190, color: 'blue' }, + { id: '7de0a670-8f04-444c-86dc-d7be00cc8b4e', value: 'VATICAN', label: 'Vatican 🇻🇦', position: 191, color: 'turquoise' }, + { id: '9acc531c-7f17-4b67-804a-035c3c873cce', value: 'VENEZUELA', label: 'Venezuela 🇻🇪', position: 192, color: 'green' }, + { id: '540b908e-f6b6-4f70-bb9c-c86dc5becbe7', value: 'VIETNAM', label: 'Vietnam 🇻🇳', position: 193, color: 'sky' }, + { id: 'a70a3610-9a9b-4fe0-9e97-10d3e60a3d92', value: 'YEMEN', label: 'Yemen 🇾🇪', position: 194, color: 'purple' }, + { id: 'fde30bd3-b2f1-4331-a255-9601259e807e', value: 'ZAMBIA', label: 'Zambia 🇿🇲', position: 195, color: 'orange' }, + { id: 'a83060bf-f55b-4efe-9e0c-b856ad5446c4', value: 'ZIMBABWE', label: 'Zimbabwe 🇿🇼', position: 196, color: 'yellow' }, + ], + }, + { + universalIdentifier: '560503de-6330-4c1d-af97-a8dee125f2ad', + type: FieldType.MULTI_SELECT, + name: 'region', + label: 'Region', + icon: 'IconWorld', + isNullable: true, + options: [ + { id: '735d7a75-c032-48b3-8480-c46e15b7e511', value: 'EUROPE', label: 'Europe', position: 0, color: 'blue' }, + { id: '78eb8d0c-841e-48dd-8425-d8546cbcfe25', value: 'US', label: 'US', position: 1, color: 'red' }, + { id: 'b0339081-52dd-4101-b7e7-83ed6ad6ca4f', value: 'LATAM', label: 'LATAM', position: 2, color: 'green' }, + { id: 'f02bd583-87b8-48d1-97db-9395056c96e2', value: 'MENA', label: 'MENA', position: 3, color: 'orange' }, + { id: '5205c25f-a300-4967-b5f3-033c0515a28a', value: 'APAC', label: 'APAC', position: 4, color: 'yellow' }, + { id: '7f55cf70-8c81-4f68-83bc-270d215f0a4e', value: 'AFRICA', label: 'Africa', position: 5, color: 'pink' }, + ], + }, + { + universalIdentifier: '243e9808-c070-4163-8603-ded12b03923c', + type: FieldType.CURRENCY, + name: 'projectBudgetMin', + label: 'Project Budget Min', + icon: 'IconCoin', + isNullable: true, + }, + { + universalIdentifier: 'ced87a97-cb2a-43cb-a6fc-4a1eff2892ba', + type: FieldType.CURRENCY, + name: 'projectBudgetTypical', + label: 'Project Budget Typical', + icon: 'IconCoins', + isNullable: true, + }, + { + universalIdentifier: '6a095709-7620-495f-b6e0-790743e412d5', + type: FieldType.CURRENCY, + name: 'hourlyRate', + label: 'Hourly Rate', + icon: 'IconCurrencyDollar', + isNullable: true, + }, + { + universalIdentifier: '640bbf33-45d7-4174-a862-dbe611ab8d1a', + type: FieldType.LINKS, + name: 'linkedin', + label: 'LinkedIn', + icon: 'IconBrandLinkedin', + isNullable: true, + }, + { + universalIdentifier: '40d730e3-2785-45c8-aa5f-cc724b1b08e0', + type: FieldType.LINKS, + name: 'profilePicture', + label: 'Profile Picture', + icon: 'IconPhoto', + isNullable: true, + }, + { + universalIdentifier: 'a0000008-0000-4000-8000-000000000008', + type: FieldType.LINKS, + name: 'calendarLink', + label: 'Calendar Link', + icon: 'IconCalendar', + isNullable: true, + }, + { + universalIdentifier: 'a0000009-0000-4000-8000-000000000009', + type: FieldType.TEXT, + name: 'introduction', + label: 'Introduction', + icon: 'IconFileText', + isNullable: true, + }, + { + universalIdentifier: 'a0000010-0000-4000-8000-000000000010', + type: FieldType.DATE_TIME, + name: 'lastMatchAt', + label: 'Last Match At', + icon: 'IconClock', + isNullable: true, + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/roles/partner.role.ts b/packages/twenty-apps/internal/twenty-partners/src/roles/partner.role.ts new file mode 100644 index 0000000000..c4c193d20f --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/roles/partner.role.ts @@ -0,0 +1,56 @@ +import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineRole } from 'twenty-sdk/define'; + +import { + PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + PARTNER_ROLE_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// PLACEHOLDER role for external partners. Twenty has no row-level filtering yet, +// so anyone assigned this role currently sees every record — do not hand out +// until RLP ships and we can scope to records owned by the assigned user. +export default defineRole({ + universalIdentifier: PARTNER_ROLE_UNIVERSAL_IDENTIFIER, + label: 'Partner', + description: + 'PLACEHOLDER. External partner self-service role. Sees ALL Partner/Opportunity records today because Twenty does not yet support row-level record filtering. When RLP ships, scope these permissions to records owned by the assigned user. DO NOT assign to real external partners until then.', + icon: 'IconBuildingStore', + canBeAssignedToUsers: true, + canUpdateAllSettings: false, + canReadAllObjectRecords: false, + canUpdateAllObjectRecords: false, + canSoftDeleteAllObjectRecords: false, + canDestroyAllObjectRecords: false, + objectPermissions: [ + { + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + canReadObjectRecords: true, + canUpdateObjectRecords: true, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: false, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: false, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: false, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/roles/twenty-partner-ops.role.ts b/packages/twenty-apps/internal/twenty-partners/src/roles/twenty-partner-ops.role.ts new file mode 100644 index 0000000000..8cc8d16121 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/roles/twenty-partner-ops.role.ts @@ -0,0 +1,55 @@ +import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, defineRole } from 'twenty-sdk/define'; + +import { + PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + TWENTY_PARTNER_OPS_ROLE_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Internal role for the Twenty partner-ops team. Scoped strictly to the CRM +// objects needed to run the matching workflow — no settings, no destroy. +export default defineRole({ + universalIdentifier: TWENTY_PARTNER_OPS_ROLE_UNIVERSAL_IDENTIFIER, + label: 'Twenty Partner Ops', + description: + 'Internal Twenty teammate role for managing partners and matched deals. Full read/write on Partner, Company, Person, Opportunity. No access to Tasks/Notes/Workflows. No settings access.', + icon: 'IconUsersGroup', + canBeAssignedToUsers: true, + canUpdateAllSettings: false, + canReadAllObjectRecords: false, + canUpdateAllObjectRecords: false, + canSoftDeleteAllObjectRecords: false, + canDestroyAllObjectRecords: false, + objectPermissions: [ + { + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + canReadObjectRecords: true, + canUpdateObjectRecords: true, + canSoftDeleteObjectRecords: true, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: true, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: true, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + { + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + canReadObjectRecords: true, + canUpdateObjectRecords: true, + canSoftDeleteObjectRecords: false, + canDestroyObjectRecords: false, + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/scripts/import-from-tft.ts b/packages/twenty-apps/internal/twenty-partners/src/scripts/import-from-tft.ts new file mode 100644 index 0000000000..f60cc9c7ac --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/scripts/import-from-tft.ts @@ -0,0 +1,420 @@ +// Import partners, opportunities and partner quotes FROM the TFT workspace INTO +// this (local) workspace. Idempotent: re-running upserts by natural key +// (partner=slug, opportunity=tftOpportunityId, quote=name). +// +// TFT (source) is read over RAW GraphQL fetch: its custom fields/filters are not +// in the SDK's generated (local) genql schema, so CoreApiClient cannot build +// queries for them. The local (target) workspace is written via CoreApiClient, +// exactly like seed.ts. Two separate credential sets, no collision: +// TFT -> TFT_API_URL / TFT_API_KEY (raw fetch) +// local-> TWENTY_PARTNERS_API_URL / TWENTY_PARTNERS_API_KEY (CoreApiClient) +// +// The local server rate-limits API calls (~100 / 60s), so existence checks are +// batched into one `in` query per object (like seed.ts) and writes are paced. +// +// DRY-RUN BY DEFAULT: reads everything, writes nothing, and reports both what it +// WOULD upsert and the distinct TFT SELECT values it saw (flagging any value not +// covered by a local field option, which would otherwise fail a real write). +// Set IMPORT_APPLY=1 to actually write to the local workspace. +// +// TFT_API_URL=https://twentyfortwenty.twenty.com TFT_API_KEY= \ +// TWENTY_PARTNERS_API_URL=http://localhost:2020 TWENTY_PARTNERS_API_KEY= \ +// [IMPORT_APPLY=1] \ +// tsx src/scripts/import-from-tft.ts + +import { config } from 'dotenv'; +config({ path: '.env.local' }); + +import { CoreApiClient } from 'twenty-client-sdk/core'; + +const requireEnv = (name: string): string => { + const value = process.env[name]; + if (!value) throw new Error(`Missing ${name} env var`); + return value; +}; + +const APPLY = process.env.IMPORT_APPLY === '1'; + +// Raw GraphQL against TFT. The generated CoreApiClient is bound to the LOCAL +// schema and cannot serialise TFT's custom fields/filters, so read TFT untyped. +const tftQuery = async (query: string): Promise => { + const url = `${requireEnv('TFT_API_URL').replace(/\/$/, '')}/graphql`; + const response = await fetch(url, { + method: 'POST', + headers: { + Authorization: `Bearer ${requireEnv('TFT_API_KEY')}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ query }), + }); + const json: any = await response.json(); + if (json.errors?.length) { + throw new Error(`TFT query failed: ${JSON.stringify(json.errors)}`); + } + return json.data; +}; + +// TFT opportunity.stage -> our matchStatus (the 4 early stages collapse to TO_BE_MATCHED) +const STAGE_TO_MATCH_STATUS: Record = { + INTRODUCED_TO_A_PARTNER: 'INTRODUCED_TO_A_PARTNER', + WORKING_WITH_A_PARTNER: 'WORKING_WITH_A_PARTNER', + WON: 'WON', + LOST: 'LOST', + RECONNECT_LATER: 'RECONNECT_LATER', + IDENTIFIED: 'TO_BE_MATCHED', + MET: 'TO_BE_MATCHED', + SOLUTIONING: 'TO_BE_MATCHED', + ADVANCED: 'TO_BE_MATCHED', +}; + +// TFT person.partnerStage -> our Partner.validationStage +const PARTNER_STAGE_TO_VALIDATION: Record = { + APPLICATION: 'APPLICATION', + POTENTIAL_PARTNER: 'POTENTIAL', + PARTNER: 'VALIDATED', + FORMER_PARTNER: 'FORMER', + REJECTED: 'REJECTED', +}; + +// Local SELECT option sets, for preflight coverage checks (a TFT value not in +// these would fail a real write). Keep in sync with src/objects + src/fields. +const LOCAL_OPTIONS: Record> = { + partnerTier: new Set(['NEW', 'INTERMEDIATE', 'ADVANCED']), + partnerScope: new Set(['APPS', 'DATA_MODEL', 'DATA_MIGRATION', 'HOSTING_ENVIRONMENT', 'WORKFLOWS']), + typeOfTeam: new Set(['SOLO', 'AGENCY']), + hostingType: new Set(['CLOUD', 'SELF_HOSTING']), + subscriptionType: new Set(['PRO', 'ORG', 'ENT']), + subscriptionFrequency: new Set(['MONTHLY', 'ANNUAL']), + quoteStatus: new Set(['WIP', 'INTERVIEW_SCHEDULED', 'UNDER_CUSTOMER_PARTNER_REVIEW', 'APPROVED', 'REJECTED']), +}; + +const slugify = (s: string): string => + s + .toLowerCase() + .trim() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); + +const edges = (result: any, key: string): any[] => + (result?.[key]?.edges ?? []).map((e: any) => e.node); + +const uniq = (values: (string | undefined | null)[]): string[] => + [...new Set(values.filter((v): v is string => !!v))]; + +async function main() { + console.log(`[import] mode: ${APPLY ? 'APPLY (writing to local)' : 'DRY-RUN (no writes)'}`); + const local = new CoreApiClient({ + url: `${requireEnv('TWENTY_PARTNERS_API_URL').replace(/\/$/, '')}/graphql`, + headers: { Authorization: `Bearer ${requireEnv('TWENTY_PARTNERS_API_KEY')}` }, + }); + + // Pace writes to stay under the local server's ~100 req/60s limit. + let writes = 0; + const pace = async () => { + if (APPLY && writes++ > 0) await new Promise((r) => setTimeout(r, 750)); + }; + + // Distinct TFT values seen, for the preflight coverage report. + const seen: Record> = { + partnerStage: new Set(), + partnerTier: new Set(), + partnerScope: new Set(), + typeOfTeam: new Set(), + oppStage: new Set(), + hostingType: new Set(), + subscriptionType: new Set(), + subscriptionFrequency: new Set(), + quoteStatus: new Set(), + typeCustom: new Set(), + }; + const note = (bucket: string, value?: string | null) => { + if (value) seen[bucket].add(value); + }; + + // --------------------------------------------------------------------- + // 1. Read all three TFT datasets (raw fetch; not rate-limited by local). + // --------------------------------------------------------------------- + const tftPeople = edges( + await tftQuery(`query { + people(first: 500, filter: { partnerStage: { in: ["APPLICATION","POTENTIAL_PARTNER","PARTNER","FORMER_PARTNER","REJECTED"] } }) { + edges { node { + id + name { firstName lastName } + emails { primaryEmail } + city jobTitle + linkedinLink { primaryLinkUrl } + partnerStage partnerTier partnerScope partnerTypeOfTeam partnerIsAvailable partnerSkills + partnerBudgetMinimum { amountMicros currencyCode } + partnerBudgetAverage { amountMicros currencyCode } + company { id name domainName { primaryLinkUrl } } + } } + } + }`), + 'people', + ); + const tftOpps = edges( + await tftQuery(`query { + opportunities(first: 500) { + edges { node { + id name numberOfSeats useCase hostingType subscriptionType subscriptionFrequence lostReason stage + amount { amountMicros currencyCode } + closeDate + company { id name domainName { primaryLinkUrl } } + partner { id } + } } + } + }`), + 'opportunities', + ); + const tftContent = edges( + await tftQuery(`query { + customerContents(first: 500) { + edges { node { id name status approvalDate typeCustom partnerPerson { id } } } + } + }`), + 'customerContents', + ); + const quotes = tftContent.filter((c: any) => Array.isArray(c.typeCustom) && c.typeCustom.includes('PARTNER_QUOTE')); + console.log(`[import] TFT: ${tftPeople.length} partner-people, ${tftOpps.length} opportunities, ${quotes.length} partner quotes`); + + const personSlug = (p: any): string => + slugify([p.name?.firstName, p.name?.lastName].filter(Boolean).join(' ').trim() || 'Unknown partner') || p.id; + + // --------------------------------------------------------------------- + // 2. Batched existence lookups against local (one `in` query per object). + // --------------------------------------------------------------------- + const partnerSlugs = uniq(tftPeople.map(personSlug)); + const partnerIdBySlug = new Map( + partnerSlugs.length + ? edges( + await local.query({ + partners: { __args: { filter: { slug: { in: partnerSlugs } }, first: 500 }, edges: { node: { id: true, slug: true } } }, + } as any), + 'partners', + ).map((n: any) => [n.slug, n.id]) + : [], + ); + + const companyNames = uniq([...tftPeople.map((p: any) => p.company?.name), ...tftOpps.map((o: any) => o.company?.name)]); + const companyIdByName = new Map( + companyNames.length + ? edges( + await local.query({ + companies: { __args: { filter: { name: { in: companyNames } }, first: 500 }, edges: { node: { id: true, name: true } } }, + } as any), + 'companies', + ).map((n: any) => [n.name, n.id]) + : [], + ); + + const oppTftIds = uniq(tftOpps.filter((o: any) => o.name).map((o: any) => o.id)); + const oppIdByTftId = new Map( + oppTftIds.length + ? edges( + await local.query({ + opportunities: { __args: { filter: { tftOpportunityId: { in: oppTftIds } }, first: 500 }, edges: { node: { id: true, tftOpportunityId: true } } }, + } as any), + 'opportunities', + ).map((n: any) => [n.tftOpportunityId, n.id]) + : [], + ); + + const quoteNames = uniq(quotes.map((q: any) => q.name || 'Partner quote')); + const quoteIdByName = new Map( + quoteNames.length + ? edges( + await local.query({ + partnerQuotes: { __args: { filter: { name: { in: quoteNames } }, first: 500 }, edges: { node: { id: true, name: true } } }, + } as any), + 'partnerQuotes', + ).map((n: any) => [n.name, n.id]) + : [], + ); + + // --------------------------------------------------------------------- + // 3. Upsert. Writes are APPLY-gated and paced; in dry-run we resolve new + // ids to synthetic placeholders so relation mapping still exercises. + // --------------------------------------------------------------------- + const upsertCompany = async (name?: string, domain?: string): Promise => { + if (!name) return undefined; + if (companyIdByName.has(name)) return companyIdByName.get(name); + let id = `dry:company:${name}`; + if (APPLY) { + await pace(); + const created: any = await local.mutation({ + createCompany: { + __args: { data: { name, ...(domain ? { domainName: { primaryLinkUrl: domain } } : {}) } }, + id: true, + }, + } as any); + id = created.createCompany.id; + } + companyIdByName.set(name, id); + return id; + }; + + const budgetCurrency = (amount: any) => + amount?.amountMicros != null ? { amountMicros: amount.amountMicros, currencyCode: amount.currencyCode ?? 'USD' } : undefined; + + // -- Partners (upsert by slug) -- + const localPartnerIdByTftPersonId = new Map(); + let partnersCreated = 0; + let partnersUpdated = 0; + for (const p of tftPeople) { + note('partnerStage', p.partnerStage); + note('partnerTier', p.partnerTier); + (Array.isArray(p.partnerScope) ? p.partnerScope : []).forEach((s: string) => note('partnerScope', s)); + note('typeOfTeam', p.partnerTypeOfTeam); + + const slug = personSlug(p); + const companyId = await upsertCompany(p.company?.name, p.company?.domainName?.primaryLinkUrl); + const data: Record = { + name: [p.name?.firstName, p.name?.lastName].filter(Boolean).join(' ').trim() || 'Unknown partner', + slug, + validationStage: PARTNER_STAGE_TO_VALIDATION[p.partnerStage] ?? 'APPLICATION', + availability: p.partnerIsAvailable ? 'AVAILABLE' : 'UNAVAILABLE', + ...(p.partnerTier ? { partnerTier: p.partnerTier } : {}), + ...(Array.isArray(p.partnerScope) && p.partnerScope.length ? { partnerScope: p.partnerScope } : {}), + ...(p.partnerTypeOfTeam ? { typeOfTeam: p.partnerTypeOfTeam } : {}), + ...(Array.isArray(p.partnerSkills) && p.partnerSkills.length ? { skills: p.partnerSkills } : {}), + ...(p.city ? { city: p.city } : {}), + ...(budgetCurrency(p.partnerBudgetMinimum) ? { projectBudgetMin: budgetCurrency(p.partnerBudgetMinimum) } : {}), + ...(budgetCurrency(p.partnerBudgetAverage) ? { projectBudgetTypical: budgetCurrency(p.partnerBudgetAverage) } : {}), + ...(p.linkedinLink?.primaryLinkUrl ? { linkedin: { primaryLinkUrl: p.linkedinLink.primaryLinkUrl } } : {}), + ...(companyId && APPLY ? { companyId } : {}), + }; + + let partnerId = partnerIdBySlug.get(slug); + if (partnerId) { + if (APPLY) { + await pace(); + await local.mutation({ updatePartner: { __args: { id: partnerId, data }, id: true } } as any); + } + partnersUpdated++; + } else { + if (APPLY) { + await pace(); + const created: any = await local.mutation({ createPartner: { __args: { data }, id: true } } as any); + partnerId = created.createPartner.id; + } else { + partnerId = `dry:partner:${slug}`; + } + partnerIdBySlug.set(slug, partnerId as string); + partnersCreated++; + } + localPartnerIdByTftPersonId.set(p.id, partnerId as string); + } + console.log(`[import] partners created=${partnersCreated} updated=${partnersUpdated}`); + + // -- Opportunities (upsert by tftOpportunityId) -- + let oppsCreated = 0; + let oppsUpdated = 0; + let oppsPartnerLinked = 0; + for (const o of tftOpps) { + if (!o.name) continue; + note('oppStage', o.stage); + note('hostingType', o.hostingType); + note('subscriptionType', o.subscriptionType); + note('subscriptionFrequency', o.subscriptionFrequence); + + const companyId = await upsertCompany(o.company?.name, o.company?.domainName?.primaryLinkUrl); + const partnerId = o.partner?.id ? localPartnerIdByTftPersonId.get(o.partner.id) : undefined; + if (partnerId) oppsPartnerLinked++; + + const data: Record = { + name: o.name, + tftOpportunityId: o.id, + matchStatus: STAGE_TO_MATCH_STATUS[o.stage] ?? 'TO_BE_MATCHED', + ...(o.numberOfSeats != null ? { numberOfSeats: o.numberOfSeats } : {}), + ...(o.useCase ? { useCase: o.useCase } : {}), + ...(o.hostingType ? { hostingType: o.hostingType } : {}), + ...(o.subscriptionType ? { subscriptionType: o.subscriptionType } : {}), + ...(o.subscriptionFrequence ? { subscriptionFrequency: o.subscriptionFrequence } : {}), + ...(o.lostReason ? { lostReason: o.lostReason } : {}), + ...(o.amount?.amountMicros != null ? { amount: { amountMicros: o.amount.amountMicros, currencyCode: o.amount.currencyCode ?? 'USD' } } : {}), + ...(o.closeDate ? { closeDate: o.closeDate } : {}), + ...(companyId && APPLY ? { companyId } : {}), + ...(partnerId && APPLY ? { partnerId } : {}), + }; + + const existingId = oppIdByTftId.get(o.id); + if (existingId) { + if (APPLY) { + await pace(); + await local.mutation({ updateOpportunity: { __args: { id: existingId, data }, id: true } } as any); + } + oppsUpdated++; + } else { + if (APPLY) { + await pace(); + await local.mutation({ createOpportunity: { __args: { data }, id: true } } as any); + } + oppsCreated++; + } + } + console.log(`[import] opportunities created=${oppsCreated} updated=${oppsUpdated} (partner-linked=${oppsPartnerLinked})`); + + // -- Partner quotes (upsert by name) -- + let quotesCreated = 0; + let quotesUpdated = 0; + tftContent.forEach((c: any) => (Array.isArray(c.typeCustom) ? c.typeCustom : []).forEach((t: string) => note('typeCustom', t))); + for (const q of quotes) { + note('quoteStatus', q.status); + const name = q.name || 'Partner quote'; + const partnerId = q.partnerPerson?.id ? localPartnerIdByTftPersonId.get(q.partnerPerson.id) : undefined; + const data: Record = { + name, + ...(q.status ? { status: q.status } : {}), + ...(q.approvalDate ? { approvalDate: q.approvalDate } : {}), + ...(partnerId && APPLY ? { partnerId } : {}), + }; + const existingId = quoteIdByName.get(name); + if (existingId) { + if (APPLY) { + await pace(); + await local.mutation({ updatePartnerQuote: { __args: { id: existingId, data }, id: true } } as any); + } + quotesUpdated++; + } else { + if (APPLY) { + await pace(); + await local.mutation({ createPartnerQuote: { __args: { data }, id: true } } as any); + } + quotesCreated++; + } + } + console.log(`[import] partner quotes created=${quotesCreated} updated=${quotesUpdated}`); + + // --------------------------------------------------------------------- + // 4. Preflight: distinct TFT values vs local option coverage. + // --------------------------------------------------------------------- + const report = (label: string, bucket: string, optionKey?: string) => { + const values = [...seen[bucket]].sort(); + const allowed = optionKey ? LOCAL_OPTIONS[optionKey] : undefined; + const uncovered = allowed ? values.filter((v) => !allowed.has(v)) : []; + console.log( + `[preflight] ${label}: ${values.join(', ') || '(none)'}` + + (uncovered.length ? ` ⚠️ NOT IN LOCAL OPTIONS: ${uncovered.join(', ')}` : ''), + ); + }; + console.log('--- preflight: distinct TFT values seen ---'); + report('partnerStage (-> validationStage map)', 'partnerStage'); + report('partnerTier', 'partnerTier', 'partnerTier'); + report('partnerScope', 'partnerScope', 'partnerScope'); + report('typeOfTeam', 'typeOfTeam', 'typeOfTeam'); + report('opp stage (-> matchStatus map)', 'oppStage'); + report('hostingType', 'hostingType', 'hostingType'); + report('subscriptionType', 'subscriptionType', 'subscriptionType'); + report('subscriptionFrequency', 'subscriptionFrequency', 'subscriptionFrequency'); + report('quote status', 'quoteStatus', 'quoteStatus'); + report('customerContent typeCustom', 'typeCustom'); + const unmappedStages = [...seen.partnerStage].filter((s) => !(s in PARTNER_STAGE_TO_VALIDATION)); + const unmappedOpps = [...seen.oppStage].filter((s) => !(s in STAGE_TO_MATCH_STATUS)); + if (unmappedStages.length) console.log(`[preflight] ⚠️ partnerStage not mapped: ${unmappedStages.join(', ')}`); + if (unmappedOpps.length) console.log(`[preflight] ⚠️ opp stage not mapped: ${unmappedOpps.join(', ')}`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/scripts/seed.ts b/packages/twenty-apps/internal/twenty-partners/src/scripts/seed.ts new file mode 100644 index 0000000000..524b984abb --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/scripts/seed.ts @@ -0,0 +1,195 @@ +// Single demo seed for the twenty-partners app. Idempotent UPSERT by natural key. +// Covers: partners across ALL validationStage values, companies + people, +// opportunities across ALL 10 matchStatus values, and partner quotes across ALL +// 5 statuses (each linked to a partner + opportunity). +// +// Run from this app directory, against a running Twenty server with the app +// installed (deploy first; do NOT run `yarn test` after — its teardown wipes the app). +// Credentials from shell env or a gitignored .env.local (TWENTY_PARTNERS_API_URL/KEY). +// +// yarn twenty dev --once +// tsx src/scripts/seed.ts + +import { config } from 'dotenv'; +config({ path: '.env.local' }); + +import { CoreApiClient } from 'twenty-client-sdk/core'; + +const requireEnv = (name: string): string => { + const value = process.env[name]; + if (!value) throw new Error(`Missing ${name} env var`); + return value; +}; + +const CAL = 'https://calendly.com/placeholder'; + +type Partner = { + slug: string; + name: string; + validationStage: string; + availability: string; + introduction: string; + calendarLink: string; + deploymentExpertise: string[]; + region: string[]; + languagesSpoken: string[]; + partnerTier: string; + partnerScope: string[]; + typeOfTeam: string; + country: string; +}; + +const PARTNERS: Partner[] = [ + { slug: 'nine-dots-ventures', name: 'Nine Dots Ventures', validationStage: 'VALIDATED', availability: 'AVAILABLE', introduction: 'Boutique CRM implementer for real-estate workflows and WhatsApp automation.', calendarLink: CAL, deploymentExpertise: ['CLOUD', 'SELF_HOST'], region: ['EUROPE', 'MENA'], languagesSpoken: ['ENGLISH', 'FRENCH', 'ARABIC'], partnerTier: 'ADVANCED', partnerScope: ['DATA_MODEL', 'WORKFLOWS', 'APPS'], typeOfTeam: 'AGENCY', country: 'FRANCE' }, + { slug: 'elevate-consulting', name: 'Elevate Consulting', validationStage: 'VALIDATED', availability: 'AVAILABLE', introduction: 'Revenue-operations partner for B2B SaaS teams scaling seed to Series C.', calendarLink: CAL, deploymentExpertise: ['CLOUD'], region: ['US', 'LATAM'], languagesSpoken: ['ENGLISH', 'SPANISH'], partnerTier: 'INTERMEDIATE', partnerScope: ['DATA_MIGRATION', 'DATA_MODEL'], typeOfTeam: 'AGENCY', country: 'UNITED_STATES' }, + { slug: 'w3villa-technologies', name: 'W3Villa Technologies', validationStage: 'VALIDATED', availability: 'AVAILABLE', introduction: 'Engineering-heavy partner running large self-hosted Twenty deployments.', calendarLink: CAL, deploymentExpertise: ['CLOUD', 'SELF_HOST'], region: ['APAC', 'MENA'], languagesSpoken: ['ENGLISH', 'HINDI'], partnerTier: 'ADVANCED', partnerScope: ['HOSTING_ENVIRONMENT', 'APPS', 'WORKFLOWS'], typeOfTeam: 'AGENCY', country: 'INDIA' }, + { slug: 'act-education', name: 'Act Education', validationStage: 'VALIDATED', availability: 'UNAVAILABLE', introduction: 'CRM partner for European education providers; compliance-first self-hosting.', calendarLink: CAL, deploymentExpertise: ['SELF_HOST'], region: ['EUROPE'], languagesSpoken: ['ENGLISH', 'GERMAN'], partnerTier: 'NEW', partnerScope: ['HOSTING_ENVIRONMENT', 'DATA_MODEL'], typeOfTeam: 'SOLO', country: 'GERMANY' }, + { slug: 'netzero-systems', name: 'NetZero Systems', validationStage: 'VALIDATED', availability: 'AVAILABLE', introduction: 'LATAM go-to-market partner for climate-tech and renewable-energy companies.', calendarLink: CAL, deploymentExpertise: ['CLOUD'], region: ['LATAM', 'US'], languagesSpoken: ['ENGLISH', 'SPANISH', 'PORTUGUESE'], partnerTier: 'INTERMEDIATE', partnerScope: ['DATA_MODEL'], typeOfTeam: 'AGENCY', country: 'BRAZIL' }, + { slug: 'meridian-craft', name: 'Meridian Craft', validationStage: 'VALIDATED', availability: 'AVAILABLE', introduction: 'APAC implementation studio for fintech and logistics; English + Chinese.', calendarLink: CAL, deploymentExpertise: ['CLOUD', 'SELF_HOST'], region: ['APAC', 'AFRICA'], languagesSpoken: ['ENGLISH', 'CHINESE', 'MALAY'], partnerTier: 'ADVANCED', partnerScope: ['APPS', 'WORKFLOWS'], typeOfTeam: 'AGENCY', country: 'SINGAPORE' }, + { slug: 'applicant-studio', name: 'Applicant Studio', validationStage: 'APPLICATION', availability: 'UNAVAILABLE', introduction: 'New applicant; awaiting first review.', calendarLink: CAL, deploymentExpertise: ['CLOUD'], region: ['EUROPE'], languagesSpoken: ['ENGLISH', 'FRENCH'], partnerTier: 'NEW', partnerScope: ['DATA_MODEL'], typeOfTeam: 'SOLO', country: 'FRANCE' }, + { slug: 'rising-crm', name: 'Rising CRM', validationStage: 'POTENTIAL', availability: 'AVAILABLE', introduction: 'Promising applicant in evaluation.', calendarLink: CAL, deploymentExpertise: ['CLOUD', 'SELF_HOST'], region: ['US'], languagesSpoken: ['ENGLISH'], partnerTier: 'NEW', partnerScope: ['WORKFLOWS', 'APPS'], typeOfTeam: 'AGENCY', country: 'UNITED_STATES' }, + { slug: 'legacy-partners', name: 'Legacy Partners', validationStage: 'FORMER', availability: 'UNAVAILABLE', introduction: 'Former partner; no longer active in the program.', calendarLink: CAL, deploymentExpertise: ['SELF_HOST'], region: ['EUROPE'], languagesSpoken: ['ENGLISH', 'GERMAN'], partnerTier: 'INTERMEDIATE', partnerScope: ['HOSTING_ENVIRONMENT'], typeOfTeam: 'AGENCY', country: 'UNITED_KINGDOM' }, + { slug: 'declined-co', name: 'Declined Co', validationStage: 'REJECTED', availability: 'UNAVAILABLE', introduction: 'Application rejected after review.', calendarLink: CAL, deploymentExpertise: ['CLOUD'], region: ['MENA'], languagesSpoken: ['ENGLISH', 'ARABIC'], partnerTier: 'NEW', partnerScope: ['APPS'], typeOfTeam: 'SOLO', country: 'UNITED_ARAB_EMIRATES' }, +]; + +const COMPANIES = [ + { name: 'Acme Real Estate', domain: 'https://acmerealestate.example' }, + { name: 'Helix Bio', domain: 'https://helixbio.example' }, + { name: 'Sunrise Logistics', domain: 'https://sunriselogistics.example' }, +]; + +const PERSONS = [ + { firstName: 'Camille', lastName: 'Durand', companyName: 'Acme Real Estate', email: 'camille@acmerealestate.example', city: 'Paris' }, + { firstName: 'Maya', lastName: 'Patel', companyName: 'Helix Bio', email: 'maya@helixbio.example', city: 'Boston' }, + { firstName: 'Wei', lastName: 'Chen', companyName: 'Sunrise Logistics', email: 'wei@sunriselogistics.example', city: 'Singapore' }, +]; + +type Opp = { + name: string; + companyName: string; + matchStatus: string; + partnerSlug?: string; + numberOfSeats?: number; + hostingType?: string; + subscriptionType?: string; + subscriptionFrequency?: string; +}; + +// One+ opportunity for every matchStatus value (all 10 covered). +const OPPORTUNITIES: Opp[] = [ + { name: 'Acme RE — Q3 renewal', companyName: 'Acme Real Estate', matchStatus: 'TO_BE_MATCHED', numberOfSeats: 20, hostingType: 'CLOUD', subscriptionType: 'PRO', subscriptionFrequency: 'ANNUAL' }, + { name: 'Helix Bio — investor reporting', companyName: 'Helix Bio', matchStatus: 'MANUAL_MATCH', numberOfSeats: 12, hostingType: 'CLOUD', subscriptionType: 'ORG', subscriptionFrequency: 'MONTHLY' }, + { name: 'Helix Bio — pipeline review', companyName: 'Helix Bio', matchStatus: 'AUTO_MATCH', numberOfSeats: 8 }, + { name: 'Acme RE — CRM rollout', companyName: 'Acme Real Estate', matchStatus: 'MATCHED', partnerSlug: 'elevate-consulting', numberOfSeats: 30, hostingType: 'CLOUD', subscriptionType: 'ENT', subscriptionFrequency: 'ANNUAL' }, + { name: 'Sunrise — APAC fleet CRM', companyName: 'Sunrise Logistics', matchStatus: 'INTRODUCED_TO_A_PARTNER', partnerSlug: 'nine-dots-ventures', numberOfSeats: 50, hostingType: 'SELF_HOSTING', subscriptionType: 'ENT', subscriptionFrequency: 'ANNUAL' }, + { name: 'Helix Bio — clinical trials CRM', companyName: 'Helix Bio', matchStatus: 'WORKING_WITH_A_PARTNER', partnerSlug: 'netzero-systems', numberOfSeats: 25, hostingType: 'CLOUD', subscriptionType: 'ORG', subscriptionFrequency: 'MONTHLY' }, + { name: 'Helix Bio — self-host evaluation', companyName: 'Helix Bio', matchStatus: 'IMPLEMENTING', partnerSlug: 'meridian-craft', numberOfSeats: 40, hostingType: 'SELF_HOSTING', subscriptionType: 'ENT', subscriptionFrequency: 'ANNUAL' }, + { name: 'Sunrise — LATAM expansion', companyName: 'Sunrise Logistics', matchStatus: 'WON', partnerSlug: 'nine-dots-ventures', numberOfSeats: 60, hostingType: 'CLOUD', subscriptionType: 'ENT', subscriptionFrequency: 'ANNUAL' }, + { name: 'Acme RE — annual review', companyName: 'Acme Real Estate', matchStatus: 'RECONNECT_LATER', partnerSlug: 'w3villa-technologies', numberOfSeats: 15 }, + { name: 'Sunrise — vendor onboarding', companyName: 'Sunrise Logistics', matchStatus: 'LOST', numberOfSeats: 10, hostingType: 'CLOUD', subscriptionType: 'PRO', subscriptionFrequency: 'MONTHLY' }, +]; + +type Quote = { name: string; status: string; partnerSlug: string; oppName: string }; +const QUOTES: Quote[] = [ + { name: 'Sunrise APAC fleet — Nine Dots quote', status: 'WIP', partnerSlug: 'nine-dots-ventures', oppName: 'Sunrise — APAC fleet CRM' }, + { name: 'Helix clinical — NetZero quote', status: 'INTERVIEW_SCHEDULED', partnerSlug: 'netzero-systems', oppName: 'Helix Bio — clinical trials CRM' }, + { name: 'Acme rollout — Elevate quote', status: 'UNDER_CUSTOMER_PARTNER_REVIEW', partnerSlug: 'elevate-consulting', oppName: 'Acme RE — CRM rollout' }, + { name: 'Sunrise LATAM — Nine Dots quote', status: 'APPROVED', partnerSlug: 'nine-dots-ventures', oppName: 'Sunrise — LATAM expansion' }, + { name: 'Helix self-host — Meridian quote', status: 'REJECTED', partnerSlug: 'meridian-craft', oppName: 'Helix Bio — self-host evaluation' }, +]; + +const nodes = (r: any, key: string): any[] => (r?.[key]?.edges ?? []).map((e: any) => e.node); + +async function main() { + const client = new CoreApiClient({ + url: `${requireEnv('TWENTY_PARTNERS_API_URL').replace(/\/$/, '')}/graphql`, + headers: { Authorization: `Bearer ${requireEnv('TWENTY_PARTNERS_API_KEY')}` }, + }); + + // -- Partners (upsert by slug) -- + const existingPartners = nodes( + await client.query({ partners: { __args: { filter: { slug: { in: PARTNERS.map((p) => p.slug) } }, first: 100 }, edges: { node: { id: true, slug: true } } } } as any), + 'partners', + ); + const partnerIdBySlug = new Map(existingPartners.map((n: any) => [n.slug, n.id])); + for (const p of PARTNERS) { + const data = { + name: p.name, slug: p.slug, validationStage: p.validationStage, availability: p.availability, + introduction: p.introduction, calendarLink: { primaryLinkUrl: p.calendarLink }, + deploymentExpertise: p.deploymentExpertise, region: p.region, languagesSpoken: p.languagesSpoken, + partnerTier: p.partnerTier, partnerScope: p.partnerScope, typeOfTeam: p.typeOfTeam, + country: p.country, + }; + const id = partnerIdBySlug.get(p.slug); + if (id) { + await client.mutation({ updatePartner: { __args: { id, data }, id: true } } as any); + } else { + const r: any = await client.mutation({ createPartner: { __args: { data }, id: true } } as any); + partnerIdBySlug.set(p.slug, r.createPartner.id); + } + } + console.log(`[seed] partners: ${partnerIdBySlug.size}`); + + // -- Companies (upsert by name) -- + const companyIdByName = new Map(); + for (const c of COMPANIES) { + const existing = nodes(await client.query({ companies: { __args: { filter: { name: { eq: c.name } }, first: 1 }, edges: { node: { id: true } } } } as any), 'companies'); + let id = existing[0]?.id; + if (!id) { + const r: any = await client.mutation({ createCompany: { __args: { data: { name: c.name, domainName: { primaryLinkUrl: c.domain } } }, id: true } } as any); + id = r.createCompany.id; + } + companyIdByName.set(c.name, id); + } + + // -- People (upsert by firstName+lastName) -- + for (const person of PERSONS) { + const existing = nodes(await client.query({ people: { __args: { filter: { name: { firstName: { eq: person.firstName } } }, first: 10 }, edges: { node: { id: true, name: { firstName: true, lastName: true } } } } } as any), 'people'); + const match = existing.find((n: any) => n.name?.firstName === person.firstName && n.name?.lastName === person.lastName); + if (!match) { + await client.mutation({ createPerson: { __args: { data: { name: { firstName: person.firstName, lastName: person.lastName }, emails: { primaryEmail: person.email }, city: person.city, companyId: companyIdByName.get(person.companyName) } }, id: true } } as any); + } + } + + // -- Opportunities (upsert by name) -- + const oppIdByName = new Map(); + for (const o of OPPORTUNITIES) { + const data: Record = { + name: o.name, matchStatus: o.matchStatus, companyId: companyIdByName.get(o.companyName), + ...(o.partnerSlug ? { partnerId: partnerIdBySlug.get(o.partnerSlug) } : {}), + ...(o.numberOfSeats != null ? { numberOfSeats: o.numberOfSeats } : {}), + ...(o.hostingType ? { hostingType: o.hostingType } : {}), + ...(o.subscriptionType ? { subscriptionType: o.subscriptionType } : {}), + ...(o.subscriptionFrequency ? { subscriptionFrequency: o.subscriptionFrequency } : {}), + }; + const existing = nodes(await client.query({ opportunities: { __args: { filter: { name: { eq: o.name } }, first: 1 }, edges: { node: { id: true } } } } as any), 'opportunities'); + let id = existing[0]?.id; + if (id) { + await client.mutation({ updateOpportunity: { __args: { id, data }, id: true } } as any); + } else { + const r: any = await client.mutation({ createOpportunity: { __args: { data }, id: true } } as any); + id = r.createOpportunity.id; + } + oppIdByName.set(o.name, id); + } + console.log(`[seed] opportunities: ${oppIdByName.size}`); + + // -- Partner quotes (upsert by name) -- + let quoteCount = 0; + for (const q of QUOTES) { + const data = { name: q.name, status: q.status, partnerId: partnerIdBySlug.get(q.partnerSlug), opportunityId: oppIdByName.get(q.oppName) }; + const existing = nodes(await client.query({ partnerQuotes: { __args: { filter: { name: { eq: q.name } }, first: 1 }, edges: { node: { id: true } } } } as any), 'partnerQuotes'); + if (existing[0]?.id) { + await client.mutation({ updatePartnerQuote: { __args: { id: existing[0].id, data }, id: true } } as any); + } else { + await client.mutation({ createPartnerQuote: { __args: { data }, id: true } } as any); + } + quoteCount++; + } + console.log(`[seed] partner quotes: ${quoteCount}`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/all-matched-deals.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/all-matched-deals.view.ts new file mode 100644 index 0000000000..188ee478a6 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/all-matched-deals.view.ts @@ -0,0 +1,36 @@ +import { + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, + ViewFilterOperand, + ViewType, + defineView, +} from 'twenty-sdk/define'; + +import { + ALL_MATCHED_DEALS_VIEW_UNIVERSAL_IDENTIFIER, + MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Opportunities where a partner is engaged (MATCHED or later). Distinct from +// Matches overview, which also includes AUTO_MATCH (in-flight, no partner yet). +export default defineView({ + universalIdentifier: ALL_MATCHED_DEALS_VIEW_UNIVERSAL_IDENTIFIER, + name: 'All matched deals', + objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: '76f6aea5-0e0b-4787-84f0-430d0799e913', fieldMetadataUniversalIdentifier: '20202020-8609-4f65-a2d9-44009eb422b5', position: 0, isVisible: true }, + { universalIdentifier: 'd9862d49-eff8-4103-9f48-a193cf8e1de2', fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, position: 1, isVisible: true }, + { universalIdentifier: '91c42a01-4ec8-4527-b9ac-9bdeb58e7243', fieldMetadataUniversalIdentifier: 'd9eeacaa-2f9e-44cc-b5f6-5e1526256d49', position: 2, isVisible: true }, + { universalIdentifier: 'c9689260-86f5-4e19-a86c-7afc95d4d6fe', fieldMetadataUniversalIdentifier: 'cc6b8a59-f860-493f-8b9a-f138c078fbf1', position: 3, isVisible: true }, + { universalIdentifier: 'd51c2737-26f8-4f27-b078-7bb0cf58c662', fieldMetadataUniversalIdentifier: 'fcf39b0c-0547-415e-806d-b238131ad7cc', position: 4, isVisible: true }, + ], + filters: [ + { + universalIdentifier: '71de9b3a-e59b-4baf-99e6-84fe01e037ee', + fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + // See filter-syntax note in Task 8.1. + operand: ViewFilterOperand.IS, + value: ['MATCHED', 'INTRODUCED_TO_A_PARTNER', 'WORKING_WITH_A_PARTNER', 'IMPLEMENTING', 'WON', 'RECONNECT_LATER', 'LOST'], + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/all-opportunities.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/all-opportunities.view.ts new file mode 100644 index 0000000000..ff8adff4c0 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/all-opportunities.view.ts @@ -0,0 +1,31 @@ +import { + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, + ViewType, + defineView, +} from 'twenty-sdk/define'; + +import { + ALL_OPPORTUNITIES_VIEW_UNIVERSAL_IDENTIFIER, + MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Default Opportunities view replacement. Surfaces matchStatus + partner alongside +// the standard Opportunity columns. partnerEligible column was dropped as part of +// the match-status redesign. +export default defineView({ + universalIdentifier: ALL_OPPORTUNITIES_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Opportunities', + icon: 'IconTargetArrow', + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: '62844317-546c-4b65-a292-917bf0b5bfce', fieldMetadataUniversalIdentifier: '20202020-8609-4f65-a2d9-44009eb422b5', position: 0, isVisible: true }, + { universalIdentifier: '295a5b86-0b37-475a-8645-26f7e7a3dd0a', fieldMetadataUniversalIdentifier: '20202020-cbac-457e-b565-adece5fc815f', position: 1, isVisible: true }, + { universalIdentifier: 'ce684df4-4456-427c-b33b-38a34368e380', fieldMetadataUniversalIdentifier: '20202020-6f76-477d-8551-28cd65b2b4b9', position: 2, isVisible: true }, + { universalIdentifier: '9f72d1ce-7c39-418c-95cb-480d1b176821', fieldMetadataUniversalIdentifier: 'd9eeacaa-2f9e-44cc-b5f6-5e1526256d49', position: 3, isVisible: true }, + { universalIdentifier: '5db9ee26-8688-4a5c-9fe8-f76b41d8e80b', fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, position: 4, isVisible: true }, + { universalIdentifier: '3727d213-e3f5-43c7-ab05-b0fb2f211273', fieldMetadataUniversalIdentifier: '20202020-527e-44d6-b1ac-c4158d307b97', position: 5, isVisible: true }, + { universalIdentifier: 'c9ad9056-fd3a-448c-b4dc-e95e0c5d22e9', fieldMetadataUniversalIdentifier: '20202020-a63e-4a62-8e63-42a51828f831', position: 6, isVisible: true }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/all-partners.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/all-partners.view.ts new file mode 100644 index 0000000000..46ef85c3ca --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/all-partners.view.ts @@ -0,0 +1,22 @@ +import { ViewType, defineView } from 'twenty-sdk/define'; + +import { + ALL_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, + PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +export default defineView({ + universalIdentifier: ALL_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Partners', + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: '21afcc69-09c5-42eb-a609-26c062de3bd3', fieldMetadataUniversalIdentifier: 'a0000001-0000-4000-8000-000000000001', position: 0, isVisible: true }, + { universalIdentifier: '529912f0-38fb-4821-92d3-8a0a68b9f340', fieldMetadataUniversalIdentifier: '2ca9856f-f54a-4326-9ff3-668fd7da0b50', position: 1, isVisible: true }, + { universalIdentifier: '68c6b96d-8c3d-4a3e-b4cd-3751d035b085', fieldMetadataUniversalIdentifier: 'a0000004-0000-4000-8000-000000000004', position: 2, isVisible: true }, + { universalIdentifier: '8862e4a5-525a-4a0c-8381-93ff0d01ccf0', fieldMetadataUniversalIdentifier: 'a0000007-0000-4000-8000-000000000007', position: 3, isVisible: true }, + { universalIdentifier: '4ebe0b9d-0c2d-4416-b187-150b02473a01', fieldMetadataUniversalIdentifier: 'a0000010-0000-4000-8000-000000000010', position: 4, isVisible: true }, + { universalIdentifier: '52408b5f-5e13-4e3c-af2d-ce50033ec126', fieldMetadataUniversalIdentifier: '560503de-6330-4c1d-af97-a8dee125f2ad', position: 5, isVisible: true }, + { universalIdentifier: '02cc471b-e9ba-4643-b403-40299d6bbbdd', fieldMetadataUniversalIdentifier: 'a0000005-0000-4000-8000-000000000005', position: 6, isVisible: true }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/matches-overview.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/matches-overview.view.ts new file mode 100644 index 0000000000..f39b3e9de8 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/matches-overview.view.ts @@ -0,0 +1,29 @@ +import { + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, + ViewType, + defineView, +} from 'twenty-sdk/define'; + +import { + MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + MATCHES_OVERVIEW_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Full matching funnel: a Kanban grouped by matchStatus, no filter (every +// opportunity appears in its matchStatus column). +export default defineView({ + universalIdentifier: MATCHES_OVERVIEW_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Matches overview', + icon: 'IconLayoutKanban', + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: ViewType.KANBAN, + mainGroupByFieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + fields: [ + { universalIdentifier: '7a6403c1-7ab9-4c3a-b833-3c028d43140e', fieldMetadataUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.fields.name.universalIdentifier, position: 0, isVisible: true }, + { universalIdentifier: '2e718b4b-fde8-4839-9cdf-deb09db0e6b6', fieldMetadataUniversalIdentifier: 'd9eeacaa-2f9e-44cc-b5f6-5e1526256d49', position: 1, isVisible: true }, + { universalIdentifier: '5ae8805c-3d71-4ccc-a2be-38368f32e3e1', fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, position: 2, isVisible: true }, + { universalIdentifier: 'cb4e5d2b-7003-4f30-874c-acda310b250c', fieldMetadataUniversalIdentifier: 'fcf39b0c-0547-415e-806d-b238131ad7cc', position: 3, isVisible: true }, + { universalIdentifier: '0fc87e70-7aa1-4c85-9152-d0edff8ae8a4', fieldMetadataUniversalIdentifier: 'cc6b8a59-f860-493f-8b9a-f138c078fbf1', position: 4, isVisible: true }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/partner-applications.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/partner-applications.view.ts new file mode 100644 index 0000000000..21ac328048 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/partner-applications.view.ts @@ -0,0 +1,29 @@ +import { ViewFilterOperand, ViewType, defineView } from 'twenty-sdk/define'; + +import { + PARTNER_APPLICATIONS_VIEW_UNIVERSAL_IDENTIFIER, + PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Partners still in the application stage (not yet validated). +export default defineView({ + universalIdentifier: PARTNER_APPLICATIONS_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Partner applications', + icon: 'IconUserPlus', + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: 'b4f505d7-3849-4a74-a27f-1c91733702b5', fieldMetadataUniversalIdentifier: 'a0000001-0000-4000-8000-000000000001', position: 0, isVisible: true }, + { universalIdentifier: '8a39e510-e533-4cd7-9b65-5e16b5f773d0', fieldMetadataUniversalIdentifier: '2ca9856f-f54a-4326-9ff3-668fd7da0b50', position: 1, isVisible: true }, + { universalIdentifier: 'b92d7fd4-4a24-4333-89fe-5d726634d428', fieldMetadataUniversalIdentifier: 'd4fa6461-37b6-49ee-9181-dd482e74a70b', position: 2, isVisible: true }, + { universalIdentifier: '2c34a120-b0f8-421b-9546-6483f1202d9f', fieldMetadataUniversalIdentifier: 'a77d7fa6-c398-47db-af0f-036a5c719f20', position: 3, isVisible: true }, + ], + filters: [ + { + universalIdentifier: '210deb57-cfca-4086-b9da-ca346fbd3126', + fieldMetadataUniversalIdentifier: '2ca9856f-f54a-4326-9ff3-668fd7da0b50', + operand: ViewFilterOperand.IS, + value: ['APPLICATION'], + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/partner-quotes.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/partner-quotes.view.ts new file mode 100644 index 0000000000..268946b93b --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/partner-quotes.view.ts @@ -0,0 +1,21 @@ +import { ViewType, defineView } from 'twenty-sdk/define'; + +import { + PARTNER_QUOTES_VIEW_UNIVERSAL_IDENTIFIER, + PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Index view for partner quotes. +export default defineView({ + universalIdentifier: PARTNER_QUOTES_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Partner quotes', + icon: 'IconFileDollar', + objectUniversalIdentifier: PARTNER_QUOTE_OBJECT_UNIVERSAL_IDENTIFIER, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: 'ad7b3702-b552-4355-afec-1e1e96d9f3df', fieldMetadataUniversalIdentifier: '9e688624-83d2-4715-8b18-80492a6de2b6', position: 0, isVisible: true }, + { universalIdentifier: '426e0c2d-449d-4a06-860b-0cfe0ed501e6', fieldMetadataUniversalIdentifier: 'a0fe09c4-c1f4-4b96-93c6-d7ec38f1166a', position: 1, isVisible: true }, + { universalIdentifier: '62bb1536-539c-4fb0-95bf-440c5c5da89f', fieldMetadataUniversalIdentifier: '2cbe67e3-24ec-421b-bab5-50f3306c2391', position: 2, isVisible: true }, + { universalIdentifier: 'fbd1f953-1dd2-4d0f-a239-148a0688fbff', fieldMetadataUniversalIdentifier: 'b52d263e-423e-40b0-b82c-29214597c005', position: 3, isVisible: true }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/validated-partners.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/validated-partners.view.ts new file mode 100644 index 0000000000..4fcd863a1e --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/validated-partners.view.ts @@ -0,0 +1,30 @@ +import { ViewFilterOperand, ViewType, defineView } from 'twenty-sdk/define'; + +import { + PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + VALIDATED_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Validated partners — serves both partner intros and the public website list. +export default defineView({ + universalIdentifier: VALIDATED_PARTNERS_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Validated partners', + icon: 'IconCircleCheck', + objectUniversalIdentifier: PARTNER_OBJECT_UNIVERSAL_IDENTIFIER, + type: ViewType.TABLE, + fields: [ + { universalIdentifier: '9463bf58-69d5-4309-bc6e-4835df346246', fieldMetadataUniversalIdentifier: 'a0000001-0000-4000-8000-000000000001', position: 0, isVisible: true }, + { universalIdentifier: 'c8fd88c5-ffa9-4944-b5b9-deec3acd3dff', fieldMetadataUniversalIdentifier: 'd4fa6461-37b6-49ee-9181-dd482e74a70b', position: 1, isVisible: true }, + { universalIdentifier: '9cb93542-2a91-4e75-a9f8-4a1866445322', fieldMetadataUniversalIdentifier: '500021ad-ca42-4fd3-8727-392dd26b722a', position: 2, isVisible: true }, + { universalIdentifier: 'd6df98ac-9c6c-46c2-8784-d4e1d6521f75', fieldMetadataUniversalIdentifier: '560503de-6330-4c1d-af97-a8dee125f2ad', position: 3, isVisible: true }, + { universalIdentifier: '375cc871-fdda-42d0-8308-e60174b6d467', fieldMetadataUniversalIdentifier: 'a0000004-0000-4000-8000-000000000004', position: 4, isVisible: true }, + ], + filters: [ + { + universalIdentifier: 'a3b7e215-693d-420c-b444-37d4109ca535', + fieldMetadataUniversalIdentifier: '2ca9856f-f54a-4326-9ff3-668fd7da0b50', + operand: ViewFilterOperand.IS, + value: ['VALIDATED'], + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/src/views/waiting-for-match.view.ts b/packages/twenty-apps/internal/twenty-partners/src/views/waiting-for-match.view.ts new file mode 100644 index 0000000000..57cee76807 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/src/views/waiting-for-match.view.ts @@ -0,0 +1,48 @@ +import { + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, + ViewFilterOperand, + ViewSortDirection, + ViewType, + defineView, +} from 'twenty-sdk/define'; + +import { + MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + WAITING_FOR_MATCH_VIEW_UNIVERSAL_IDENTIFIER, +} from 'src/constants/universal-identifiers'; + +// Ops inbox: opportunities awaiting a human matching decision. +// Includes TO_BE_MATCHED (default for new opps) and MANUAL_MATCH +// (opps that auto-match couldn't resolve or that ops opted to handle manually). +export default defineView({ + universalIdentifier: WAITING_FOR_MATCH_VIEW_UNIVERSAL_IDENTIFIER, + name: 'Waiting for match', + icon: 'IconClockHour4', + objectUniversalIdentifier: + STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity.universalIdentifier, + type: ViewType.KANBAN, + mainGroupByFieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + fields: [ + { universalIdentifier: 'd74b5eb3-21ee-48fa-b703-4cfd629738b4', fieldMetadataUniversalIdentifier: '20202020-8609-4f65-a2d9-44009eb422b5', position: 0, isVisible: true }, + { universalIdentifier: '50822cf9-c238-4450-ba31-5807011afa65', fieldMetadataUniversalIdentifier: '20202020-cbac-457e-b565-adece5fc815f', position: 1, isVisible: true }, + { universalIdentifier: 'f432a71f-3bd0-495e-b5b1-8a78e155dc5a', fieldMetadataUniversalIdentifier: '20202020-d01b-4132-9b32-123456789abc', position: 2, isVisible: true }, + { universalIdentifier: '9e47592f-9965-4ee7-9c6a-303477b293f4', fieldMetadataUniversalIdentifier: 'cc6b8a59-f860-493f-8b9a-f138c078fbf1', position: 3, isVisible: true }, + // matchStatus column (replaces the dropped partnerEligible column) + { universalIdentifier: '909e1eee-077a-4f23-8c9b-4c8027623a78', fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, position: 4, isVisible: true }, + ], + filters: [ + { + universalIdentifier: '93476207-1471-49d9-898c-f8a1d52f468f', + fieldMetadataUniversalIdentifier: MATCH_STATUS_FIELD_UNIVERSAL_IDENTIFIER, + operand: ViewFilterOperand.IS, + value: ['TO_BE_MATCHED', 'MANUAL_MATCH'], + }, + ], + sorts: [ + { + universalIdentifier: 'a7c5a89e-d9d7-4cf6-a6d2-3ad9f12a7b1f', + fieldMetadataUniversalIdentifier: '20202020-d01b-4132-9b32-123456789abc', + direction: ViewSortDirection.ASC, + }, + ], +}); diff --git a/packages/twenty-apps/internal/twenty-partners/tsconfig.json b/packages/twenty-apps/internal/twenty-partners/tsconfig.json new file mode 100644 index 0000000000..d574c8c810 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/tsconfig.json @@ -0,0 +1,42 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "sourceMap": true, + "declaration": true, + "outDir": "./dist", + "rootDir": ".", + "jsx": "react-jsx", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "allowUnreachableCode": false, + "strict": true, + "alwaysStrict": true, + "noImplicitAny": true, + "strictBindCallApply": false, + "target": "es2018", + "module": "esnext", + "lib": ["es2020", "dom"], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "resolveJsonModule": true, + "paths": { + "src/*": ["./src/*"], + "~/*": ["./*"] + } + }, + "exclude": [ + "node_modules", + "dist", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.integration-test.ts" + ], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/twenty-apps/internal/twenty-partners/tsconfig.spec.json b/packages/twenty-apps/internal/twenty-partners/tsconfig.spec.json new file mode 100644 index 0000000000..ea69a6c010 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "types": ["vitest/globals", "node"] + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/twenty-apps/internal/twenty-partners/vitest.config.ts b/packages/twenty-apps/internal/twenty-partners/vitest.config.ts new file mode 100644 index 0000000000..7ed938cad9 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/vitest.config.ts @@ -0,0 +1,40 @@ +import { loadEnv } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +// Integration tests authenticate to a local Twenty server. Credentials are +// resolved from the shell env, then a gitignored .env.local in this directory +// (see .env.example). No API key is committed; if none is found, global-setup +// fails with a clear message. +const fileEnv = loadEnv('test', process.cwd(), 'TWENTY_'); + +const TWENTY_API_URL = + process.env.TWENTY_API_URL ?? fileEnv.TWENTY_API_URL ?? 'http://localhost:2020'; +const TWENTY_API_KEY = process.env.TWENTY_API_KEY ?? fileEnv.TWENTY_API_KEY; + +// Make env available to globalSetup (runs in the main process); test.env below +// covers the worker processes. +process.env.TWENTY_API_URL = TWENTY_API_URL; +if (TWENTY_API_KEY) { + process.env.TWENTY_API_KEY = TWENTY_API_KEY; +} + +export default defineConfig({ + plugins: [ + tsconfigPaths({ + projects: ['tsconfig.spec.json'], + ignoreConfigErrors: true, + }), + ], + test: { + testTimeout: 120_000, + hookTimeout: 120_000, + fileParallelism: false, + include: ['src/**/*.integration-test.ts'], + globalSetup: ['src/__tests__/global-setup.ts'], + env: { + TWENTY_API_URL, + ...(TWENTY_API_KEY ? { TWENTY_API_KEY } : {}), + }, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-partners/yarn.lock b/packages/twenty-apps/internal/twenty-partners/yarn.lock new file mode 100644 index 0000000000..5db4798e5d --- /dev/null +++ b/packages/twenty-apps/internal/twenty-partners/yarn.lock @@ -0,0 +1,4607 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@alcalzone/ansi-tokenize@npm:^0.2.4": + version: 0.2.5 + resolution: "@alcalzone/ansi-tokenize@npm:0.2.5" + dependencies: + ansi-styles: "npm:^6.2.1" + is-fullwidth-code-point: "npm:^5.0.0" + checksum: 10c0/dd8622288426b5b7dbf8b68d51d4b930cea591d0e3b9dbc3f523131464d78ac922c165fcb7ba5307f133d35dbcaa0e6648a1c3fb6a0dc2725546d6f867b70af4 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/aix-ppc64@npm:0.25.12" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/aix-ppc64@npm:0.27.7" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/aix-ppc64@npm:0.28.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm64@npm:0.25.12" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm64@npm:0.27.7" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm64@npm:0.28.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm@npm:0.25.12" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm@npm:0.27.7" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm@npm:0.28.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-x64@npm:0.25.12" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-x64@npm:0.27.7" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-x64@npm:0.28.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-arm64@npm:0.25.12" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-arm64@npm:0.27.7" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-arm64@npm:0.28.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-x64@npm:0.25.12" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-x64@npm:0.27.7" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-x64@npm:0.28.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-arm64@npm:0.25.12" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-arm64@npm:0.27.7" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-arm64@npm:0.28.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-x64@npm:0.25.12" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-x64@npm:0.27.7" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-x64@npm:0.28.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm64@npm:0.25.12" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm64@npm:0.27.7" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm64@npm:0.28.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm@npm:0.25.12" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm@npm:0.27.7" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm@npm:0.28.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ia32@npm:0.25.12" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ia32@npm:0.27.7" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ia32@npm:0.28.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-loong64@npm:0.25.12" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-loong64@npm:0.27.7" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-loong64@npm:0.28.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-mips64el@npm:0.25.12" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-mips64el@npm:0.27.7" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-mips64el@npm:0.28.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ppc64@npm:0.25.12" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ppc64@npm:0.27.7" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ppc64@npm:0.28.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-riscv64@npm:0.25.12" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-riscv64@npm:0.27.7" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-riscv64@npm:0.28.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-s390x@npm:0.25.12" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-s390x@npm:0.27.7" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-s390x@npm:0.28.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-x64@npm:0.25.12" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-x64@npm:0.27.7" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-x64@npm:0.28.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-arm64@npm:0.25.12" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-arm64@npm:0.27.7" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-arm64@npm:0.28.0" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-x64@npm:0.25.12" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-x64@npm:0.27.7" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-x64@npm:0.28.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-arm64@npm:0.25.12" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-arm64@npm:0.27.7" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-arm64@npm:0.28.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-x64@npm:0.25.12" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-x64@npm:0.27.7" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-x64@npm:0.28.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openharmony-arm64@npm:0.25.12" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openharmony-arm64@npm:0.27.7" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openharmony-arm64@npm:0.28.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/sunos-x64@npm:0.25.12" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/sunos-x64@npm:0.27.7" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/sunos-x64@npm:0.28.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-arm64@npm:0.25.12" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-arm64@npm:0.27.7" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-arm64@npm:0.28.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-ia32@npm:0.25.12" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-ia32@npm:0.27.7" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-ia32@npm:0.28.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-x64@npm:0.25.12" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-x64@npm:0.27.7" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-x64@npm:0.28.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3 + languageName: node + linkType: hard + +"@genql/cli@npm:^3.0.3": + version: 3.0.5 + resolution: "@genql/cli@npm:3.0.5" + dependencies: + "@graphql-tools/graphql-file-loader": "npm:^7.5.11" + "@graphql-tools/load": "npm:^7.8.6" + fs-extra: "npm:^10.1.0" + graphql: "npm:^16.6.0" + kleur: "npm:^4.1.5" + listr: "npm:^0.14.3" + lodash: "npm:^4.17.21" + mkdirp: "npm:^0.5.1" + native-fetch: "npm:^4.0.2" + prettier: "npm:^2.8.0" + qs: "npm:^6.11.0" + rimraf: "npm:^2.6.3" + undici: "npm:^5.18.0" + yargs: "npm:^15.3.1" + bin: + genql: dist/cli.js + checksum: 10c0/646d4da8986741a8f1b610bd8cfb5bc26cd9a856de671461e4ca87fb05443f37dd0edfb3b30ceaa34cd049077873afa07febfd4714dd2e0681fb07484e19a080 + languageName: node + linkType: hard + +"@genql/runtime@npm:^2.10.0": + version: 2.10.0 + resolution: "@genql/runtime@npm:2.10.0" + dependencies: + "@types/qs": "npm:^6.9.0" + "@types/ws": "npm:^6.0.1" + graphql-query-batcher: "npm:^1.0.1" + isomorphic-unfetch: "npm:^3.0.0" + lodash: "npm:^4.17.20" + subscriptions-transport-ws: "npm:^0.9.16" + tslib: "npm:^2.0.0" + utility-types: "npm:^3.10.0" + ws: "npm:^6.1.4" + zen-observable-ts: "npm:^0.8.21" + peerDependencies: + graphql: "*" + checksum: 10c0/e2a886c2469c933681e2b0ddd6a5b7f4cb12932251ba460e3cf2db4246817da79313ea4ba9769ec7cbe53ab9c1cb81ad8fcce6a969cd241185b79398d2a4f3c6 + languageName: node + linkType: hard + +"@graphql-tools/graphql-file-loader@npm:^7.5.11": + version: 7.5.17 + resolution: "@graphql-tools/graphql-file-loader@npm:7.5.17" + dependencies: + "@graphql-tools/import": "npm:6.7.18" + "@graphql-tools/utils": "npm:^9.2.1" + globby: "npm:^11.0.3" + tslib: "npm:^2.4.0" + unixify: "npm:^1.0.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/f737f14357731ad01da57755e1cf26ce375b475209d6ab7e4b656b56191a8979d2ab7dd5d1c54a1f11e04374f7a373fa95ea5ec6a001d0cef913ea208fadc65b + languageName: node + linkType: hard + +"@graphql-tools/import@npm:6.7.18": + version: 6.7.18 + resolution: "@graphql-tools/import@npm:6.7.18" + dependencies: + "@graphql-tools/utils": "npm:^9.2.1" + resolve-from: "npm:5.0.0" + tslib: "npm:^2.4.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/d33e37a1879dd43ac2851c9bac2f2873c58bb3687f1c06e159760dbb5e540ef074d688df70cc6dbd3ee5de48d437878df8f65a7c65ae80bd025bf98f2d615732 + languageName: node + linkType: hard + +"@graphql-tools/load@npm:^7.8.6": + version: 7.8.14 + resolution: "@graphql-tools/load@npm:7.8.14" + dependencies: + "@graphql-tools/schema": "npm:^9.0.18" + "@graphql-tools/utils": "npm:^9.2.1" + p-limit: "npm:3.1.0" + tslib: "npm:^2.4.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/1fa036ac596ccf48f350aa545d108c173184d9b53247f9e21c0d4ba96c5cba4a0b44281f9154f122e1e8e9d9d6eab93a5b2618ca8a797969bde1e75c1d45e786 + languageName: node + linkType: hard + +"@graphql-tools/merge@npm:^8.4.1": + version: 8.4.2 + resolution: "@graphql-tools/merge@npm:8.4.2" + dependencies: + "@graphql-tools/utils": "npm:^9.2.1" + tslib: "npm:^2.4.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/2df55222b48e010e683572f456cf265aabae5748c59f7c1260c66dec9794b7a076d3706f04da969b77f0a32c7ccb4551fee30125931d3fe9c98a8806aae9a3f4 + languageName: node + linkType: hard + +"@graphql-tools/schema@npm:^9.0.18": + version: 9.0.19 + resolution: "@graphql-tools/schema@npm:9.0.19" + dependencies: + "@graphql-tools/merge": "npm:^8.4.1" + "@graphql-tools/utils": "npm:^9.2.1" + tslib: "npm:^2.4.0" + value-or-promise: "npm:^1.0.12" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/42fd8ca8d3c8d60b583077c201980518482ff0cd5ed0c1f14bd9b835a2689ad41d02cbd3478f7d7dea7aec1227f7639fd5deb5e6360852a2e542b96b44bfb7a4 + languageName: node + linkType: hard + +"@graphql-tools/utils@npm:^9.2.1": + version: 9.2.1 + resolution: "@graphql-tools/utils@npm:9.2.1" + dependencies: + "@graphql-typed-document-node/core": "npm:^3.1.1" + tslib: "npm:^2.4.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/37a7bd7e14d28ff1bacc007dca84bc6cef2d7d7af9a547b5dbe52fcd134afddd6d4a7b2148cfbaff5ddba91a868453d597da77bd0457fb0be15928f916901606 + languageName: node + linkType: hard + +"@graphql-typed-document-node/core@npm:^3.1.1": + version: 3.2.0 + resolution: "@graphql-typed-document-node/core@npm:3.2.0" + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 10c0/94e9d75c1f178bbae8d874f5a9361708a3350c8def7eaeb6920f2c820e82403b7d4f55b3735856d68e145e86c85cbfe2adc444fdc25519cd51f108697e99346c + languageName: node + linkType: hard + +"@inquirer/checkbox@npm:^2.5.0": + version: 2.5.0 + resolution: "@inquirer/checkbox@npm:2.5.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.3" + ansi-escapes: "npm:^4.3.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/679d17ffe3aef0825593f3bc8d193b6c37b860c6cf6e0e9a10d4e60cc254a2dfc5da4a982bf5b9b5147018e456fffcb0b0dadf93ee1914b9d600b0c814284e22 + languageName: node + linkType: hard + +"@inquirer/confirm@npm:^3.2.0": + version: 3.2.0 + resolution: "@inquirer/confirm@npm:3.2.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + checksum: 10c0/a2cbfc8ae9c880bba4cce1993f5c399fb0d12741fdd574917c87fceb40ece62ffa60e35aaadf4e62d7c114f54008e45aee5d6d90497bb62d493996c02725d243 + languageName: node + linkType: hard + +"@inquirer/core@npm:^9.1.0": + version: 9.2.1 + resolution: "@inquirer/core@npm:9.2.1" + dependencies: + "@inquirer/figures": "npm:^1.0.6" + "@inquirer/type": "npm:^2.0.0" + "@types/mute-stream": "npm:^0.0.4" + "@types/node": "npm:^22.5.5" + "@types/wrap-ansi": "npm:^3.0.0" + ansi-escapes: "npm:^4.3.2" + cli-width: "npm:^4.1.0" + mute-stream: "npm:^1.0.0" + signal-exit: "npm:^4.1.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^6.2.0" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/11c14be77a9fa85831de799a585721b0a49ab2f3b7d8fd1780c48ea2b29229c6bdc94e7892419086d0f7734136c2ba87b6a32e0782571eae5bbd655b1afad453 + languageName: node + linkType: hard + +"@inquirer/editor@npm:^2.2.0": + version: 2.2.0 + resolution: "@inquirer/editor@npm:2.2.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + external-editor: "npm:^3.1.0" + checksum: 10c0/b8afc0790a7a5d82998bdfe469cbaa83b0cd0700be432cf95256c548e2a6a494997b5e93d65cbf94979c17b510758cf8494d85559f6b9508eb15d239a7f22aee + languageName: node + linkType: hard + +"@inquirer/expand@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/expand@npm:2.3.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/f2030cb482a715e4d5153c19b3f0fd8bf47c16cdc16e1c669e90985386edf4f7b0f3b0e97e2990bb228878b93716228eb067d94fc557c25d3c5ee58747c0a995 + languageName: node + linkType: hard + +"@inquirer/figures@npm:^1.0.5, @inquirer/figures@npm:^1.0.6": + version: 1.0.15 + resolution: "@inquirer/figures@npm:1.0.15" + checksum: 10c0/6e39a040d260ae234ae220180b7994ff852673e20be925f8aa95e78c7934d732b018cbb4d0ec39e600a410461bcb93dca771e7de23caa10630d255692e440f69 + languageName: node + linkType: hard + +"@inquirer/input@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/input@npm:2.3.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + checksum: 10c0/44c8cea38c9192f528cae556f38709135a00230132deab3b9bb9a925375fce0513fecf4e8c1df7c4319e1ed7aa31fb4dd2c4956c8bc9dd39af087aafff5b6f1f + languageName: node + linkType: hard + +"@inquirer/number@npm:^1.1.0": + version: 1.1.0 + resolution: "@inquirer/number@npm:1.1.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + checksum: 10c0/db472dab57c951c4a083b2a749ce58262b1efd9889e7603de6e9c3f9af7d8dce8fbdfa3859f65402d3587470e0397a076e5fb4ed775db33310f17a42c9faeb20 + languageName: node + linkType: hard + +"@inquirer/password@npm:^2.2.0": + version: 2.2.0 + resolution: "@inquirer/password@npm:2.2.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + ansi-escapes: "npm:^4.3.2" + checksum: 10c0/fa4b335164b2c9c3304d29a7214ef93bac8d3da6788146603ea3d0485b8d811151e49bf66cb0dcc729a9dc21406c3a8c2718c5beec572a91d07026d22842c13f + languageName: node + linkType: hard + +"@inquirer/prompts@npm:^5.5.0": + version: 5.5.0 + resolution: "@inquirer/prompts@npm:5.5.0" + dependencies: + "@inquirer/checkbox": "npm:^2.5.0" + "@inquirer/confirm": "npm:^3.2.0" + "@inquirer/editor": "npm:^2.2.0" + "@inquirer/expand": "npm:^2.3.0" + "@inquirer/input": "npm:^2.3.0" + "@inquirer/number": "npm:^1.1.0" + "@inquirer/password": "npm:^2.2.0" + "@inquirer/rawlist": "npm:^2.3.0" + "@inquirer/search": "npm:^1.1.0" + "@inquirer/select": "npm:^2.5.0" + checksum: 10c0/2d62b50ca761b2bd2d5759f48c03758f1af0665ac602c26ae1ae257ac512cf5c27fd82cde108ee0c6371ec39187adc6f45637f31ca79adf5bf96579f23e77143 + languageName: node + linkType: hard + +"@inquirer/rawlist@npm:^2.3.0": + version: 2.3.0 + resolution: "@inquirer/rawlist@npm:2.3.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/type": "npm:^1.5.3" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/d49d5e12b7a54394c140b27c8d8748ba1ab855c67c01fa72b5a63810f12865df3bf4d5ae929f54fad77b5fc2f7431a332ae1e5fe4babb335380c28917002f364 + languageName: node + linkType: hard + +"@inquirer/search@npm:^1.1.0": + version: 1.1.0 + resolution: "@inquirer/search@npm:1.1.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.3" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/20d7e910266b9e3f0dc8eef8f3007f487e6149fa8421d293eaf7c11a1e35c3d82aa30af118b3a6e35eed1048a27d7d806f45722abb10005db5d099ea64b00b17 + languageName: node + linkType: hard + +"@inquirer/select@npm:^2.5.0": + version: 2.5.0 + resolution: "@inquirer/select@npm:2.5.0" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.3" + ansi-escapes: "npm:^4.3.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/280fa700187ff29da0ad4bf32aa11db776261584ddf5cc1ceac5caebb242a4ac0c5944af522a2579d78b6ec7d6e8b1b9f6564872101abd8dcc69929b4e33fc4c + languageName: node + linkType: hard + +"@inquirer/type@npm:^1.5.3": + version: 1.5.5 + resolution: "@inquirer/type@npm:1.5.5" + dependencies: + mute-stream: "npm:^1.0.0" + checksum: 10c0/4c41736c09ba9426b5a9e44993bdd54e8f532e791518802e33866f233a2a6126a25c1c82c19d1abbf1df627e57b1b957dd3f8318ea96073d8bfc32193943bcb3 + languageName: node + linkType: hard + +"@inquirer/type@npm:^2.0.0": + version: 2.0.0 + resolution: "@inquirer/type@npm:2.0.0" + dependencies: + mute-stream: "npm:^1.0.0" + checksum: 10c0/8c663d52beb2b89a896d3c3d5cc3d6d024fa149e565555bcb42fa640cbe23fba7ff2c51445342cef1fe6e46305e2d16c1590fa1d11ad0ddf93a67b655ef41f0a + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 + languageName: node + linkType: hard + +"@oxlint/darwin-arm64@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/darwin-arm64@npm:0.16.12" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/darwin-x64@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/darwin-x64@npm:0.16.12" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxlint/linux-arm64-gnu@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/linux-arm64-gnu@npm:0.16.12" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/linux-arm64-musl@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/linux-arm64-musl@npm:0.16.12" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxlint/linux-x64-gnu@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/linux-x64-gnu@npm:0.16.12" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/linux-x64-musl@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/linux-x64-musl@npm:0.16.12" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxlint/win32-arm64@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/win32-arm64@npm:0.16.12" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/win32-x64@npm:0.16.12": + version: 0.16.12 + resolution: "@oxlint/win32-x64@npm:0.16.12" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.60.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-android-arm64@npm:4.60.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-darwin-arm64@npm:4.60.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-darwin-x64@npm:4.60.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.60.4" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-freebsd-x64@npm:4.60.4" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.60.4" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.60.4" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.60.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.60.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.60.4" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-loong64-musl@npm:4.60.4" + conditions: os=linux & cpu=loong64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.60.4" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.60.4" + conditions: os=linux & cpu=ppc64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.60.4" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.60.4" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.60.4" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.60.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.60.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openbsd-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-openbsd-x64@npm:4.60.4" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.60.4" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.60.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.60.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.60.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.60.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@samverschueren/stream-to-observable@npm:^0.3.0": + version: 0.3.1 + resolution: "@samverschueren/stream-to-observable@npm:0.3.1" + dependencies: + any-observable: "npm:^0.3.0" + peerDependenciesMeta: + rxjs: + optional: true + zen-observable: + optional: true + checksum: 10c0/0d874453f6bc2460d71783292291f52feb36c2a75314b1072a6ffe6206562f33e9d664a554348d565a6b54da9041d75070371052545bc329caaa52f64216987f + languageName: node + linkType: hard + +"@sniptt/guards@npm:^0.2.0": + version: 0.2.0 + resolution: "@sniptt/guards@npm:0.2.0" + checksum: 10c0/749bb0f550d1ddd4abdb23dc1076cba26e977659922b73d000bceeb253c09270aaced0d18e92f09d4ce2fdaae33e55f60f2142f5359bc90ba505422af0873526 + languageName: node + linkType: hard + +"@types/chai@npm:^5.2.2": + version: 5.2.3 + resolution: "@types/chai@npm:5.2.3" + dependencies: + "@types/deep-eql": "npm:*" + assertion-error: "npm:^2.0.1" + checksum: 10c0/e0ef1de3b6f8045a5e473e867c8565788c444271409d155588504840ad1a53611011f85072188c2833941189400228c1745d78323dac13fcede9c2b28bacfb2f + languageName: node + linkType: hard + +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 + languageName: node + linkType: hard + +"@types/estree@npm:^1.0.0": + version: 1.0.9 + resolution: "@types/estree@npm:1.0.9" + checksum: 10c0/3ad3286ca2988cd550dafb8f2ad599c8474868e954fa601a36655bdfefd8039f7c714b8c1c7f2ae219ffbd58bd4660e66fa7479a0120fc02d4777057d4865387 + languageName: node + linkType: hard + +"@types/mute-stream@npm:^0.0.4": + version: 0.0.4 + resolution: "@types/mute-stream@npm:0.0.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/944730fd7b398c5078de3c3d4d0afeec8584283bc694da1803fdfca14149ea385e18b1b774326f1601baf53898ce6d121a952c51eb62d188ef6fcc41f725c0dc + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 25.8.0 + resolution: "@types/node@npm:25.8.0" + dependencies: + undici-types: "npm:>=7.24.0 <7.24.7" + checksum: 10c0/ff53e5428309d2e6060190ec5e02afd0e4a7369456b16130a7f5898f12a6ad0efd62d752830f2f7355d714ae429bc0acbb2dc0cbf761cadb03e88c4996cdf1dc + languageName: node + linkType: hard + +"@types/node@npm:^22.5.5": + version: 22.19.19 + resolution: "@types/node@npm:22.19.19" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/402e0f088c94cabda3cd721546bd8e4e75e098e0b342f6e03b90ca1e19c28986f9650112c64fcfd09fc8cebc0f8b20291a513153e90489331cf666e1e5503e16 + languageName: node + linkType: hard + +"@types/node@npm:^24.7.2": + version: 24.12.4 + resolution: "@types/node@npm:24.12.4" + dependencies: + undici-types: "npm:~7.16.0" + checksum: 10c0/d2c36b78b6050d8677769fa05a32243061675e81ddc2bb43955d91a671af3465506ef2731a24c0c9ab42b6b679bd5c1513de45bbe9ea278c2c07ee63b564b61b + languageName: node + linkType: hard + +"@types/qs@npm:^6.9.0": + version: 6.15.1 + resolution: "@types/qs@npm:6.15.1" + checksum: 10c0/1dfdbcb4cf2a8f66d57f0b9a9fe6b1c7091cb816687b6698c1351eaf31f62e412cea9b7453a9637b570cd5fad8dced527e5a9e69b4fcc6e318daacd8b749f094 + languageName: node + linkType: hard + +"@types/react@npm:^19.0.0": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" + dependencies: + csstype: "npm:^3.2.2" + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + languageName: node + linkType: hard + +"@types/wrap-ansi@npm:^3.0.0": + version: 3.0.0 + resolution: "@types/wrap-ansi@npm:3.0.0" + checksum: 10c0/8d8f53363f360f38135301a06b596c295433ad01debd082078c33c6ed98b05a5c8fe8853a88265432126096084f4a135ec1564e3daad631b83296905509f90b3 + languageName: node + linkType: hard + +"@types/ws@npm:^6.0.1": + version: 6.0.4 + resolution: "@types/ws@npm:6.0.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/fa958e64596ca9487c3ed6012834de70b47f25d971f1950cfb8e6a99cb77ff340ae82ac7627744e01b58010674ef8ede07d5a2ac29ca9ad0d67a430fcc69ae14 + languageName: node + linkType: hard + +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/7586104e3fd31dbe1e6ecaafb9a70131e4197dce2940f727b6a84131eee3decac7b10f9c7c72fa5edbdb68b6f854353bd4c0fa84779e274207fb7379563b10db + languageName: node + linkType: hard + +"@vitest/mocker@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/mocker@npm:3.2.4" + dependencies: + "@vitest/spy": "npm:3.2.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.17" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/f7a4aea19bbbf8f15905847ee9143b6298b2c110f8b64789224cb0ffdc2e96f9802876aa2ca83f1ec1b6e1ff45e822abb34f0054c24d57b29ab18add06536ccd + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" + dependencies: + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/5ad7d4278e067390d7d633e307fee8103958806a419ca380aec0e33fae71b44a64415f7a9b4bc11635d3c13d4a9186111c581d3cef9c65cc317e68f077456887 + languageName: node + linkType: hard + +"@vitest/runner@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/runner@npm:3.2.4" + dependencies: + "@vitest/utils": "npm:3.2.4" + pathe: "npm:^2.0.3" + strip-literal: "npm:^3.0.0" + checksum: 10c0/e8be51666c72b3668ae3ea348b0196656a4a5adb836cb5e270720885d9517421815b0d6c98bfdf1795ed02b994b7bfb2b21566ee356a40021f5bf4f6ed4e418a + languageName: node + linkType: hard + +"@vitest/snapshot@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/snapshot@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + checksum: 10c0/f8301a3d7d1559fd3d59ed51176dd52e1ed5c2d23aa6d8d6aa18787ef46e295056bc726a021698d8454c16ed825ecba163362f42fa90258bb4a98cfd2c9424fc + languageName: node + linkType: hard + +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" + dependencies: + tinyspy: "npm:^4.0.3" + checksum: 10c0/6ebf0b4697dc238476d6b6a60c76ba9eb1dd8167a307e30f08f64149612fd50227682b876420e4c2e09a76334e73f72e3ebf0e350714dc22474258292e202024 + languageName: node + linkType: hard + +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + loupe: "npm:^3.1.4" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/024a9b8c8bcc12cf40183c246c244b52ecff861c6deb3477cbf487ac8781ad44c68a9c5fd69f8c1361878e55b97c10d99d511f2597f1f7244b5e5101d028ba64 + languageName: node + linkType: hard + +"abbrev@npm:^4.0.0": + version: 4.0.0 + resolution: "abbrev@npm:4.0.0" + checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5 + languageName: node + linkType: hard + +"agent-base@npm:6": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: 10c0/dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261 + languageName: node + linkType: hard + +"ansi-escapes@npm:^3.0.0": + version: 3.2.0 + resolution: "ansi-escapes@npm:3.2.0" + checksum: 10c0/084e1ce38139ad2406f18a8e7efe2b850ddd06ce3c00f633392d1ce67756dab44fe290e573d09ef3c9a0cb13c12881e0e35a8f77a017d39a0a4ab85ae2fae04f + languageName: node + linkType: hard + +"ansi-escapes@npm:^4.3.2": + version: 4.3.2 + resolution: "ansi-escapes@npm:4.3.2" + dependencies: + type-fest: "npm:^0.21.3" + checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50 + languageName: node + linkType: hard + +"ansi-escapes@npm:^7.3.0": + version: 7.3.0 + resolution: "ansi-escapes@npm:7.3.0" + dependencies: + environment: "npm:^1.0.0" + checksum: 10c0/068961d99f0ef28b661a4a9f84a5d645df93ccf3b9b93816cc7d46bbe1913321d4cdf156bb842a4e1e4583b7375c631fa963efb43001c4eb7ff9ab8f78fc0679 + languageName: node + linkType: hard + +"ansi-regex@npm:^2.0.0": + version: 2.1.1 + resolution: "ansi-regex@npm:2.1.1" + checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b + languageName: node + linkType: hard + +"ansi-regex@npm:^3.0.0": + version: 3.0.1 + resolution: "ansi-regex@npm:3.0.1" + checksum: 10c0/d108a7498b8568caf4a46eea4f1784ab4e0dfb2e3f3938c697dee21443d622d765c958f2b7e2b9f6b9e55e2e2af0584eaa9915d51782b89a841c28e744e7a167 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.2.2": + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f + languageName: node + linkType: hard + +"ansi-styles@npm:^2.2.1": + version: 2.2.1 + resolution: "ansi-styles@npm:2.2.1" + checksum: 10c0/7c68aed4f1857389e7a12f85537ea5b40d832656babbf511cc7ecd9efc52889b9c3e5653a71a6aade783c3c5e0aa223ad4ff8e83c27ac8a666514e6c79068cab + languageName: node + linkType: hard + +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.2.1, ansi-styles@npm:^6.2.3": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 + languageName: node + linkType: hard + +"any-observable@npm:^0.3.0": + version: 0.3.0 + resolution: "any-observable@npm:0.3.0" + checksum: 10c0/104c2b79c2ac7e6c75b35f8fd62babf73015668f22bd25336c6f848350d91f9e7daf2fddbf1c1b76fe795e89fbc91b49f70a2aec5c69f1acf0562c344f36042b + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 + languageName: node + linkType: hard + +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186 + languageName: node + linkType: hard + +"async-limiter@npm:~1.0.0": + version: 1.0.1 + resolution: "async-limiter@npm:1.0.1" + checksum: 10c0/0693d378cfe86842a70d4c849595a0bb50dc44c11649640ca982fa90cbfc74e3cc4753b5a0847e51933f2e9c65ce8e05576e75e5e1fd963a086e673735b35969 + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + +"auto-bind@npm:^5.0.1": + version: 5.0.1 + resolution: "auto-bind@npm:5.0.1" + checksum: 10c0/a703375350ea7b6e92405d8e6bcc6dbfb84b0d7c7172b33e5788a7593929a18227999ff9aa9c32436741d06d021e6672457b1cec73287efe3fab95cff6627eaf + languageName: node + linkType: hard + +"axios@npm:^1.13.5": + version: 1.16.1 + resolution: "axios@npm:1.16.1" + dependencies: + follow-redirects: "npm:^1.16.0" + form-data: "npm:^4.0.5" + https-proxy-agent: "npm:^5.0.1" + proxy-from-env: "npm:^2.1.0" + checksum: 10c0/2f77e37e6552bbff8a772d058fb09500198e9188c6b20dc799d82dbe12a8cb506f6eed4e4e62a9ba612a35cbab496faa26d68f9bff14a53af6d15c3e136391a7 + languageName: node + linkType: hard + +"backo2@npm:^1.0.2": + version: 1.0.2 + resolution: "backo2@npm:1.0.2" + checksum: 10c0/a9e825a6a38a6d1c4a94476eabc13d6127dfaafb0967baf104affbb67806ae26abbb58dab8d572d2cd21ef06634ff57c3ad48dff14b904e18de1474cc2f22bf3 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.14 + resolution: "brace-expansion@npm:1.1.14" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10c0/b6fdac832bc4e36a753658c9ed052c2e1a2be221763b002df25d1efbf7d21724334e726a6cd5eadc72a4b19ec3efb632d629cc003bc9c62f7af7a7915ffa4385 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 + languageName: node + linkType: hard + +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 + languageName: node + linkType: hard + +"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.2": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + +"camelcase@npm:^5.0.0": + version: 5.3.1 + resolution: "camelcase@npm:5.3.1" + checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23 + languageName: node + linkType: hard + +"chai@npm:^5.2.0": + version: 5.3.3 + resolution: "chai@npm:5.3.3" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/b360fd4d38861622e5010c2f709736988b05c7f31042305fa3f4e9911f6adb80ccfb4e302068bf8ed10e835c2e2520cba0f5edc13d878b886987e5aa62483f53 + languageName: node + linkType: hard + +"chalk@npm:^1.0.0, chalk@npm:^1.1.3": + version: 1.1.3 + resolution: "chalk@npm:1.1.3" + dependencies: + ansi-styles: "npm:^2.2.1" + escape-string-regexp: "npm:^1.0.2" + has-ansi: "npm:^2.0.0" + strip-ansi: "npm:^3.0.0" + supports-color: "npm:^2.0.0" + checksum: 10c0/28c3e399ec286bb3a7111fd4225ebedb0d7b813aef38a37bca7c498d032459c265ef43404201d5fbb8d888d29090899c95335b4c0cda13e8b126ff15c541cef8 + languageName: node + linkType: hard + +"chalk@npm:^2.4.1": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0, chalk@npm:^5.6.0": + version: 5.6.2 + resolution: "chalk@npm:5.6.2" + checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 + languageName: node + linkType: hard + +"chardet@npm:^0.7.0": + version: 0.7.0 + resolution: "chardet@npm:0.7.0" + checksum: 10c0/96e4731b9ec8050cbb56ab684e8c48d6c33f7826b755802d14e3ebfdc51c57afeece3ea39bc6b09acc359e4363525388b915e16640c1378053820f5e70d0f27d + languageName: node + linkType: hard + +"check-error@npm:^2.1.1": + version: 2.1.3 + resolution: "check-error@npm:2.1.3" + checksum: 10c0/878e99038fb6476316b74668cd6a498c7e66df3efe48158fa40db80a06ba4258742ac3ee2229c4a2a98c5e73f5dff84eb3e50ceb6b65bbd8f831eafc8338607d + languageName: node + linkType: hard + +"chokidar@npm:^4.0.0": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: "npm:^4.0.1" + checksum: 10c0/a58b9df05bb452f7d105d9e7229ac82fa873741c0c40ddcc7bb82f8a909fbe3f7814c9ebe9bc9a2bef9b737c0ec6e2d699d179048ef06ad3ec46315df0ebe6ad + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 + languageName: node + linkType: hard + +"cli-boxes@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-boxes@npm:3.0.0" + checksum: 10c0/4db3e8fbfaf1aac4fb3a6cbe5a2d3fa048bee741a45371b906439b9ffc821c6e626b0f108bdcd3ddf126a4a319409aedcf39a0730573ff050fdd7b6731e99fb9 + languageName: node + linkType: hard + +"cli-cursor@npm:^2.0.0, cli-cursor@npm:^2.1.0": + version: 2.1.0 + resolution: "cli-cursor@npm:2.1.0" + dependencies: + restore-cursor: "npm:^2.0.0" + checksum: 10c0/09ee6d8b5b818d840bf80ec9561eaf696672197d3a02a7daee2def96d5f52ce6e0bbe7afca754ccf14f04830b5a1b4556273e983507d5029f95bba3016618eda + languageName: node + linkType: hard + +"cli-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-cursor@npm:4.0.0" + dependencies: + restore-cursor: "npm:^4.0.0" + checksum: 10c0/e776e8c3c6727300d0539b0d25160b2bb56aed1a63942753ba1826b012f337a6f4b7ace3548402e4f2f13b5e16bfd751be672c44b203205e7eca8be94afec42c + languageName: node + linkType: hard + +"cli-truncate@npm:^0.2.1": + version: 0.2.1 + resolution: "cli-truncate@npm:0.2.1" + dependencies: + slice-ansi: "npm:0.0.4" + string-width: "npm:^1.0.1" + checksum: 10c0/c6caa5e2b70d841c42f4a2270d6fc7129df915f8911e4afa90c79231ccc857cd819a2c90e0707fde04e51ce56b4d71646b843f6cbaff4f7cdcb3b91ed51f6e89 + languageName: node + linkType: hard + +"cli-truncate@npm:^5.1.1": + version: 5.2.0 + resolution: "cli-truncate@npm:5.2.0" + dependencies: + slice-ansi: "npm:^8.0.0" + string-width: "npm:^8.2.0" + checksum: 10c0/0d4ec94702ca85b64522ac93633837fb5ea7db17b79b1322a60f6045e6ae2b8cd7bd4c1d19ac7d1f9e10e3bbda1112e172e439b68c02b785ee00da8d6a5c5471 + languageName: node + linkType: hard + +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 10c0/1fbd56413578f6117abcaf858903ba1f4ad78370a4032f916745fa2c7e390183a9d9029cf837df320b0fdce8137668e522f60a30a5f3d6529ff3872d265a955f + languageName: node + linkType: hard + +"cliui@npm:^6.0.0": + version: 6.0.0 + resolution: "cliui@npm:6.0.0" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.0" + wrap-ansi: "npm:^6.2.0" + checksum: 10c0/35229b1bb48647e882104cac374c9a18e34bbf0bace0e2cf03000326b6ca3050d6b59545d91e17bfe3705f4a0e2988787aa5cde6331bf5cbbf0164732cef6492 + languageName: node + linkType: hard + +"code-excerpt@npm:^4.0.0": + version: 4.0.0 + resolution: "code-excerpt@npm:4.0.0" + dependencies: + convert-to-spaces: "npm:^2.0.1" + checksum: 10c0/b6c5a06e039cecd2ab6a0e10ee0831de8362107d1f298ca3558b5f9004cb8e0260b02dd6c07f57b9a0e346c76864d2873311ee1989809fdeb05bd5fbbadde773 + languageName: node + linkType: hard + +"code-point-at@npm:^1.0.0": + version: 1.1.0 + resolution: "code-point-at@npm:1.1.0" + checksum: 10c0/33f6b234084e46e6e369b6f0b07949392651b4dde70fc6a592a8d3dafa08d5bb32e3981a02f31f6fc323a26bc03a4c063a9d56834848695bda7611c2417ea2e6 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + +"commander@npm:^12.0.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + +"convert-to-spaces@npm:^2.0.1": + version: 2.0.1 + resolution: "convert-to-spaces@npm:2.0.1" + checksum: 10c0/d90aa0e3b6a27f9d5265a8d32def3c5c855b3e823a9db1f26d772f8146d6b91020a2fdfd905ce8048a73fad3aaf836fef8188c67602c374405e2ae8396c4ac46 + languageName: node + linkType: hard + +"csstype@npm:^3.2.2": + version: 3.2.3 + resolution: "csstype@npm:3.2.3" + checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce + languageName: node + linkType: hard + +"date-fns@npm:^1.27.2": + version: 1.30.1 + resolution: "date-fns@npm:1.30.1" + checksum: 10c0/bad6ad7c15180121e15d61ad62a4a214c108d66f35b35f5eeb6ade837a3c29aa4444b9528a93a5374b95ba11231c142276351bf52f4d168676f9a1e17ce3726a + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.4.1": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 + languageName: node + linkType: hard + +"decamelize@npm:^1.2.0": + version: 1.2.0 + resolution: "decamelize@npm:1.2.0" + checksum: 10c0/85c39fe8fbf0482d4a1e224ef0119db5c1897f8503bcef8b826adff7a1b11414972f6fef2d7dec2ee0b4be3863cf64ac1439137ae9e6af23a3d8dcbe26a5b4b2 + languageName: node + linkType: hard + +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c + languageName: node + linkType: hard + +"dotenv@npm:^16.0.0, dotenv@npm:^16.4.0": + version: 16.6.1 + resolution: "dotenv@npm:16.6.1" + checksum: 10c0/15ce56608326ea0d1d9414a5c8ee6dcf0fffc79d2c16422b4ac2268e7e2d76ff5a572d37ffe747c377de12005f14b3cc22361e79fc7f1061cce81f77d2c973dc + languageName: node + linkType: hard + +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.2.0" + checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031 + languageName: node + linkType: hard + +"elegant-spinner@npm:^1.0.1": + version: 1.0.1 + resolution: "elegant-spinner@npm:1.0.1" + checksum: 10c0/df607c83c20fc3ce56c514175dd5d1ee7f667da00cee13d04d32c70d55e76555091fa236689e691cf7dedba17b0020fec635e499cdde84dbea2ef8639314e5f8 + languageName: node + linkType: hard + +"emoji-regex@npm:^10.3.0": + version: 10.6.0 + resolution: "emoji-regex@npm:10.6.0" + checksum: 10c0/1e4aa097bb007301c3b4b1913879ae27327fdc48e93eeefefe3b87e495eb33c5af155300be951b4349ff6ac084f4403dc9eff970acba7c1c572d89396a9a32d7 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"environment@npm:^1.0.0": + version: 1.1.0 + resolution: "environment@npm:1.1.0" + checksum: 10c0/fb26434b0b581ab397039e51ff3c92b34924a98b2039dcb47e41b7bca577b9dbf134a8eadb364415c74464b682e2d3afe1a4c0eb9873dc44ea814c5d3103331d + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10c0/ef2ca9ce49afe3931cb32e35da4dcb6d86ab02592cfc2ce3e49ced199d9d0bb5085fc7e73e06312213765f5efa47cc1df553a6a5154584b21448e9fb8355b1af + languageName: node + linkType: hard + +"es-toolkit@npm:^1.39.10": + version: 1.46.1 + resolution: "es-toolkit@npm:1.46.1" + dependenciesMeta: + "@trivago/prettier-plugin-sort-imports@4.3.0": + unplugged: true + prettier-plugin-sort-re-exports@0.0.1: + unplugged: true + checksum: 10c0/6a4c3dd0ddc2138fa13d983d93ebaf8061759c52c2cf7c3101315139fc1fca826d253daa67fe85ad880c03cc4c092bd53a83a7cbf58b4721c251479122ba5303 + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": + version: 0.25.12 + resolution: "esbuild@npm:0.25.12" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.12" + "@esbuild/android-arm": "npm:0.25.12" + "@esbuild/android-arm64": "npm:0.25.12" + "@esbuild/android-x64": "npm:0.25.12" + "@esbuild/darwin-arm64": "npm:0.25.12" + "@esbuild/darwin-x64": "npm:0.25.12" + "@esbuild/freebsd-arm64": "npm:0.25.12" + "@esbuild/freebsd-x64": "npm:0.25.12" + "@esbuild/linux-arm": "npm:0.25.12" + "@esbuild/linux-arm64": "npm:0.25.12" + "@esbuild/linux-ia32": "npm:0.25.12" + "@esbuild/linux-loong64": "npm:0.25.12" + "@esbuild/linux-mips64el": "npm:0.25.12" + "@esbuild/linux-ppc64": "npm:0.25.12" + "@esbuild/linux-riscv64": "npm:0.25.12" + "@esbuild/linux-s390x": "npm:0.25.12" + "@esbuild/linux-x64": "npm:0.25.12" + "@esbuild/netbsd-arm64": "npm:0.25.12" + "@esbuild/netbsd-x64": "npm:0.25.12" + "@esbuild/openbsd-arm64": "npm:0.25.12" + "@esbuild/openbsd-x64": "npm:0.25.12" + "@esbuild/openharmony-arm64": "npm:0.25.12" + "@esbuild/sunos-x64": "npm:0.25.12" + "@esbuild/win32-arm64": "npm:0.25.12" + "@esbuild/win32-ia32": "npm:0.25.12" + "@esbuild/win32-x64": "npm:0.25.12" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/c205357531423220a9de8e1e6c6514242bc9b1666e762cd67ccdf8fdfdc3f1d0bd76f8d9383958b97ad4c953efdb7b6e8c1f9ca5951cd2b7c5235e8755b34a6b + languageName: node + linkType: hard + +"esbuild@npm:^0.27.0": + version: 0.27.7 + resolution: "esbuild@npm:0.27.7" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.7" + "@esbuild/android-arm": "npm:0.27.7" + "@esbuild/android-arm64": "npm:0.27.7" + "@esbuild/android-x64": "npm:0.27.7" + "@esbuild/darwin-arm64": "npm:0.27.7" + "@esbuild/darwin-x64": "npm:0.27.7" + "@esbuild/freebsd-arm64": "npm:0.27.7" + "@esbuild/freebsd-x64": "npm:0.27.7" + "@esbuild/linux-arm": "npm:0.27.7" + "@esbuild/linux-arm64": "npm:0.27.7" + "@esbuild/linux-ia32": "npm:0.27.7" + "@esbuild/linux-loong64": "npm:0.27.7" + "@esbuild/linux-mips64el": "npm:0.27.7" + "@esbuild/linux-ppc64": "npm:0.27.7" + "@esbuild/linux-riscv64": "npm:0.27.7" + "@esbuild/linux-s390x": "npm:0.27.7" + "@esbuild/linux-x64": "npm:0.27.7" + "@esbuild/netbsd-arm64": "npm:0.27.7" + "@esbuild/netbsd-x64": "npm:0.27.7" + "@esbuild/openbsd-arm64": "npm:0.27.7" + "@esbuild/openbsd-x64": "npm:0.27.7" + "@esbuild/openharmony-arm64": "npm:0.27.7" + "@esbuild/sunos-x64": "npm:0.27.7" + "@esbuild/win32-arm64": "npm:0.27.7" + "@esbuild/win32-ia32": "npm:0.27.7" + "@esbuild/win32-x64": "npm:0.27.7" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/ccd51f0555708bc9ff4ec9dc3ac92d3daacd45ecaac949ca8645984c5c323bf8cefe98c2df307418685e0b4ce37f9a3bdbfe8e3651fe632a0059a436195a17d4 + languageName: node + linkType: hard + +"esbuild@npm:~0.28.0": + version: 0.28.0 + resolution: "esbuild@npm:0.28.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.28.0" + "@esbuild/android-arm": "npm:0.28.0" + "@esbuild/android-arm64": "npm:0.28.0" + "@esbuild/android-x64": "npm:0.28.0" + "@esbuild/darwin-arm64": "npm:0.28.0" + "@esbuild/darwin-x64": "npm:0.28.0" + "@esbuild/freebsd-arm64": "npm:0.28.0" + "@esbuild/freebsd-x64": "npm:0.28.0" + "@esbuild/linux-arm": "npm:0.28.0" + "@esbuild/linux-arm64": "npm:0.28.0" + "@esbuild/linux-ia32": "npm:0.28.0" + "@esbuild/linux-loong64": "npm:0.28.0" + "@esbuild/linux-mips64el": "npm:0.28.0" + "@esbuild/linux-ppc64": "npm:0.28.0" + "@esbuild/linux-riscv64": "npm:0.28.0" + "@esbuild/linux-s390x": "npm:0.28.0" + "@esbuild/linux-x64": "npm:0.28.0" + "@esbuild/netbsd-arm64": "npm:0.28.0" + "@esbuild/netbsd-x64": "npm:0.28.0" + "@esbuild/openbsd-arm64": "npm:0.28.0" + "@esbuild/openbsd-x64": "npm:0.28.0" + "@esbuild/openharmony-arm64": "npm:0.28.0" + "@esbuild/sunos-x64": "npm:0.28.0" + "@esbuild/win32-arm64": "npm:0.28.0" + "@esbuild/win32-ia32": "npm:0.28.0" + "@esbuild/win32-x64": "npm:0.28.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/8acd95c238ec6c4a9d16163277faf228a8994b642d187b3fe667ffbb469008e6748cde144fdc3c175bf8e78ee49e15a0ed9b9f183fdb5fcea1772f87fb1372a4 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 + languageName: node + linkType: hard + +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d + languageName: node + linkType: hard + +"eventemitter3@npm:^3.1.0": + version: 3.1.2 + resolution: "eventemitter3@npm:3.1.2" + checksum: 10c0/c67262eccbf85848b7cc6d4abb6c6e34155e15686db2a01c57669fd0d44441a574a19d44d25948b442929e065774cbe5003d8e77eed47674fbf876ac77887793 + languageName: node + linkType: hard + +"expect-type@npm:^1.2.1": + version: 1.3.0 + resolution: "expect-type@npm:1.3.0" + checksum: 10c0/8412b3fe4f392c420ab41dae220b09700e4e47c639a29ba7ba2e83cc6cffd2b4926f7ac9e47d7e277e8f4f02acda76fd6931cb81fd2b382fa9477ef9ada953fd + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.3 + resolution: "exponential-backoff@npm:3.1.3" + checksum: 10c0/77e3ae682b7b1f4972f563c6dbcd2b0d54ac679e62d5d32f3e5085feba20483cf28bd505543f520e287a56d4d55a28d7874299941faf637e779a1aa5994d1267 + languageName: node + linkType: hard + +"external-editor@npm:^3.1.0": + version: 3.1.0 + resolution: "external-editor@npm:3.1.0" + dependencies: + chardet: "npm:^0.7.0" + iconv-lite: "npm:^0.4.24" + tmp: "npm:^0.0.33" + checksum: 10c0/c98f1ba3efdfa3c561db4447ff366a6adb5c1e2581462522c56a18bf90dfe4da382f9cd1feee3e330108c3595a854b218272539f311ba1b3298f841eb0fbf339 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.9": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.8" + checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.20.1 + resolution: "fastq@npm:1.20.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10c0/e5dd725884decb1f11e5c822221d76136f239d0236f176fab80b7b8f9e7619ae57e6b4e5b73defc21e6b9ef99437ee7b545cff8e6c2c337819633712fa9d352e + languageName: node + linkType: hard + +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f + languageName: node + linkType: hard + +"figures@npm:^1.7.0": + version: 1.7.0 + resolution: "figures@npm:1.7.0" + dependencies: + escape-string-regexp: "npm:^1.0.5" + object-assign: "npm:^4.1.0" + checksum: 10c0/a10942b0eec3372bf61822ab130d2bbecdf527d551b0b013fbe7175b7a0238ead644ee8930a1a3cb872fb9ab2ec27df30e303765a3b70b97852e2e9ee43bdff3 + languageName: node + linkType: hard + +"figures@npm:^2.0.0": + version: 2.0.0 + resolution: "figures@npm:2.0.0" + dependencies: + escape-string-regexp: "npm:^1.0.5" + checksum: 10c0/5dc5a75fec3e7e04ae65d6ce51d28b3e70d4656c51b06996b6fdb2cb5b542df512e3b3c04482f5193a964edddafa5521479ff948fa84e12ff556e53e094ab4ce + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 + languageName: node + linkType: hard + +"find-up@npm:^4.1.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: "npm:^5.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 + languageName: node + linkType: hard + +"follow-redirects@npm:^1.16.0": + version: 1.16.0 + resolution: "follow-redirects@npm:1.16.0" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/a1e2900163e6f1b4d1ed5c221b607f41decbab65534c63fe7e287e40a5d552a6496e7d9d7d976fa4ba77b4c51c11e5e9f683f10b43011ea11e442ff128d0e181 + languageName: node + linkType: hard + +"form-data@npm:^4.0.5": + version: 4.0.5 + resolution: "form-data@npm:4.0.5" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + es-set-tostringtag: "npm:^2.1.0" + hasown: "npm:^2.0.2" + mime-types: "npm:^2.1.12" + checksum: 10c0/dd6b767ee0bbd6d84039db12a0fa5a2028160ffbfaba1800695713b46ae974a5f6e08b3356c3195137f8530dcd9dfcb5d5ae1eeff53d0db1e5aad863b619ce3b + languageName: node + linkType: hard + +"fs-extra@npm:^10.1.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8 + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.1": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + +"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.1, get-east-asian-width@npm:^1.5.0": + version: 1.6.0 + resolution: "get-east-asian-width@npm:1.6.0" + checksum: 10c0/7e72e9550fd49ca5b246f9af6bb2afc129c96412845ff6556b3274fd44817a381702ca17028efe9866b261a3d44254cbf21e6c90cf05b4b61675630af776d431 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.3.0": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d + languageName: node + linkType: hard + +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: "npm:^1.0.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + languageName: node + linkType: hard + +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + +"globby@npm:^11.0.3": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 + languageName: node + linkType: hard + +"globrex@npm:^0.1.2": + version: 0.1.2 + resolution: "globrex@npm:0.1.2" + checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1 + languageName: node + linkType: hard + +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"graphql-query-batcher@npm:^1.0.1": + version: 1.0.1 + resolution: "graphql-query-batcher@npm:1.0.1" + checksum: 10c0/804d0f4064721a2116a16b9eac422e9233e85f4ab5b250cb8f83662725658ffde35779a8ae8211037f3dd2f9717de8cb63b394ad8057ce22171a83db2471196a + languageName: node + linkType: hard + +"graphql-sse@npm:^2.5.4": + version: 2.6.0 + resolution: "graphql-sse@npm:2.6.0" + peerDependencies: + graphql: ">=0.11 <=16" + checksum: 10c0/e05f0b5c8539d61e5ce34af8e0bb418c02bf922d6a7f9232a9abd53c77df5654684ca14f674ac771645c8fba9c37ce666c5d06f46eef54ea07e63653468065b0 + languageName: node + linkType: hard + +"graphql@npm:^16.6.0, graphql@npm:^16.8.1": + version: 16.14.0 + resolution: "graphql@npm:16.14.0" + checksum: 10c0/baaa368fcfeb7bf2cdf94b9f31bf916e97eaa9e7e82148a7046f31cbd49b760b38190f22393b024cbdd9ca0f4f46287515de0136b6a0cc164074b36ad7b50618 + languageName: node + linkType: hard + +"has-ansi@npm:^2.0.0": + version: 2.0.0 + resolution: "has-ansi@npm:2.0.0" + dependencies: + ansi-regex: "npm:^2.0.0" + checksum: 10c0/f54e4887b9f8f3c4bfefd649c48825b3c093987c92c27880ee9898539e6f01aed261e82e73153c3f920fde0db5bf6ebd58deb498ed1debabcb4bc40113ccdf05 + languageName: node + linkType: hard + +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.3 + resolution: "hasown@npm:2.0.3" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/f5eb28c3fd0d3e4facd821c1eeee3836c37b70ab0b0fc532e8a39976e18fef43652415dadc52f8c7a5ff6d5ac93b7bef128789aa6f90f4e9b9a9083dce74ab38 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.1": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 10c0/6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 + languageName: node + linkType: hard + +"indent-string@npm:^3.0.0": + version: 3.2.0 + resolution: "indent-string@npm:3.2.0" + checksum: 10c0/91b6d61621d24944c5c4d365d6f1ff4a490264ccaf1162a602faa0d323e69231db2180ad4ccc092c2f49cf8888cdb3da7b73e904cc0fdeec40d0bfb41ceb9478 + languageName: node + linkType: hard + +"indent-string@npm:^5.0.0": + version: 5.0.0 + resolution: "indent-string@npm:5.0.0" + checksum: 10c0/8ee77b57d92e71745e133f6f444d6fa3ed503ad0e1bcd7e80c8da08b42375c07117128d670589725ed07b1978065803fa86318c309ba45415b7fe13e7f170220 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 + languageName: node + linkType: hard + +"ink@npm:^6.8.0": + version: 6.8.0 + resolution: "ink@npm:6.8.0" + dependencies: + "@alcalzone/ansi-tokenize": "npm:^0.2.4" + ansi-escapes: "npm:^7.3.0" + ansi-styles: "npm:^6.2.1" + auto-bind: "npm:^5.0.1" + chalk: "npm:^5.6.0" + cli-boxes: "npm:^3.0.0" + cli-cursor: "npm:^4.0.0" + cli-truncate: "npm:^5.1.1" + code-excerpt: "npm:^4.0.0" + es-toolkit: "npm:^1.39.10" + indent-string: "npm:^5.0.0" + is-in-ci: "npm:^2.0.0" + patch-console: "npm:^2.0.0" + react-reconciler: "npm:^0.33.0" + scheduler: "npm:^0.27.0" + signal-exit: "npm:^3.0.7" + slice-ansi: "npm:^8.0.0" + stack-utils: "npm:^2.0.6" + string-width: "npm:^8.1.1" + terminal-size: "npm:^4.0.1" + type-fest: "npm:^5.4.1" + widest-line: "npm:^6.0.0" + wrap-ansi: "npm:^9.0.0" + ws: "npm:^8.18.0" + yoga-layout: "npm:~3.2.1" + peerDependencies: + "@types/react": ">=19.0.0" + react: ">=19.0.0" + react-devtools-core: ">=6.1.2" + peerDependenciesMeta: + "@types/react": + optional: true + react-devtools-core: + optional: true + checksum: 10c0/50500e547fdf6a1f1d836d6befbd4770e3ab649ef0be1884500a6da411fb68a90e22dd7dcc9c404911d30e9f87506b3b9d8e997c6c6ceac85ee054b4dadefaff + languageName: node + linkType: hard + +"inquirer@npm:^10.0.0": + version: 10.2.2 + resolution: "inquirer@npm:10.2.2" + dependencies: + "@inquirer/core": "npm:^9.1.0" + "@inquirer/prompts": "npm:^5.5.0" + "@inquirer/type": "npm:^1.5.3" + "@types/mute-stream": "npm:^0.0.4" + ansi-escapes: "npm:^4.3.2" + mute-stream: "npm:^1.0.0" + run-async: "npm:^3.0.0" + rxjs: "npm:^7.8.1" + checksum: 10c0/09bcff887a968ce29d3a8cba749ef35b6531b7fb7bf5b28aaf3e10aebae07af2494dd3ec67ae6f1dabe76da1064cfe4514098d4c7658fcaf3fd480b2975d7163 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^1.0.0": + version: 1.0.0 + resolution: "is-fullwidth-code-point@npm:1.0.0" + dependencies: + number-is-nan: "npm:^1.0.0" + checksum: 10c0/12acfcf16142f2d431bf6af25d68569d3198e81b9799b4ae41058247aafcc666b0127d64384ea28e67a746372611fcbe9b802f69175287aba466da3eddd5ba0f + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^2.0.0": + version: 2.0.0 + resolution: "is-fullwidth-code-point@npm:2.0.0" + checksum: 10c0/e58f3e4a601fc0500d8b2677e26e9fe0cd450980e66adb29d85b6addf7969731e38f8e43ed2ec868a09c101a55ac3d8b78902209269f38c5286bc98f5bc1b4d9 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^5.0.0, is-fullwidth-code-point@npm:^5.1.0": + version: 5.1.0 + resolution: "is-fullwidth-code-point@npm:5.1.0" + dependencies: + get-east-asian-width: "npm:^1.3.1" + checksum: 10c0/c1172c2e417fb73470c56c431851681591f6a17233603a9e6f94b7ba870b2e8a5266506490573b607fb1081318589372034aa436aec07b465c2029c0bc7f07a4 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-in-ci@npm:^2.0.0": + version: 2.0.0 + resolution: "is-in-ci@npm:2.0.0" + bin: + is-in-ci: cli.js + checksum: 10c0/1e1d1056939a681e8206035de5ad84e0404556eaa7622bb55f0f1868b9788bff3df427bc0b1ed5a172623154a90fcb1e759a230817cd73d09435543ae3c71feb + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"is-observable@npm:^1.1.0": + version: 1.1.0 + resolution: "is-observable@npm:1.1.0" + dependencies: + symbol-observable: "npm:^1.1.0" + checksum: 10c0/cf3166b0822f70ad06e7851e09430166ce658349d54aaa64c93a03320420b9285735821b23164bdce741ff83a86730ac3e53035ce4e2511ed843dbff4105bfa2 + languageName: node + linkType: hard + +"is-promise@npm:^2.1.0": + version: 2.2.2 + resolution: "is-promise@npm:2.2.2" + checksum: 10c0/2dba959812380e45b3df0fb12e7cb4d4528c989c7abb03ececb1d1fd6ab1cbfee956ca9daa587b9db1d8ac3c1e5738cf217bdb3dfd99df8c691be4c00ae09069 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 10c0/b8ae7971e78d2e8488d15f804229c6eed7ed36a28f8807a1815938771f4adff0e705218b7dab968270433f67103e4fef98062a0beea55d64835f705ee72c7002 + languageName: node + linkType: hard + +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce + languageName: node + linkType: hard + +"isomorphic-unfetch@npm:^3.0.0": + version: 3.1.0 + resolution: "isomorphic-unfetch@npm:3.1.0" + dependencies: + node-fetch: "npm:^2.6.1" + unfetch: "npm:^4.2.0" + checksum: 10c0/d3b61fca06304db692b7f76bdfd3a00f410e42cfa7403c3b250546bf71589d18cf2f355922f57198e4cc4a9872d3647b20397a5c3edf1a347c90d57c83cf2a89 + languageName: node + linkType: hard + +"iterall@npm:^1.2.1": + version: 1.3.0 + resolution: "iterall@npm:1.3.0" + checksum: 10c0/40de624e5fe937c4c0e511981b91caea9ff2142bfc0316cccc8506eaa03aa253820cc17c5bc5f0a98706c7268a373e5ebee9af9a0c8a359730cf7c05938b57b5 + languageName: node + linkType: hard + +"js-tokens@npm:^9.0.1": + version: 9.0.1 + resolution: "js-tokens@npm:9.0.1" + checksum: 10c0/68dcab8f233dde211a6b5fd98079783cbcd04b53617c1250e3553ee16ab3e6134f5e65478e41d82f6d351a052a63d71024553933808570f04dbf828d7921e80e + languageName: node + linkType: hard + +"jsonc-parser@npm:^3.2.0": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 10c0/269c3ae0a0e4f907a914bf334306c384aabb9929bd8c99f909275ebd5c2d3bc70b9bcd119ad794f339dec9f24b6a4ee9cd5a8ab2e6435e730ad4075388fc2ab6 + languageName: node + linkType: hard + +"jsonfile@npm:^6.0.1": + version: 6.2.1 + resolution: "jsonfile@npm:6.2.1" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/e1abf000ecee9942d4d028a8e02dc752617face227d72afd1cfb2187e2433079e625bf82b807a313689db71b6472c6b2b389a2340d2798737b1199a39631c28a + languageName: node + linkType: hard + +"kleur@npm:^4.1.5": + version: 4.1.5 + resolution: "kleur@npm:4.1.5" + checksum: 10c0/e9de6cb49657b6fa70ba2d1448fd3d691a5c4370d8f7bbf1c2f64c24d461270f2117e1b0afe8cb3114f13bbd8e51de158c2a224953960331904e636a5e4c0f2a + languageName: node + linkType: hard + +"listr-silent-renderer@npm:^1.1.1": + version: 1.1.1 + resolution: "listr-silent-renderer@npm:1.1.1" + checksum: 10c0/a13e08ebf863516a757bce4887f05290070772113d89095e9f51a07cf0b11a43a7563a67ff3b287c752c08f6d781fdb2123b02957534e3e0675fb564f2a42e1b + languageName: node + linkType: hard + +"listr-update-renderer@npm:^0.5.0": + version: 0.5.0 + resolution: "listr-update-renderer@npm:0.5.0" + dependencies: + chalk: "npm:^1.1.3" + cli-truncate: "npm:^0.2.1" + elegant-spinner: "npm:^1.0.1" + figures: "npm:^1.7.0" + indent-string: "npm:^3.0.0" + log-symbols: "npm:^1.0.2" + log-update: "npm:^2.3.0" + strip-ansi: "npm:^3.0.1" + peerDependencies: + listr: ^0.14.2 + checksum: 10c0/8ade44bf3dc6146c8e0178000619439e8889792c4689b66be6ce82bd459f5fe462ecb34b05147fb206a8ad60e6d4e6f34c9f48038e18366f867fd972688b8edc + languageName: node + linkType: hard + +"listr-verbose-renderer@npm:^0.5.0": + version: 0.5.0 + resolution: "listr-verbose-renderer@npm:0.5.0" + dependencies: + chalk: "npm:^2.4.1" + cli-cursor: "npm:^2.1.0" + date-fns: "npm:^1.27.2" + figures: "npm:^2.0.0" + checksum: 10c0/041cd1e82da7054f27ae0a914e98b40d15faf9f950ef850578fc6241d3fff3c2d7158a4f6226006e566b4c47bf445be2d254dd1ce5c16569a3a5dcd575bec656 + languageName: node + linkType: hard + +"listr@npm:^0.14.3": + version: 0.14.3 + resolution: "listr@npm:0.14.3" + dependencies: + "@samverschueren/stream-to-observable": "npm:^0.3.0" + is-observable: "npm:^1.1.0" + is-promise: "npm:^2.1.0" + is-stream: "npm:^1.1.0" + listr-silent-renderer: "npm:^1.1.1" + listr-update-renderer: "npm:^0.5.0" + listr-verbose-renderer: "npm:^0.5.0" + p-map: "npm:^2.0.0" + rxjs: "npm:^6.3.3" + checksum: 10c0/753d518218c423f46bee8eeacccecadfd2e414ba9c0f602e7f85fe3f6fa18404dfab0812433aeda4683ee2548358488f597ac1a3d321196baec5d3149b200b10 + languageName: node + linkType: hard + +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: "npm:^4.1.0" + checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 + languageName: node + linkType: hard + +"lodash@npm:^4.17.20, lodash@npm:^4.17.21": + version: 4.18.1 + resolution: "lodash@npm:4.18.1" + checksum: 10c0/757228fc68805c59789e82185135cf85f05d0b2d3d54631d680ca79ec21944ec8314d4533639a14b8bcfbd97a517e78960933041a5af17ecb693ec6eecb99a27 + languageName: node + linkType: hard + +"log-symbols@npm:^1.0.2": + version: 1.0.2 + resolution: "log-symbols@npm:1.0.2" + dependencies: + chalk: "npm:^1.0.0" + checksum: 10c0/c64e1fe41d0d043840f8b592d043b8607a836b846506f525a53d99d578561f02f97b2cba1d2b3c30bae5311d64b308d5a392a9930d252b906a9042fc2877da7a + languageName: node + linkType: hard + +"log-update@npm:^2.3.0": + version: 2.3.0 + resolution: "log-update@npm:2.3.0" + dependencies: + ansi-escapes: "npm:^3.0.0" + cli-cursor: "npm:^2.0.0" + wrap-ansi: "npm:^3.0.1" + checksum: 10c0/9bf21b138801ab4770a2bfa735161cf005b869360eaf5003a84ba64ddc5f5c3ce7217f4f1fa79d9c1f510d792213b2c9800327228e94df05859d19b716215d90 + languageName: node + linkType: hard + +"loupe@npm:^3.1.0, loupe@npm:^3.1.4": + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 10c0/910c872cba291309664c2d094368d31a68907b6f5913e989d301b5c25f30e97d76d77f23ab3bf3b46d0f601ff0b6af8810c10c31b91d2c6b2f132809ca2cc705 + languageName: node + linkType: hard + +"magic-string@npm:^0.30.17": + version: 0.30.21 + resolution: "magic-string@npm:0.30.21" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10c0/299378e38f9a270069fc62358522ddfb44e94244baa0d6a8980ab2a9b2490a1d03b236b447eee309e17eb3bddfa482c61259d47960eb018a904f0ded52780c4a + languageName: node + linkType: hard + +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f + languageName: node + linkType: hard + +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb + languageName: node + linkType: hard + +"micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + +"mimic-fn@npm:^1.0.0": + version: 1.2.0 + resolution: "mimic-fn@npm:1.2.0" + checksum: 10c0/ad55214aec6094c0af4c0beec1a13787556f8116ed88807cf3f05828500f21f93a9482326bcd5a077ae91e3e8795b4e76b5b4c8bb12237ff0e4043a365516cba + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4 + languageName: node + linkType: hard + +"minimatch@npm:^3.1.1": + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70 + languageName: node + linkType: hard + +"minimist@npm:^1.2.6": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 + languageName: node + linkType: hard + +"minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb + languageName: node + linkType: hard + +"minizlib@npm:^3.1.0": + version: 3.1.0 + resolution: "minizlib@npm:3.1.0" + dependencies: + minipass: "npm:^7.1.2" + checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec + languageName: node + linkType: hard + +"mkdirp@npm:^0.5.1": + version: 0.5.6 + resolution: "mkdirp@npm:0.5.6" + dependencies: + minimist: "npm:^1.2.6" + bin: + mkdirp: bin/cmd.js + checksum: 10c0/e2e2be789218807b58abced04e7b49851d9e46e88a2f9539242cc8a92c9b5c3a0b9bab360bd3014e02a140fc4fbc58e31176c408b493f8a2a6f4986bd7527b01 + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"mute-stream@npm:^1.0.0": + version: 1.0.0 + resolution: "mute-stream@npm:1.0.0" + checksum: 10c0/dce2a9ccda171ec979a3b4f869a102b1343dee35e920146776780de182f16eae459644d187e38d59a3d37adf85685e1c17c38cf7bfda7e39a9880f7a1d10a74c + languageName: node + linkType: hard + +"nanoid@npm:^3.3.11": + version: 3.3.12 + resolution: "nanoid@npm:3.3.12" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/ba142b7b39e11e80c16dd74b0365d407880c87c1cf7e1480956981ae940ee36060fa5b6f092cd1e315184dd19244c657bd017d03327bd3c62247d691c5e8edfb + languageName: node + linkType: hard + +"native-fetch@npm:^4.0.2": + version: 4.0.2 + resolution: "native-fetch@npm:4.0.2" + peerDependencies: + undici: "*" + checksum: 10c0/e3b824721daaa628086d9dcd02e8eb12f0a6c5e13a1d182682bae238d80c9bbf3dfd6314a94692ebe20316aa354476804b4df148201d066b46fc552a5794cfab + languageName: node + linkType: hard + +"node-fetch@npm:^2.6.1": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 12.3.0 + resolution: "node-gyp@npm:12.3.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + graceful-fs: "npm:^4.2.6" + nopt: "npm:^9.0.0" + proc-log: "npm:^6.0.0" + semver: "npm:^7.3.5" + tar: "npm:^7.5.4" + tinyglobby: "npm:^0.2.12" + undici: "npm:^6.25.0" + which: "npm:^6.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/9d9032b405cbe42f72a105259d9eb679376470c102df4a2dbaa51e07d59bf741dcffb85897087ea9d8318b9cabb824a8978af51508ae142f0239ae1e6a3c2329 + languageName: node + linkType: hard + +"nopt@npm:^9.0.0": + version: 9.0.0 + resolution: "nopt@npm:9.0.0" + dependencies: + abbrev: "npm:^4.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd + languageName: node + linkType: hard + +"normalize-path@npm:^2.1.1": + version: 2.1.1 + resolution: "normalize-path@npm:2.1.1" + dependencies: + remove-trailing-separator: "npm:^1.0.1" + checksum: 10c0/db814326ff88057437233361b4c7e9cac7b54815b051b57f2d341ce89b1d8ec8cbd43e7fa95d7652b3b69ea8fcc294b89b8530d556a84d1bdace94229e1e9a8b + languageName: node + linkType: hard + +"number-is-nan@npm:^1.0.0": + version: 1.0.1 + resolution: "number-is-nan@npm:1.0.1" + checksum: 10c0/cb97149006acc5cd512c13c1838223abdf202e76ddfa059c5e8e7507aff2c3a78cd19057516885a2f6f5b576543dc4f7b6f3c997cc7df53ae26c260855466df5 + languageName: node + linkType: hard + +"object-assign@npm:^4.1.0": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 + languageName: node + linkType: hard + +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10c0/d7f8711e803b96ea3191c745d6f8056ce1f2496e530e6a19a0e92d89b0fa3c76d910c31f0aa270432db6bd3b2f85500a376a83aaba849a8d518c8845b3211692 + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"onetime@npm:^2.0.0": + version: 2.0.1 + resolution: "onetime@npm:2.0.1" + dependencies: + mimic-fn: "npm:^1.0.0" + checksum: 10c0/b4e44a8c34e70e02251bfb578a6e26d6de6eedbed106cd78211d2fd64d28b6281d54924696554e4e966559644243753ac5df73c87f283b0927533d3315696215 + languageName: node + linkType: hard + +"onetime@npm:^5.1.0": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f + languageName: node + linkType: hard + +"os-tmpdir@npm:~1.0.2": + version: 1.0.2 + resolution: "os-tmpdir@npm:1.0.2" + checksum: 10c0/f438450224f8e2687605a8dd318f0db694b6293c5d835ae509a69e97c8de38b6994645337e5577f5001115470414638978cc49da1cdcc25106dad8738dc69990 + languageName: node + linkType: hard + +"oxlint@npm:^0.16.0": + version: 0.16.12 + resolution: "oxlint@npm:0.16.12" + dependencies: + "@oxlint/darwin-arm64": "npm:0.16.12" + "@oxlint/darwin-x64": "npm:0.16.12" + "@oxlint/linux-arm64-gnu": "npm:0.16.12" + "@oxlint/linux-arm64-musl": "npm:0.16.12" + "@oxlint/linux-x64-gnu": "npm:0.16.12" + "@oxlint/linux-x64-musl": "npm:0.16.12" + "@oxlint/win32-arm64": "npm:0.16.12" + "@oxlint/win32-x64": "npm:0.16.12" + dependenciesMeta: + "@oxlint/darwin-arm64": + optional: true + "@oxlint/darwin-x64": + optional: true + "@oxlint/linux-arm64-gnu": + optional: true + "@oxlint/linux-arm64-musl": + optional: true + "@oxlint/linux-x64-gnu": + optional: true + "@oxlint/linux-x64-musl": + optional: true + "@oxlint/win32-arm64": + optional: true + "@oxlint/win32-x64": + optional: true + bin: + oxc_language_server: bin/oxc_language_server + oxlint: bin/oxlint + checksum: 10c0/209c3484039c4f1fdd340689e81be93a70fdf74e8c111731e70d81580d223b0029439107c95fa4118cec3c9b03ba6c56624d3dcb8cdc79af222da3561122b3e7 + languageName: node + linkType: hard + +"p-limit@npm:3.1.0": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a + languageName: node + linkType: hard + +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: "npm:^2.0.0" + checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12 + languageName: node + linkType: hard + +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: "npm:^2.2.0" + checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 + languageName: node + linkType: hard + +"p-map@npm:^2.0.0": + version: 2.1.0 + resolution: "p-map@npm:2.1.0" + checksum: 10c0/735dae87badd4737a2dd582b6d8f93e49a1b79eabbc9815a4d63a528d5e3523e978e127a21d784cccb637010e32103a40d2aaa3ab23ae60250b1a820ca752043 + languageName: node + linkType: hard + +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f + languageName: node + linkType: hard + +"patch-console@npm:^2.0.0": + version: 2.0.0 + resolution: "patch-console@npm:2.0.0" + checksum: 10c0/486602591a0af7af8d4c76d8eea42cad32b6de7200488819c6383c75e43733ca7bdc80e30f2e68ce05f06a1607cce1683a1706c6672ca27dada1921b366e8f1c + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 + languageName: node + linkType: hard + +"pathval@npm:^2.0.0": + version: 2.0.1 + resolution: "pathval@npm:2.0.1" + checksum: 10c0/460f4709479fbf2c45903a65655fc8f0a5f6d808f989173aeef5fdea4ff4f303dc13f7870303999add60ec49d4c14733895c0a869392e9866f1091fa64fd7581 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.2 + resolution: "picomatch@npm:2.3.2" + checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3, picomatch@npm:^4.0.4": + version: 4.0.4 + resolution: "picomatch@npm:4.0.4" + checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 + languageName: node + linkType: hard + +"postcss@npm:^8.5.6": + version: 8.5.14 + resolution: "postcss@npm:8.5.14" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/48138207cf5ef5581be1bfe2cb65ccfe0ac75e43888ba045afc8ed6043d7b56aeb3b9a9fe5b353ff554be943cd0cc15d826ccb991525159175971e5ee8ab0237 + languageName: node + linkType: hard + +"preact@npm:^10.28.3": + version: 10.29.1 + resolution: "preact@npm:10.29.1" + checksum: 10c0/55da3994d0d9ebcc26476552c6571f8be1150cccdafe842aad40eff9abc84c867555f6d01db386fc63ac4cbe9f9da245002468bb24df0642365162d8f1b545e2 + languageName: node + linkType: hard + +"prettier@npm:^2.8.0": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: 10c0/463ea8f9a0946cd5b828d8cf27bd8b567345cf02f56562d5ecde198b91f47a76b7ac9eae0facd247ace70e927143af6135e8cf411986b8cb8478784a4d6d724a + languageName: node + linkType: hard + +"proc-log@npm:^6.0.0": + version: 6.1.0 + resolution: "proc-log@npm:6.1.0" + checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82 + languageName: node + linkType: hard + +"proxy-from-env@npm:^2.1.0": + version: 2.1.0 + resolution: "proxy-from-env@npm:2.1.0" + checksum: 10c0/ed01729fd4d094eab619cd7e17ce3698b3413b31eb102c4904f9875e677cd207392795d5b4adee9cec359dfd31c44d5ad7595a3a3ad51c40250e141512281c58 + languageName: node + linkType: hard + +"qs@npm:^6.11.0": + version: 6.15.1 + resolution: "qs@npm:6.15.1" + dependencies: + side-channel: "npm:^1.1.0" + checksum: 10c0/19ee504f0ebff72598503e38cd6d9bd7b52a8ab62ae18b1e6bee3d4db58469bd65871ef1893a881bafb0f80ef2f9ab586e1f255cf25cc8d816c0f5a704721d97 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 + languageName: node + linkType: hard + +"react-dom@npm:^19.0.0": + version: 19.2.6 + resolution: "react-dom@npm:19.2.6" + dependencies: + scheduler: "npm:^0.27.0" + peerDependencies: + react: ^19.2.6 + checksum: 10c0/dbf2aef67857c03a612bc9316a4562e5066f43fa04bf28f7f0734963fc1350da2c9f8eb973930655453281079f30cc8222bab383dbec4b5097084e2c081e3334 + languageName: node + linkType: hard + +"react-reconciler@npm:^0.33.0": + version: 0.33.0 + resolution: "react-reconciler@npm:0.33.0" + dependencies: + scheduler: "npm:^0.27.0" + peerDependencies: + react: ^19.2.0 + checksum: 10c0/3f7b27ea8d0ff4c8bf0e402a285e1af9b7d0e6f4c1a70a28f4384938bc1130bc82a90a31df0b79ef5e380e2e55e2598bd90b4dbf802b1203d735ba0355817d3a + languageName: node + linkType: hard + +"react@npm:^19.0.0": + version: 19.2.6 + resolution: "react@npm:19.2.6" + checksum: 10c0/66afde33b9a9ee87b1e1cae39d8e7e040d1262e719524fd70660c4d4ce79929c532ac19fc3df5a911edaf02768fdf2c49de4ede1ba99bc6aad72796e0e26e798 + languageName: node + linkType: hard + +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 10c0/60a14f7619dec48c9c850255cd523e2717001b0e179dc7037cfa0895da7b9e9ab07532d324bfb118d73a710887d1e35f79c495fa91582784493e085d18c72c62 + languageName: node + linkType: hard + +"remove-trailing-separator@npm:^1.0.1": + version: 1.1.0 + resolution: "remove-trailing-separator@npm:1.1.0" + checksum: 10c0/3568f9f8f5af3737b4aee9e6e1e8ec4be65a92da9cb27f989e0893714d50aa95ed2ff02d40d1fa35e1b1a234dc9c2437050ef356704a3999feaca6667d9e9bfc + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + +"require-main-filename@npm:^2.0.0": + version: 2.0.0 + resolution: "require-main-filename@npm:2.0.0" + checksum: 10c0/db91467d9ead311b4111cbd73a4e67fa7820daed2989a32f7023785a2659008c6d119752d9c4ac011ae07e537eb86523adff99804c5fdb39cd3a017f9b401bb6 + languageName: node + linkType: hard + +"resolve-from@npm:5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 + languageName: node + linkType: hard + +"restore-cursor@npm:^2.0.0": + version: 2.0.0 + resolution: "restore-cursor@npm:2.0.0" + dependencies: + onetime: "npm:^2.0.0" + signal-exit: "npm:^3.0.2" + checksum: 10c0/f5b335bee06f440445e976a7031a3ef53691f9b7c4a9d42a469a0edaf8a5508158a0d561ff2b26a1f4f38783bcca2c0e5c3a44f927326f6694d5b44d7a4993e6 + languageName: node + linkType: hard + +"restore-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "restore-cursor@npm:4.0.0" + dependencies: + onetime: "npm:^5.1.0" + signal-exit: "npm:^3.0.2" + checksum: 10c0/6f7da8c5e422ac26aa38354870b1afac09963572cf2879443540449068cb43476e9cbccf6f8de3e0171e0d6f7f533c2bc1a0a008003c9a525bbc098e89041318 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.1.0 + resolution: "reusify@npm:1.1.0" + checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa + languageName: node + linkType: hard + +"rimraf@npm:^2.6.3": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: ./bin.js + checksum: 10c0/4eef73d406c6940927479a3a9dee551e14a54faf54b31ef861250ac815172bade86cc6f7d64a4dc5e98b65e4b18a2e1c9ff3b68d296be0c748413f092bb0dd40 + languageName: node + linkType: hard + +"rollup@npm:^4.43.0": + version: 4.60.4 + resolution: "rollup@npm:4.60.4" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.60.4" + "@rollup/rollup-android-arm64": "npm:4.60.4" + "@rollup/rollup-darwin-arm64": "npm:4.60.4" + "@rollup/rollup-darwin-x64": "npm:4.60.4" + "@rollup/rollup-freebsd-arm64": "npm:4.60.4" + "@rollup/rollup-freebsd-x64": "npm:4.60.4" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.60.4" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.60.4" + "@rollup/rollup-linux-arm64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-arm64-musl": "npm:4.60.4" + "@rollup/rollup-linux-loong64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-loong64-musl": "npm:4.60.4" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-ppc64-musl": "npm:4.60.4" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-riscv64-musl": "npm:4.60.4" + "@rollup/rollup-linux-s390x-gnu": "npm:4.60.4" + "@rollup/rollup-linux-x64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-x64-musl": "npm:4.60.4" + "@rollup/rollup-openbsd-x64": "npm:4.60.4" + "@rollup/rollup-openharmony-arm64": "npm:4.60.4" + "@rollup/rollup-win32-arm64-msvc": "npm:4.60.4" + "@rollup/rollup-win32-ia32-msvc": "npm:4.60.4" + "@rollup/rollup-win32-x64-gnu": "npm:4.60.4" + "@rollup/rollup-win32-x64-msvc": "npm:4.60.4" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-loong64-musl": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-musl": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openbsd-x64": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-gnu": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/2734511579da220408eefb877b51281767d790652cee25da8fcd4936c947e3db14882b5edb1d0d5d5bf60f2a71a58ae7d5f7f46c11e3fdf33182538953886243 + languageName: node + linkType: hard + +"run-async@npm:^3.0.0": + version: 3.0.0 + resolution: "run-async@npm:3.0.0" + checksum: 10c0/b18b562ae37c3020083dcaae29642e4cc360c824fbfb6b7d50d809a9d5227bb986152d09310255842c8dce40526e82ca768f02f00806c91ba92a8dfa6159cb85 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + languageName: node + linkType: hard + +"rxjs@npm:^6.3.3": + version: 6.6.7 + resolution: "rxjs@npm:6.6.7" + dependencies: + tslib: "npm:^1.9.0" + checksum: 10c0/e556a13a9aa89395e5c9d825eabcfa325568d9c9990af720f3f29f04a888a3b854f25845c2b55875d875381abcae2d8100af9cacdc57576e7ed6be030a01d2fe + languageName: node + linkType: hard + +"rxjs@npm:^7.8.1": + version: 7.8.2 + resolution: "rxjs@npm:7.8.2" + dependencies: + tslib: "npm:^2.1.0" + checksum: 10c0/1fcd33d2066ada98ba8f21fcbbcaee9f0b271de1d38dc7f4e256bfbc6ffcdde68c8bfb69093de7eeb46f24b1fb820620bf0223706cff26b4ab99a7ff7b2e2c45 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 + languageName: node + linkType: hard + +"semver@npm:^7.3.5": + version: 7.8.0 + resolution: "semver@npm:7.8.0" + bin: + semver: bin/semver.js + checksum: 10c0/8f096ca9b80ffd47b308d03f9ce8c873e27e2983f36023c559cdc92c51e8433fc23ebbfe57ec9623fc155636a6961ee989501099841ae4bb1babc8d2b3f048cd + languageName: node + linkType: hard + +"set-blocking@npm:^2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454 + languageName: node + linkType: hard + +"side-channel-list@npm:^1.0.0": + version: 1.0.1 + resolution: "side-channel-list@npm:1.0.1" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.4" + checksum: 10c0/d346c787fd2f9f1c2fdea14f00e8250118db0e7596d85a6cb9faa75f105d31a73a8f7a341c93d7df2a2429098c3d37a77bd3be9e88c37094b8c01807bc77c7a2 + languageName: node + linkType: hard + +"side-channel-map@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-map@npm:1.0.1" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + checksum: 10c0/010584e6444dd8a20b85bc926d934424bd809e1a3af941cace229f7fdcb751aada0fb7164f60c2e22292b7fa3c0ff0bce237081fd4cdbc80de1dc68e95430672 + languageName: node + linkType: hard + +"side-channel-weakmap@npm:^1.0.2": + version: 1.0.2 + resolution: "side-channel-weakmap@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + side-channel-map: "npm:^1.0.1" + checksum: 10c0/71362709ac233e08807ccd980101c3e2d7efe849edc51455030327b059f6c4d292c237f94dc0685031dd11c07dd17a68afde235d6cf2102d949567f98ab58185 + languageName: node + linkType: hard + +"side-channel@npm:^1.1.0": + version: 1.1.0 + resolution: "side-channel@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.3" + side-channel-list: "npm:^1.0.0" + side-channel-map: "npm:^1.0.1" + side-channel-weakmap: "npm:^1.0.2" + checksum: 10c0/cb20dad41eb032e6c24c0982e1e5a24963a28aa6122b4f05b3f3d6bf8ae7fd5474ef382c8f54a6a3ab86e0cac4d41a23bd64ede3970e5bfb50326ba02a7996e6 + languageName: node + linkType: hard + +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.7": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 + languageName: node + linkType: hard + +"signal-exit@npm:^4.1.0": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b + languageName: node + linkType: hard + +"slice-ansi@npm:0.0.4": + version: 0.0.4 + resolution: "slice-ansi@npm:0.0.4" + checksum: 10c0/997d4cc73e34aa8c0f60bdb71701b16c062cc4acd7a95e3b10e8c05d790eb5e735d9b470270dc6f443b1ba21492db7ceb849d5c93011d1256061bf7ed7216c7a + languageName: node + linkType: hard + +"slice-ansi@npm:^8.0.0": + version: 8.0.0 + resolution: "slice-ansi@npm:8.0.0" + dependencies: + ansi-styles: "npm:^6.2.3" + is-fullwidth-code-point: "npm:^5.1.0" + checksum: 10c0/0ce4aa91febb7cea4a00c2c27bb820fa53b6d2862ce0f80f7120134719f7914fc416b0ed966cf35250a3169e152916392f35917a2d7cad0fcc5d8b841010fa9a + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf + languageName: node + linkType: hard + +"stack-utils@npm:^2.0.6": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a + languageName: node + linkType: hard + +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + +"std-env@npm:^3.9.0": + version: 3.10.0 + resolution: "std-env@npm:3.10.0" + checksum: 10c0/1814927a45004d36dde6707eaf17552a546769bc79a6421be2c16ce77d238158dfe5de30910b78ec30d95135cc1c59ea73ee22d2ca170f8b9753f84da34c427f + languageName: node + linkType: hard + +"string-width@npm:^1.0.1": + version: 1.0.2 + resolution: "string-width@npm:1.0.2" + dependencies: + code-point-at: "npm:^1.0.0" + is-fullwidth-code-point: "npm:^1.0.0" + strip-ansi: "npm:^3.0.0" + checksum: 10c0/c558438baed23a9ab9370bb6a939acbdb2b2ffc517838d651aad0f5b2b674fb85d460d9b1d0b6a4c210dffd09e3235222d89a5bd4c0c1587f78b2bb7bc00c65e + languageName: node + linkType: hard + +"string-width@npm:^2.1.1": + version: 2.1.1 + resolution: "string-width@npm:2.1.1" + dependencies: + is-fullwidth-code-point: "npm:^2.0.0" + strip-ansi: "npm:^4.0.0" + checksum: 10c0/e5f2b169fcf8a4257a399f95d069522f056e92ec97dbdcb9b0cdf14d688b7ca0b1b1439a1c7b9773cd79446cbafd582727279d6bfdd9f8edd306ea5e90e5b610 + languageName: node + linkType: hard + +"string-width@npm:^4.1.0, string-width@npm:^4.2.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^7.0.0": + version: 7.2.0 + resolution: "string-width@npm:7.2.0" + dependencies: + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 + languageName: node + linkType: hard + +"string-width@npm:^8.1.0, string-width@npm:^8.1.1, string-width@npm:^8.2.0": + version: 8.2.1 + resolution: "string-width@npm:8.2.1" + dependencies: + get-east-asian-width: "npm:^1.5.0" + strip-ansi: "npm:^7.1.2" + checksum: 10c0/d467b4eaf4c40a01bb438a2620e77badd2456ffd5131c9973abe4f3acf7c802d5b21f3b6a00a5e33a7fc28ca8f9c103226e01bac61e9f259659c6f46d78e353a + languageName: node + linkType: hard + +"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": + version: 3.0.1 + resolution: "strip-ansi@npm:3.0.1" + dependencies: + ansi-regex: "npm:^2.0.0" + checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f + languageName: node + linkType: hard + +"strip-ansi@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-ansi@npm:4.0.0" + dependencies: + ansi-regex: "npm:^3.0.0" + checksum: 10c0/d75d9681e0637ea316ddbd7d4d3be010b1895a17e885155e0ed6a39755ae0fd7ef46e14b22162e66a62db122d3a98ab7917794e255532ab461bb0a04feb03e7d + languageName: node + linkType: hard + +"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.1.0, strip-ansi@npm:^7.1.2": + version: 7.2.0 + resolution: "strip-ansi@npm:7.2.0" + dependencies: + ansi-regex: "npm:^6.2.2" + checksum: 10c0/544d13b7582f8254811ea97db202f519e189e59d35740c46095897e254e4f1aa9fe1524a83ad6bc5ad67d4dd6c0281d2e0219ed62b880a6238a16a17d375f221 + languageName: node + linkType: hard + +"strip-literal@npm:^3.0.0": + version: 3.1.0 + resolution: "strip-literal@npm:3.1.0" + dependencies: + js-tokens: "npm:^9.0.1" + checksum: 10c0/50918f669915d9ad0fe4b7599902b735f853f2201c97791ead00104a654259c0c61bc2bc8fa3db05109339b61f4cf09e47b94ecc874ffbd0e013965223893af8 + languageName: node + linkType: hard + +"subscriptions-transport-ws@npm:^0.9.16": + version: 0.9.19 + resolution: "subscriptions-transport-ws@npm:0.9.19" + dependencies: + backo2: "npm:^1.0.2" + eventemitter3: "npm:^3.1.0" + iterall: "npm:^1.2.1" + symbol-observable: "npm:^1.0.4" + ws: "npm:^5.2.0 || ^6.0.0 || ^7.0.0" + peerDependencies: + graphql: ">=0.10.0" + checksum: 10c0/6f2ade56865f0ba291d3ff82c79781b051c2374873bac853286fedfdbc05001b8c4018ab7cba44af667ead7f573e48d18892d58a8f9ca8d90dfb4bff5c125045 + languageName: node + linkType: hard + +"supports-color@npm:^2.0.0": + version: 2.0.0 + resolution: "supports-color@npm:2.0.0" + checksum: 10c0/570e0b63be36cccdd25186350a6cb2eaad332a95ff162fa06d9499982315f2fe4217e69dd98e862fbcd9c81eaff300a825a1fe7bf5cc752e5b84dfed042b0dda + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + +"symbol-observable@npm:^1.0.4, symbol-observable@npm:^1.1.0": + version: 1.2.0 + resolution: "symbol-observable@npm:1.2.0" + checksum: 10c0/009fee50798ef80ed4b8195048288f108b03de162db07493f2e1fd993b33fafa72d659e832b584da5a2427daa78e5a738fb2a9ab027ee9454252e0bedbcd1fdc + languageName: node + linkType: hard + +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1 + languageName: node + linkType: hard + +"tar@npm:^7.5.4": + version: 7.5.15 + resolution: "tar@npm:7.5.15" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.1.0" + yallist: "npm:^5.0.0" + checksum: 10c0/8f039edb1d12fdd7df6c6f9877d125afe9f3da3f5f9317df326fdd090d48793d6998cede1506a1471f3e3a250db270a89dace28005eb5e99c5a9132d704ac956 + languageName: node + linkType: hard + +"terminal-size@npm:^4.0.1": + version: 4.0.1 + resolution: "terminal-size@npm:4.0.1" + checksum: 10c0/89afd9d816dd9dbfe4499da9aeea70491bbde4ff4592226a9c8ac71074a7580afead6a78e95ecc35f6d42e09087b55ffcb1019302cd55e0cc957b6ce5c4847e8 + languageName: node + linkType: hard + +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.16 + resolution: "tinyglobby@npm:0.2.16" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10c0/f2e09fd93dd95c41e522113b686ff6f7c13020962f8698a864a257f3d7737599afc47722b7ab726e12f8a813f779906187911ff8ee6701ede65072671a7e934b + languageName: node + linkType: hard + +"tinypool@npm:^1.1.1": + version: 1.1.1 + resolution: "tinypool@npm:1.1.1" + checksum: 10c0/bf26727d01443061b04fa863f571016950888ea994ba0cd8cba3a1c51e2458d84574341ab8dbc3664f1c3ab20885c8cf9ff1cc4b18201f04c2cde7d317fff69b + languageName: node + linkType: hard + +"tinyrainbow@npm:^2.0.0": + version: 2.0.0 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 10c0/c83c52bef4e0ae7fb8ec6a722f70b5b6fa8d8be1c85792e829f56c0e1be94ab70b293c032dc5048d4d37cfe678f1f5babb04bdc65fd123098800148ca989184f + languageName: node + linkType: hard + +"tinyspy@npm:^4.0.3": + version: 4.0.4 + resolution: "tinyspy@npm:4.0.4" + checksum: 10c0/a8020fc17799251e06a8398dcc352601d2770aa91c556b9531ecd7a12581161fd1c14e81cbdaff0c1306c93bfdde8ff6d1c1a3f9bbe6d91604f0fd4e01e2f1eb + languageName: node + linkType: hard + +"tmp@npm:^0.0.33": + version: 0.0.33 + resolution: "tmp@npm:0.0.33" + dependencies: + os-tmpdir: "npm:~1.0.2" + checksum: 10c0/69863947b8c29cabad43fe0ce65cec5bb4b481d15d4b4b21e036b060b3edbf3bc7a5541de1bacb437bb3f7c4538f669752627fdf9b4aaf034cebd172ba373408 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"tr46@npm:~0.0.3": + version: 0.0.3 + resolution: "tr46@npm:0.0.3" + checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11 + languageName: node + linkType: hard + +"tsconfck@npm:^3.0.3": + version: 3.1.6 + resolution: "tsconfck@npm:3.1.6" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + bin: + tsconfck: bin/tsconfck.js + checksum: 10c0/269c3c513540be44844117bb9b9258fe6f8aeab026d32aeebf458d5299125f330711429dbb556dbf125a0bc25f4a81e6c24ac96de2740badd295c3fb400f66c4 + languageName: node + linkType: hard + +"tslib@npm:^1.9.0, tslib@npm:^1.9.3": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + +"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.4.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + +"tsx@npm:^4.0.0": + version: 4.22.2 + resolution: "tsx@npm:4.22.2" + dependencies: + esbuild: "npm:~0.28.0" + fsevents: "npm:~2.3.3" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 10c0/5e9a9b5577642b6084bac14450379bdb72567a9bf47b3508470f3ccd530693358ab0c5eb86c57c249260f2ffa0549e2e4cedc93cbe526bbae5ef4d215e1d57a3 + languageName: node + linkType: hard + +"twenty-client-sdk@npm:2.4.0": + version: 2.4.0 + resolution: "twenty-client-sdk@npm:2.4.0" + dependencies: + "@genql/cli": "npm:^3.0.3" + "@genql/runtime": "npm:^2.10.0" + esbuild: "npm:^0.25.0" + graphql: "npm:^16.8.1" + checksum: 10c0/cdd9e70a59b8ce16f40e84b79c16e89b984dfcbb04e4646341fea40911acee8eab5aa61872421f25212949e677a75ed51af99e61829f2902af0f0a10e6e5614d + languageName: node + linkType: hard + +"twenty-partners@workspace:.": + version: 0.0.0-use.local + resolution: "twenty-partners@workspace:." + dependencies: + "@types/node": "npm:^24.7.2" + "@types/react": "npm:^19.0.0" + dotenv: "npm:^16.0.0" + oxlint: "npm:^0.16.0" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" + tsx: "npm:^4.0.0" + twenty-client-sdk: "npm:2.4.0" + twenty-sdk: "npm:2.4.0" + typescript: "npm:^5.9.3" + vite-tsconfig-paths: "npm:^4.2.1" + vitest: "npm:^3.1.1" + languageName: unknown + linkType: soft + +"twenty-sdk@npm:2.4.0": + version: 2.4.0 + resolution: "twenty-sdk@npm:2.4.0" + dependencies: + "@genql/cli": "npm:^3.0.3" + "@genql/runtime": "npm:^2.10.0" + "@sniptt/guards": "npm:^0.2.0" + axios: "npm:^1.13.5" + chalk: "npm:^5.3.0" + chokidar: "npm:^4.0.0" + commander: "npm:^12.0.0" + dotenv: "npm:^16.4.0" + esbuild: "npm:^0.25.0" + graphql: "npm:^16.8.1" + graphql-sse: "npm:^2.5.4" + ink: "npm:^6.8.0" + inquirer: "npm:^10.0.0" + jsonc-parser: "npm:^3.2.0" + preact: "npm:^10.28.3" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" + tinyglobby: "npm:^0.2.15" + twenty-client-sdk: "npm:2.4.0" + typescript: "npm:^5.9.2" + uuid: "npm:^13.0.0" + vite: "npm:^7.0.0" + vite-tsconfig-paths: "npm:^4.2.1" + zod: "npm:^4.1.11" + bin: + twenty: dist/cli.cjs + checksum: 10c0/7266755dd0f192f0107b25b72db7340a8476f4b97f3e8d2fa539010f6702f9104463da8ddca9318b2e7df2d6be43362be5eddb95af2067d8863578907b713617 + languageName: node + linkType: hard + +"type-fest@npm:^0.21.3": + version: 0.21.3 + resolution: "type-fest@npm:0.21.3" + checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8 + languageName: node + linkType: hard + +"type-fest@npm:^5.4.1": + version: 5.6.0 + resolution: "type-fest@npm:5.6.0" + dependencies: + tagged-tag: "npm:^1.0.0" + checksum: 10c0/5468a8ffda7f3904e6f7bbd8069eb8b6dd4bd9156e206df7a01d09a73e28cd1afedf74ead9d0fc12841c8c90074194859feca240511c50800962fde1bd9ddcbc + languageName: node + linkType: hard + +"typescript@npm:^5.9.2, typescript@npm:^5.9.3": + version: 5.9.3 + resolution: "typescript@npm:5.9.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.9.2#optional!builtin, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin": + version: 5.9.3 + resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430 + languageName: node + linkType: hard + +"undici-types@npm:>=7.24.0 <7.24.7": + version: 7.24.6 + resolution: "undici-types@npm:7.24.6" + checksum: 10c0/d9cd8befb643ac904615c280a095ba4240531f6bb4a5e75a22a7483630ca8d3f1016d2ab6ace6ceda1f63b3a2db2fe037fafe121d6917a0187573aa548ff78ca + languageName: node + linkType: hard + +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 + languageName: node + linkType: hard + +"undici-types@npm:~7.16.0": + version: 7.16.0 + resolution: "undici-types@npm:7.16.0" + checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a + languageName: node + linkType: hard + +"undici@npm:^5.18.0": + version: 5.29.0 + resolution: "undici@npm:5.29.0" + dependencies: + "@fastify/busboy": "npm:^2.0.0" + checksum: 10c0/e4e4d631ca54ee0ad82d2e90e7798fa00a106e27e6c880687e445cc2f13b4bc87c5eba2a88c266c3eecffb18f26e227b778412da74a23acc374fca7caccec49b + languageName: node + linkType: hard + +"undici@npm:^6.25.0": + version: 6.25.0 + resolution: "undici@npm:6.25.0" + checksum: 10c0/2597cc6689bdb02c210c557b1f85febbfda65becae6e6fc1061508e2f33734d25207f81cd8af56ada9956329eb3a7bd7431e87dcfeceba20ee87059b57dcf985 + languageName: node + linkType: hard + +"unfetch@npm:^4.2.0": + version: 4.2.0 + resolution: "unfetch@npm:4.2.0" + checksum: 10c0/a5c0a896a6f09f278b868075aea65652ad185db30e827cb7df45826fe5ab850124bf9c44c4dafca4bf0c55a0844b17031e8243467fcc38dd7a7d435007151f1b + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + +"unixify@npm:^1.0.0": + version: 1.0.0 + resolution: "unixify@npm:1.0.0" + dependencies: + normalize-path: "npm:^2.1.1" + checksum: 10c0/8b89100619ebde9f0ab4024a4d402316fb7b1d4853723410fc828944e8d3d01480f210cddf94d9a1699559f8180d861eb6323da8011b7bcc1bbaf6a11a5b1f1e + languageName: node + linkType: hard + +"utility-types@npm:^3.10.0": + version: 3.11.0 + resolution: "utility-types@npm:3.11.0" + checksum: 10c0/2f1580137b0c3e6cf5405f37aaa8f5249961a76d26f1ca8efc0ff49a2fc0e0b2db56de8e521a174d075758e0c7eb3e590edec0832eb44478b958f09914920f19 + languageName: node + linkType: hard + +"uuid@npm:^13.0.0": + version: 13.0.2 + resolution: "uuid@npm:13.0.2" + bin: + uuid: dist-node/bin/uuid + checksum: 10c0/32c7ee84fa7c7966cc09b3a1514a752a8e2f609f15c00033fbaedc0255d577d1877b839f11ee537f37e587bbc620bbb98c3b3a1482931b8ed47d79497cd7a7cd + languageName: node + linkType: hard + +"value-or-promise@npm:^1.0.12": + version: 1.0.12 + resolution: "value-or-promise@npm:1.0.12" + checksum: 10c0/b75657b74e4d17552bd88e0c2857020fbab34a4d091dc058db18c470e7da0336067e72c130b3358e3321ac0a6ff11c0b92b67a382318a3705ad5d57de7ff3262 + languageName: node + linkType: hard + +"vite-node@npm:3.2.4": + version: 3.2.4 + resolution: "vite-node@npm:3.2.4" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.4.1" + es-module-lexer: "npm:^1.7.0" + pathe: "npm:^2.0.3" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + bin: + vite-node: vite-node.mjs + checksum: 10c0/6ceca67c002f8ef6397d58b9539f80f2b5d79e103a18367288b3f00a8ab55affa3d711d86d9112fce5a7fa658a212a087a005a045eb8f4758947dd99af2a6c6b + languageName: node + linkType: hard + +"vite-tsconfig-paths@npm:^4.2.1": + version: 4.3.2 + resolution: "vite-tsconfig-paths@npm:4.3.2" + dependencies: + debug: "npm:^4.1.1" + globrex: "npm:^0.1.2" + tsconfck: "npm:^3.0.3" + peerDependencies: + vite: "*" + peerDependenciesMeta: + vite: + optional: true + checksum: 10c0/f390ac1d1c3992fc5ac50f9274c1090f8b55ab34a89ea88893db9a6924a3b26c9f64bc1163615150ad100749db73b6b2cf1d57f6cd60df6e762ceb5b8ad30024 + languageName: node + linkType: hard + +"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^7.0.0": + version: 7.3.3 + resolution: "vite@npm:7.3.3" + dependencies: + esbuild: "npm:^0.27.0" + fdir: "npm:^6.5.0" + fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.3" + postcss: "npm:^8.5.6" + rollup: "npm:^4.43.0" + tinyglobby: "npm:^0.2.15" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/44fed2591d5d0a9d1f6313e0a4330659b7f1eec57e542558f12a924c53b450a84b9fad6d57ac28ec739eca1cf5ff0f62e41b965e3806c47eefdbbe13b74ec9ae + languageName: node + linkType: hard + +"vitest@npm:^3.1.1": + version: 3.2.4 + resolution: "vitest@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/expect": "npm:3.2.4" + "@vitest/mocker": "npm:3.2.4" + "@vitest/pretty-format": "npm:^3.2.4" + "@vitest/runner": "npm:3.2.4" + "@vitest/snapshot": "npm:3.2.4" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + debug: "npm:^4.4.1" + expect-type: "npm:^1.2.1" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.2" + std-env: "npm:^3.9.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.2" + tinyglobby: "npm:^0.2.14" + tinypool: "npm:^1.1.1" + tinyrainbow: "npm:^2.0.0" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + vite-node: "npm:3.2.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/5bf53ede3ae6a0e08956d72dab279ae90503f6b5a05298a6a5e6ef47d2fd1ab386aaf48fafa61ed07a0ebfe9e371772f1ccbe5c258dd765206a8218bf2eb79eb + languageName: node + linkType: hard + +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: "npm:~0.0.3" + webidl-conversions: "npm:^3.0.0" + checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5 + languageName: node + linkType: hard + +"which-module@npm:^2.0.0": + version: 2.0.1 + resolution: "which-module@npm:2.0.1" + checksum: 10c0/087038e7992649eaffa6c7a4f3158d5b53b14cf5b6c1f0e043dccfacb1ba179d12f17545d5b85ebd94a42ce280a6fe65d0cbcab70f4fc6daad1dfae85e0e6a3e + languageName: node + linkType: hard + +"which@npm:^6.0.0": + version: 6.0.1 + resolution: "which@npm:6.0.1" + dependencies: + isexe: "npm:^4.0.0" + bin: + node-which: bin/which.js + checksum: 10c0/7e710e54ea36d2d6183bee2f9caa27a3b47b9baf8dee55a199b736fcf85eab3b9df7556fca3d02b50af7f3dfba5ea3a45644189836df06267df457e354da66d5 + languageName: node + linkType: hard + +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + +"widest-line@npm:^6.0.0": + version: 6.0.0 + resolution: "widest-line@npm:6.0.0" + dependencies: + string-width: "npm:^8.1.0" + checksum: 10c0/735f1fdcd97fe765a07bb8b5e73c020bed8e53ab34e83ce0ef01693ba3c914d9e7977fe5f5facf0d0b670297a82dd5e376d3efa0896860dfcdaf7cd6924c0fb7 + languageName: node + linkType: hard + +"wrap-ansi@npm:^3.0.1": + version: 3.0.1 + resolution: "wrap-ansi@npm:3.0.1" + dependencies: + string-width: "npm:^2.1.1" + strip-ansi: "npm:^4.0.0" + checksum: 10c0/ad6fed8f242c26755badaf452da154122d0d862f8b7aab56e758466857f230efafdc5fbffca026650b947ac3fc0eb563df5c05b9e2190a52a4a68f4eef3d4555 + languageName: node + linkType: hard + +"wrap-ansi@npm:^6.2.0": + version: 6.2.0 + resolution: "wrap-ansi@npm:6.2.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/baad244e6e33335ea24e86e51868fe6823626e3a3c88d9a6674642afff1d34d9a154c917e74af8d845fd25d170c4ea9cf69a47133c3f3656e1252b3d462d9f6c + languageName: node + linkType: hard + +"wrap-ansi@npm:^9.0.0": + version: 9.0.2 + resolution: "wrap-ansi@npm:9.0.2" + dependencies: + ansi-styles: "npm:^6.2.1" + string-width: "npm:^7.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/3305839b9a0d6fb930cb63a52f34d3936013d8b0682ff3ec133c9826512620f213800ffa19ea22904876d5b7e9a3c1f40682f03597d986a4ca881fa7b033688c + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"ws@npm:^5.2.0 || ^6.0.0 || ^7.0.0": + version: 7.5.10 + resolution: "ws@npm:7.5.10" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d + languageName: node + linkType: hard + +"ws@npm:^6.1.4": + version: 6.2.3 + resolution: "ws@npm:6.2.3" + dependencies: + async-limiter: "npm:~1.0.0" + checksum: 10c0/56a35b9799993cea7ce2260197e7879f21bbbb194a967f31acbbda6f7f46ecda4365951966fb062044c95197e19fb2f053be6f65c172435455186835f494de41 + languageName: node + linkType: hard + +"ws@npm:^8.18.0": + version: 8.20.1 + resolution: "ws@npm:8.20.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/ce162433218399cdedeb76fd33363d4d86a7d910058d4e3c679dce08cea65d6da6b39f11baa4d7808d024cf46ed88f6a05c17611621aaad8fc5e62edacc30c5d + languageName: node + linkType: hard + +"y18n@npm:^4.0.0": + version: 4.0.3 + resolution: "y18n@npm:4.0.3" + checksum: 10c0/308a2efd7cc296ab2c0f3b9284fd4827be01cfeb647b3ba18230e3a416eb1bc887ac050de9f8c4fd9e7856b2e8246e05d190b53c96c5ad8d8cb56dffb6f81024 + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 + languageName: node + linkType: hard + +"yargs-parser@npm:^18.1.2": + version: 18.1.3 + resolution: "yargs-parser@npm:18.1.3" + dependencies: + camelcase: "npm:^5.0.0" + decamelize: "npm:^1.2.0" + checksum: 10c0/25df918833592a83f52e7e4f91ba7d7bfaa2b891ebf7fe901923c2ee797534f23a176913ff6ff7ebbc1cc1725a044cc6a6539fed8bfd4e13b5b16376875f9499 + languageName: node + linkType: hard + +"yargs@npm:^15.3.1": + version: 15.4.1 + resolution: "yargs@npm:15.4.1" + dependencies: + cliui: "npm:^6.0.0" + decamelize: "npm:^1.2.0" + find-up: "npm:^4.1.0" + get-caller-file: "npm:^2.0.1" + require-directory: "npm:^2.1.1" + require-main-filename: "npm:^2.0.0" + set-blocking: "npm:^2.0.0" + string-width: "npm:^4.2.0" + which-module: "npm:^2.0.0" + y18n: "npm:^4.0.0" + yargs-parser: "npm:^18.1.2" + checksum: 10c0/f1ca680c974333a5822732825cca7e95306c5a1e7750eb7b973ce6dc4f97a6b0a8837203c8b194f461969bfe1fb1176d1d423036635285f6010b392fa498ab2d + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f + languageName: node + linkType: hard + +"yoctocolors-cjs@npm:^2.1.2": + version: 2.1.3 + resolution: "yoctocolors-cjs@npm:2.1.3" + checksum: 10c0/584168ef98eb5d913473a4858dce128803c4a6cd87c0f09e954fa01126a59a33ab9e513b633ad9ab953786ed16efdd8c8700097a51635aafaeed3fef7712fa79 + languageName: node + linkType: hard + +"yoga-layout@npm:~3.2.1": + version: 3.2.1 + resolution: "yoga-layout@npm:3.2.1" + checksum: 10c0/9001e51be993c85e03757e5a04a2b61b8b30c9e5a7865d0156ca87a6431a3b717d51eb4990bfe588189fcfeac688dd9c3de707bbd50d1c344a84e63974cc54a8 + languageName: node + linkType: hard + +"zen-observable-ts@npm:^0.8.21": + version: 0.8.21 + resolution: "zen-observable-ts@npm:0.8.21" + dependencies: + tslib: "npm:^1.9.3" + zen-observable: "npm:^0.8.0" + checksum: 10c0/fe4a02f862b5f7e8ae0f86230c37b84c7d5611f5c206981afb4043e732d04cf7067a6cbe1ba82d20f18b735a3387937195a12542158a631d308ae3959a1d93c4 + languageName: node + linkType: hard + +"zen-observable@npm:^0.8.0": + version: 0.8.15 + resolution: "zen-observable@npm:0.8.15" + checksum: 10c0/71cc2f2bbb537300c3f569e25693d37b3bc91f225cefce251a71c30bc6bb3e7f8e9420ca0eb57f2ac9e492b085b8dfa075fd1e8195c40b83c951dd59c6e4fbf8 + languageName: node + linkType: hard + +"zod@npm:^4.1.11": + version: 4.4.3 + resolution: "zod@npm:4.4.3" + checksum: 10c0/7ea31b558e88f9faf44f31dd185e2e1cbf51fed3081787fb96cc2534749b50c0acfc6da7f0922a7353ed092dd358c7d50c28ea96c94d04af64191bd33152eca3 + languageName: node + linkType: hard