diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 82aa65b..f4a9269 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -13,10 +13,27 @@ on: - check-tests jobs: + check-secrets: + runs-on: ubuntu-latest + outputs: + has_token: ${{ steps.check.outputs.has_token }} + steps: + - name: Check whether PLANE_EE_CHECKOUT_TOKEN is configured + # `secrets` isn't reliably available in a job-level `if:` on every runner + # context, so export the check as a step output here instead and gate the + # v2-golden-drift job on that output. + id: check + run: echo "has_token=${{ secrets.PLANE_EE_CHECKOUT_TOKEN != '' }}" >> "$GITHUB_OUTPUT" + build-lint: runs-on: ubuntu-latest + defaults: + run: + working-directory: plane-node-sdk steps: - uses: actions/checkout@v4 + with: + path: plane-node-sdk - name: Set up Node.js uses: actions/setup-node@v4 @@ -36,9 +53,53 @@ jobs: - name: Run build run: pnpm run build - - name: Run tests + - name: Run unit tests + run: pnpm run test:unit + + - name: Run e2e tests run: pnpm run test:e2e env: PLANE_API_KEY: ${{ secrets.PLANE_API_KEY }} PLANE_BASE_URL: ${{ secrets.PLANE_BASE_URL }} TEST_WORKSPACE_SLUG: ${{ vars.TEST_WORKSPACE_SLUG }} + + v2-golden-drift: + needs: check-secrets + if: ${{ needs.check-secrets.outputs.has_token == 'true' }} + runs-on: ubuntu-latest + # Runs inside plane-node-sdk/ with plane-ee as a sibling dir: the generator records + # its golden path in the output header, so the relative spelling must match the + # committed one (`../plane-ee/apps/api/plane/api_v2/core/schema/openapi`). + defaults: + run: + working-directory: plane-node-sdk + steps: + - uses: actions/checkout@v4 + with: + path: plane-node-sdk + + - name: Set up Node.js + uses: actions/setup-node@v4 + + - name: Enable corepack + run: corepack enable pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Checkout plane-ee (api_v2 OpenAPI golden) + # PLANE_EE_CHECKOUT_TOKEN: fine-grained PAT with read access to makeplane/plane-ee. + # Without it this job is skipped (visibly), not failed. + uses: actions/checkout@v4 + with: + repository: makeplane/plane-ee + ref: preview + token: ${{ secrets.PLANE_EE_CHECKOUT_TOKEN }} + sparse-checkout: apps/api/plane/api_v2/core/schema/openapi + sparse-checkout-cone-mode: false + path: plane-ee + + - name: Check generated v2 constants against the api_v2 golden + run: | + pnpm codegen:v2 ../plane-ee/apps/api/plane/api_v2/core/schema/openapi + git diff --exit-code src/api/v2/generated/constants.ts diff --git a/.oxlintrc.json b/.oxlintrc.json index 1ba57c1..c383076 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -101,6 +101,24 @@ "node": true } }, + { + "files": ["scripts/**"], + "rules": { + "no-console": "off" + } + }, + // Deliberately narrow: covers e2e cleanup logging only (a test-support helper + // that warns on a best-effort cleanup failure is doing the right thing). Does + // NOT extend to tests/** generally -- pre-existing `console` warnings elsewhere + // under tests/ (e.g. stray console.log calls in v1 test files) are intentionally + // left visible; a broader tests/** override would silence ~70 of them and turn + // the lint count from a tripwire into a number nobody can trust again. + { + "files": ["tests/e2e/v2/support/**"], + "rules": { + "no-console": "off" + } + }, { "files": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"], "rules": { diff --git a/CLAUDE.md b/CLAUDE.md index f3c72f4..fce13d4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,6 +42,24 @@ Tests live in `tests/unit/` and `tests/e2e/`. Tests require a `.env.test` file ( - `AgentRuns/` → Activities - `WorkItemProperties/` → Options, Values +**API v2** (`src/api/v2/`): the v2 surface, reached as `client.v2`. The bound/chained +form is the only public shape — `client.v2.workspace(slug)` returns a `Workspace` +locator (`src/api/v2/Workspace.ts`), `.project(key)` off of that returns a `Project` +locator (`src/api/v2/Project.ts`); both do zero I/O. `Wiki.ts` is `Workspace.wiki`'s +container (`.pages`/`.collections`). `kernel/` holds the shared machinery (transport, +pagination, generic `V2Resource`, bulk helpers); `generated/constants.ts` is produced +by `pnpm codegen:v2` from the api_v2 OpenAPI golden and must never be hand-edited. +Resources are thin declarations over `V2Resource`, constructed with a `scope` +(`{ slug }` / `{ slug, project_id }`) a locator already bound — `V2Resource`'s +`urlFor` resolves path placeholders from `{...scope, ...pathParams}`, explicit +`pathParams` winning. No public v2 method takes `workspaceSlug`/`project` — the +locator supplies both; leaf ids (`workItemId`, `releaseId`, ...) stay as the first +positional argument. Models live in `src/models/v2/`; read models mark every +field except `id` optional, because `?fields=` and collection deferral can omit any +of them. The wiki page model is `Page` (`src/models/v2/Page.ts`) — files that also +need the pagination envelope `Page` (`models/v2/common.ts`) import it under a +local `WikiPage` alias to keep both in scope. + **Models** (`src/models/`): TypeScript interfaces for each entity with separate Create/Update DTOs. Uses `Pick`, `Omit`, and `Partial` for DTO derivation. Notable: `WorkItem` uses a generic expandable fields pattern (`WorkItem`). **Errors** (`src/errors/`): `PlaneError` (base) → `HttpError` (HTTP-specific with status code and response data). diff --git a/README.md b/README.md index 9c5dc97..16f4fff 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,144 @@ const project = await client.projects.create("workspace-slug", { }); ``` +## API v2 + +`client.v2` reaches the v2 surface. The v1 resources on the client are unchanged. + +The bound/chained form is the **only** public shape: bind a workspace, then (for +project-scoped resources) a project — both locators do zero I/O, so building the +chain never makes a request on its own. + +```ts +import { PlaneClient, v2 } from "@makeplane/plane-node-sdk"; + +const client = new PlaneClient({ baseUrl: "https://api.plane.so", apiKey: "..." }); + +// Bind once. `project` accepts a project id or its key (e.g. "ENG"). +const ws = client.v2.workspace("acme"); +const eng = ws.project("ENG"); + +// States resolve by name; every method below takes only the arguments the +// workspace/project scope doesn't already supply. +const todo = await eng.states.findByName("Todo"); + +// Ask for only the fields you need — list/retrieve narrow the return type to match. +// An inline array literal needs no `as const`. +const page = await eng.states.list({ fields: ["id", "name"] }); +for (const state of page.data) { + console.log(state.id, state.name); // typed — only id/name exist on this row +} + +// iterate() follows pagination automatically, but always returns the full row type +for await (const state of eng.states.iterate()) { + console.log(state.id, state.name); +} + +await eng.states.create({ name: "In Review", color: "#4ECDC4" }); + +// Batches report per row; partial success is the default. `raiseForFailures` and the +// other bulk helpers live on the `v2` namespace, not the package root. +const result = await eng.states.bulkCreate([{ name: "QA", color: "#fff" }]); +v2.raiseForFailures(result); + +// The 6 operations that aren't workspace-scoped at all stay on the top-level namespace. +await client.v2.users.me(); +``` + +No v2 method takes `workspaceSlug`/`project` — the locator supplies both. Leaf ids +(`workItemId`, `releaseId`, `collectionId`, …) stay as the first positional argument: + +```ts +const item = await eng.workItems.create({ name: "Fix login bug", state: "Todo", labels: ["bug"] }); +await eng.workItems.comments.list(item.id); +await ws.workItems.retrieveByIdentifier("ENG-12"); // by human key, no project needed +await ws.releases.comments.list(releaseId); +``` + +A field list built at runtime (not a literal) must be typed `StateField[]` / +`LabelField[]` — plain `string[]` is **not** assignable to `readonly StateField[]` and +fails with a long overload-mismatch error: + +```ts +import { PlaneClient, v2 } from "@makeplane/plane-node-sdk"; + +const client = new PlaneClient({ baseUrl: "https://api.plane.so", apiKey: "..." }); +const eng = client.v2.workspace("acme").project("ENG"); + +const wanted: v2.StateField[] = includeColor ? ["id", "name", "color"] : ["id", "name"]; +const page = await eng.states.list({ fields: wanted }); // still narrows +``` + +`"all"` is a legal field value meaning "every field" and correctly yields the full row +type. Sparse responses mean every read field except `id` is optional — check for +`undefined` rather than assuming a field is present. + +**Pagination**: `Page` is a union of the offset envelope (`total_count`, `next`) and +the cursor envelope (`has_more`, `next_cursor`) — which one a given `list()` returns +depends on the request's `paginate` param. Narrow it with `v2.isCursorPage` / +`v2.isOffsetPage` before reading an envelope-specific field; reading one without +narrowing first is a compile error, since it may not exist on the other half of the +union: + +```ts +import { PlaneClient, v2 } from "@makeplane/plane-node-sdk"; + +const client = new PlaneClient({ baseUrl: "https://api.plane.so", apiKey: "..." }); +const eng = client.v2.workspace("acme").project("ENG"); + +const page = await eng.states.list(); +if (v2.isOffsetPage(page)) { + console.log(page.total_count); // only reachable once narrowed +} else if (v2.isCursorPage(page)) { + console.log(page.next_cursor); +} +``` + +`order_by` is validated the same way `fields` is, against a generated +`StateOrderBy`/`LabelOrderBy` union — an unsupported value throws client-side rather +than reaching the server. + +**Wiki**: `ws.wiki.pages` is every global page in the workspace (not one project — +that's `eng.pages`); `ws.wiki.collections` is wiki collections. A page write's +`collection_id` can be omitted for a public page (it lands in the workspace's default +"General" collection); a private page needs an explicit `collection_id` of a +collection the caller owns. + +```ts +const ws = client.v2.workspace("acme"); +await ws.wiki.pages.create({ name: "Handbook" }); // public page -> default collection +const handbook = await ws.wiki.collections.findByName("Engineering handbook"); +await ws.wiki.pages.create({ name: "Runbook", collection_id: handbook.id }); +await ws.wiki.collections.default(); // the default collection, resolved via `is_default` +``` + +**Errors**: `PlaneApiError` — an RFC 9457 problem detail with `.status`, `.type`, +`.code`, `.detail`, `.errors` — plus `NoMatchFoundError` and +`MultipleMatchesFoundError` from `findByName`. A request that never reaches a server +at all (connection refused, DNS failure, timeout, ...) raises `PlaneNetworkError` +instead, carrying the underlying error's message and `.cause`. + +**Bulk writes** (`bulkCreate` / `bulkUpdate` / `bulkDelete`) always answer HTTP 200, +even when some rows fail — partial success is the default. Call +`v2.raiseForFailures(result)` to throw, carrying the first failure's `errors`. The cap +is 50 items per call (`v2.BULK_MAX_ITEMS`); an empty batch is rejected client-side (not +a silent no-op). + +**Types**: v2 types are reachable through the `v2` and `v2models` namespaces (e.g. +`v2models.State`, `v2.StateField`), and the most common ones are also aliased at the +package root: `V2Label`, `V2State`, `V2Page`, `V2Cycle`, `V2Module`, `V2Milestone`, +`V2ListStatesParams`, `V2ListLabelsParams`. Use those — v2's bare `Label`/`State`/ +`Page`/`Cycle`/`Module`/`Milestone` names collide with v1's in the bundled type +definitions, so `import { Label } from "@makeplane/plane-node-sdk"` resolves to +**v1's** shape, not v2's. (`V2Page` is the wiki page model; the pagination envelope +`Page` is aliased separately as `V2PageEnvelope`.) + +**Generated data**: `v2.FIELDS` and `v2.ORDER_BY` are the full operation-id -> allowed- +values maps `encodeFields`/`encodeOrderBy` validate against (e.g. `v2.FIELDS["states_list"]` +lists every field `states.list` accepts); `v2.OPENAPI_VERSION` is the api_v2 golden +version the SDK was generated from. All three, plus `v2.BULK_MAX_ITEMS`, are exported +from the `v2` namespace so a caller can enumerate valid values rather than guessing. + ## Features - ✅ TypeScript support with full type safety diff --git a/jest.config.js b/jest.config.js index 8c670e5..87818ed 100644 --- a/jest.config.js +++ b/jest.config.js @@ -15,7 +15,12 @@ module.exports = { collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/**/*.spec.ts"], coverageDirectory: "coverage", coverageReporters: ["text", "lcov", "html"], - testTimeout: 60000, // 60 seconds timeout for API tests + // 180s, not 60s: tests/e2e/v2/support/client.ts's rate-limit retry budget needs + // headroom to actually absorb this dev server's observed 429 Retry-After (56-59s) + // instead of always losing the race against Jest's own timeout — see that file's + // own comment. Harmless for every non-live test: they finish in milliseconds + // regardless of the ceiling. + testTimeout: 180000, verbose: true, // Allow tests to run in parallel but with some control maxWorkers: 1, // Run tests sequentially to avoid API rate limits diff --git a/package.json b/package.json index 36a360c..2622e7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@makeplane/plane-node-sdk", - "version": "0.2.13", + "version": "0.3.0", "description": "Node SDK for Plane", "author": "Plane ", "repository": { @@ -15,7 +15,7 @@ ], "scripts": { "build:types-bundle": "dts-bundle-generator --no-check -o dist/types.bundle.d.ts dist/index.d.ts", - "build": "tsc && pnpm run build:types-bundle", + "build": "tsc && pnpm run build:types-bundle && node scripts/check-types-bundle.mjs", "dev": "tsc --watch", "test": "jest", "test:unit": "jest --testPathPattern=tests/unit", @@ -27,7 +27,9 @@ "check:lint": "oxlint", "fix:lint": "oxlint --fix", "check:format": "oxfmt --check", - "fix:format": "oxfmt" + "fix:format": "oxfmt", + "codegen:v2": "node scripts/generate-v2-constants.mjs", + "check:types-bundle": "node scripts/check-types-bundle.mjs" }, "keywords": [ "plane", @@ -47,6 +49,7 @@ "dotenv": "^17.4.2", "dts-bundle-generator": "^9.5.1", "jest": "^29.0.0", + "nock": "^14.0.17", "oxfmt": "^0.42.0", "oxlint": "^1.57.0", "ts-node": "^10.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 297164b..3285520 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,6 +36,9 @@ importers: jest: specifier: ^29.0.0 version: 29.7.0(@types/node@20.19.39)(ts-node@10.9.2(@types/node@20.19.39)(typescript@5.9.3)) + nock: + specifier: ^14.0.17 + version: 14.0.17 oxfmt: specifier: ^0.42.0 version: 0.42.0 @@ -313,6 +316,19 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@mswjs/interceptors@0.41.9': + resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} + engines: {node: '>=18'} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@oxfmt/binding-android-arm-eabi@0.42.0': resolution: {integrity: sha512-dsqPTYsozeokRjlrt/b4E7Pj0z3eS3Eg74TWQuuKbjY4VttBmA88rB7d50Xrd+TZ986qdXCNeZRPEzZHAe+jow==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1018,6 +1034,9 @@ packages: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1197,6 +1216,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1271,6 +1293,10 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + nock@14.0.17: + resolution: {integrity: sha512-EjRr1weMa4ALQX35AgZTEnP+weJJjlW1KGDiNM2IQC2069YDHas4f4B4UUYR+TTLyKWxJvOz2wObDKQs/LNreA==} + engines: {node: '>=18.20.0 <20 || >=20.12.1'} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -1292,6 +1318,9 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + oxfmt@0.42.0: resolution: {integrity: sha512-QhejGErLSMReNuZ6vxgFHDyGoPbjTRNi6uGHjy0cvIjOQFqD6xmr/T+3L41ixR3NIgzcNiJ6ylQKpvShTgDfqg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1365,6 +1394,10 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -1434,6 +1467,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -2000,6 +2036,24 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@mswjs/interceptors@0.41.9': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@oxfmt/binding-android-arm-eabi@0.42.0': optional: true @@ -2578,6 +2632,8 @@ snapshots: is-generator-fn@2.1.0: {} + is-node-process@1.2.0: {} + is-number@7.0.0: {} is-stream@2.0.1: {} @@ -2944,6 +3000,8 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-stringify-safe@5.0.1: {} + json5@2.2.3: {} kleur@3.0.3: {} @@ -3001,6 +3059,12 @@ snapshots: neo-async@2.6.2: {} + nock@14.0.17: + dependencies: + '@mswjs/interceptors': 0.41.9 + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + node-int64@0.4.0: {} node-releases@2.0.37: {} @@ -3019,6 +3083,8 @@ snapshots: dependencies: mimic-fn: 2.1.0 + outvariant@1.4.3: {} + oxfmt@0.42.0: dependencies: tinypool: 2.1.0 @@ -3115,6 +3181,8 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + propagate@2.0.1: {} + proxy-from-env@2.1.0: {} pure-rand@6.1.0: {} @@ -3165,6 +3233,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + strict-event-emitter@0.5.1: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 diff --git a/scripts/__fixtures__/types-bundle-exports.snapshot.txt b/scripts/__fixtures__/types-bundle-exports.snapshot.txt new file mode 100644 index 0000000..d6dc9dd --- /dev/null +++ b/scripts/__fixtures__/types-bundle-exports.snapshot.txt @@ -0,0 +1,1450 @@ +root AccessEnum AccessEnum 5beb677a818b6d2f +root AddCollectionPages AddCollectionPages 31f635cba0655dcb +root AddEpicWorkItems AddEpicWorkItems 1a7fcb98960f392a +root AddInitiativeEpicsRequest AddInitiativeEpicsRequest 1f9bd4f3adcdb4ba +root AddInitiativeLabelsRequest AddInitiativeLabelsRequest 4a3a7e57dd2157c0 +root AddInitiativeProjectsRequest AddInitiativeProjectsRequest 53a0593ceff8cbd3 +root AddReleaseItemLabel AddReleaseItemLabel 572875acd1554656 +root AddReleaseWorkItems AddReleaseWorkItems 1d52f5148f2b617e +root AddTeamspaceMembersRequest AddTeamspaceMembersRequest e940c26eb5341c32 +root AddTeamspaceProjectsRequest AddTeamspaceProjectsRequest 98596637fb91b552 +root AddWorkItemsToCycleRequest AddWorkItemsToCycleRequest 7a325f3225de9363 +root AddWorkspaceWorkflowStates AddWorkspaceWorkflowStates 4c7a22617d883714 +root AdvancedSearchFilter AdvancedSearchFilter 8befbf2f8fd1c5fc +root AdvancedSearchResult AdvancedSearchResult 94487f1d1a862d9c +root AdvancedSearchWorkItem AdvancedSearchWorkItem fd91e271273497ce +root AgentRun AgentRun c77fd98aeead2f9f +root AgentRunActivities Activities$2 3bc208fabe9488ee +root AgentRunActivity AgentRunActivity d2d46f65642c75a2 +root AgentRunActivityActionContent AgentRunActivityActionContent 6cd9c0a9c9a5442b +root AgentRunActivityContent AgentRunActivityContent 5ae02c0b34285d2e +root AgentRunActivitySignal AgentRunActivitySignal 3ea7fc575ff2afe3 +root AgentRunActivityTextContent AgentRunActivityTextContent 1d46a7874e95fed5 +root AgentRunActivityType AgentRunActivityType 1dbb57e6ee99c3bf +root AgentRuns AgentRuns 9d3a8b1dc24e8edf +root AgentRunStatus AgentRunStatus 626f1245f0d10d13 +root AgentRunType AgentRunType 7002bbcb0a4df4db +root AnyOperationId AnyOperationId 102a7f4c32c7d620 +root Artifact Artifact 8f4f4ab71cb8c53d +root ArtifactDataMode ArtifactDataMode 29c277b65f52892b +root ArtifactDetail ArtifactDetail 87aff13ed4468ffb +root ArtifactPublishResult ArtifactPublishResult fba408b8f4b397eb +root ArtifactUpdateResult ArtifactUpdateResult 8d2f0f1e3dcefafa +root Assignee Assignee 4df1d5e13eae6ada +root AttachedWorkItemTypeProperties AttachedWorkItemTypeProperties acd010d0807a6bde +root AttachWorkflowStates AttachWorkflowStates 92f378e7a9f562ba +root AuditLog AuditLog 5748cf85faae47c1 +root AuditLogActorType AuditLogActorType 35e22038eafe4c59 +root AuditLogCategory AuditLogCategory 1484076310a18487 +root AuditLogField AuditLogField de42bf6a11cdc85b +root AuditLogOrderBy AuditLogOrderBy e5a46079550cdac9 +root AuditLogOutcome AuditLogOutcome 4900c934d786a2b0 +root AuditLogSource AuditLogSource 9327151c9a43f7fd +root Automation Automation 6ae3a789e2ea73e4 +root AutomationActivity AutomationActivity 7ee11f52c7d2fb62 +root AutomationEdge AutomationEdge 49c515a820d1bfe6 +root AutomationNode AutomationNode 40cfbb6523392f48 +root AutomationNodeType AutomationNodeType ab4ea99462a019fe +root AutomationStatus AutomationStatus 2dee24e5da80571d +root AutomationWebhookSecret AutomationWebhookSecret fad7965f0cf62061 +root BaseCreateWorkItemProperty BaseCreateWorkItemProperty 3e7e8b2e330a67df +root BaseModel BaseModel 7a13600fa51d0759 +root BaseResource BaseResource a99a29823d0aae8e +root BulkCreateWorkspaceInvites BulkCreateWorkspaceInvites b1a680f16ffd3ece +root BulkRowFailure BulkRowFailure 3a63c31df60f367c +root BulkRowSuccess BulkRowSuccess 6840350f1463f1ca +root BulkUpdateItem BulkUpdateItem f74590a8eeabea42 +root BulkWriteResponse BulkWriteResponse a62766eda2d9e61f +root BulkWriteRow BulkWriteRow b749b40b311a9124 +root CatalogGroupEnum CatalogGroupEnum aa33010d055285dd +root Collection Collection$1 1863c430f18162ca +root CollectionAccess CollectionAccess 6f764be7a4ca020a +root CollectionAccessEnum CollectionAccessEnum 1d044a20691cb0a0 +root CollectionBranchPage CollectionBranchPage 2f6451b26cfa3982 +root CollectionBranchPageDetail CollectionBranchPageDetail 9b89ed500ee2dcb6 +root CollectionExpand CollectionExpand 68923a08b96dccdf +root CollectionField CollectionField fa33e727203e0006 +root CollectionMember CollectionMember$1 6ef391e0b2ea9134 +root CollectionMemberAccess CollectionMemberAccess$1 3f51c027c1f01593 +root CollectionMemberAccessEnum CollectionMemberAccessEnum 9daaadea6ebfdf5c +root CollectionMemberAddItem CollectionMemberAddItem 95e143cfa1f45db6 +root CollectionMemberExpand CollectionMemberExpand 2e8c17318ee22d9d +root CollectionMemberField CollectionMemberField 5ad47417381b3fca +root CollectionMembersManageRequest CollectionMembersManageRequest 4bf7110404b254eb +root CollectionMembersManageResponse CollectionMembersManageResponse 5ef005598104a071 +root CollectionMemberSource CollectionMemberSource 277b9eb3f44a2f5b +root CollectionMembersResource Members 01db6123282f4b8a +root CollectionOrderBy CollectionOrderBy b141c12a97dab0c5 +root CollectionPage CollectionPage 9ab6ea820ac02489 +root CollectionPageSearch CollectionPageSearch 8b51dfba5d6fd2b3 +root CollectionPageSearchField CollectionPageSearchField 6ae76235d2a3b1ac +root CollectionPageSearchResult CollectionPageSearchResult db96ac010e9afa9a +root CollectionPagesManageRequest CollectionPagesManageRequest 83a731634d038b58 +root CollectionPagesManageResponse CollectionPagesManageResponse ac5dddd044fb4f9e +root CollectionPagesResource Pages$2 db32805900a83eb9 +root Collections Collections$1 7f4d552d43ffae22 +root Configuration Configuration 3699a98cbead400c +root CreateAgentRunActivityRequest CreateAgentRunActivityRequest b6ab9ab8d2670c55 +root CreateAgentRunRequest CreateAgentRunRequest 4ee23b5478c4a50f +root CreateArtifact CreateArtifact a1a0c90fb34f4ef3 +root CreateAutomation CreateAutomation 9a9a62c5ec5118bc +root CreateAutomationEdge CreateAutomationEdge 736ef458b14f945d +root CreateAutomationNode CreateAutomationNode 543b8b4e3387b54f +root CreateBooleanWorkItemProperty CreateBooleanWorkItemProperty ccb216e5088ff6fa +root CreateCollection CreateCollection$1 b3ea9dbea451d69f +root CreateCollectionMember CreateCollectionMember d688f78bf4d913a2 +root CreateCustomer CreateCustomer$1 fd9de350af2b072c +root CreateCustomerProperty CreateCustomerProperty 420db71864a79391 +root CreateCustomerPropertyOption CreateCustomerPropertyOption e818442a4ce6c3a0 +root CreateCustomerPropertyRequest CreateCustomerPropertyRequest 52ea388107f77ac4 +root CreateCustomerPropertyValues CreateCustomerPropertyValues da41ca7f5977895d +root CreateCustomerRequest CreateCustomerRequest$1 565f10415fc05cb5 +root CreateCycle CreateCycle 23f0ebe512ec0384 +root CreateCycleRequest CreateCycleRequest 92245f5608794af0 +root CreateDateTimeWorkItemProperty CreateDateTimeWorkItemProperty 126ae159a2d193ba +root CreateDecimalWorkItemProperty CreateDecimalWorkItemProperty f119312c419b53cb +root CreateEntity CreateEntity 027f8a4bde7bb893 +root CreateEpic CreateEpic 78b3ce6d0a3c6860 +root CreateEstimate CreateEstimate 0413e51a22cb269a +root CreateEstimatePoint CreateEstimatePoint 1cb096c34f59af7d +root CreateEstimatePointRequest CreateEstimatePointRequest 09cc492a346ec219 +root CreateEstimateRequest CreateEstimateRequest 2110e8703d9f7f7e +root CreateGroupMapping CreateGroupMapping b2dd47de6138a93d +root CreateInitiative CreateInitiative$1 ee6742698478e29e +root CreateInitiativeLabel CreateInitiativeLabel$1 3332d2fd79fe070a +root CreateIntakeWorkItem CreateIntakeWorkItem e63583cdd19753c0 +root CreateLabel CreateLabel$1 add2c0f3ef77c24e +root CreateLink CreateLink 86742fbce2642c5c +root CreateMilestone CreateMilestone c343a49181fdedc7 +root CreateMilestoneRequest CreateMilestoneRequest 37293f0acb4e27d6 +root CreateModule CreateModule 5a93c1c805962604 +root CreateModuleRequest CreateModuleRequest a417ce10672849a7 +root CreateOptionWorkItemProperty CreateOptionWorkItemProperty 24169d671e4ad02a +root CreatePage CreatePage$1 191f7119ba205a48 +root CreatePageTemplate CreatePageTemplate 8a3b9ef75dc39339 +root CreateProject CreateProject$1 73e1f10f0730766a +root CreateProjectMember CreateProjectMember cc74eb3e229f28dc +root CreateRelationWorkItemProperty CreateRelationWorkItemProperty aba4a779f11fc482 +root CreateRelease CreateRelease$1 4c038c48970ac89f +root CreateReleaseComment CreateReleaseComment$1 1a28cf47e698197d +root CreateReleaseLabel CreateReleaseLabel$1 41aa2c913b31e013 +root CreateReleaseLink CreateReleaseLink$1 3e6f3da64264808d +root CreateReleaseTag CreateReleaseTag$1 249006f86937c535 +root CreateState CreateState$1 d061d0050345aa4e +root CreateSticky CreateSticky$1 da5c357696e5e97d +root CreateTeamspace CreateTeamspace$1 4006be56b72002d5 +root CreateTextWorkItemProperty CreateTextWorkItemProperty cd83ddc6cab7cf09 +root CreateView CreateView c45c383521d10adb +root CreateWebhook CreateWebhook cf78dd312a0d05ba +root CreateWorkflow CreateWorkflow$1 78201216b4754e3a +root CreateWorkflowTransition CreateWorkflowTransition$1 45510e0b617f6460 +root CreateWorkflowTransitionHook CreateWorkflowTransitionHook 38fff173d57eafa0 +root CreateWorkItem CreateWorkItem$1 99c3f1ed9f2dd4bc +root CreateWorkItemComment CreateWorkItemComment fda978bfd6dcfc04 +root CreateWorkItemCustomRelationRequest CreateWorkItemCustomRelationRequest c8bf301ad067f724 +root CreateWorkItemDependencyRequest CreateWorkItemDependencyRequest d8b8ba086c345c32 +root CreateWorkItemLink CreateWorkItemLink 0ffd0c540f660d6c +root CreateWorkItemPageRequest CreateWorkItemPageRequest c55f1acd66e11cd5 +root CreateWorkItemProperty CreateWorkItemProperty$1 6c668e186eaf29ac +root CreateWorkItemPropertyContext CreateWorkItemPropertyContext 76702715f55a1cd6 +root CreateWorkItemPropertyOption CreateWorkItemPropertyOption$1 ae8f68390aae7770 +root CreateWorkItemRelationDefinition CreateWorkItemRelationDefinition$1 58e93cd33c1ad919 +root CreateWorkItemTemplate CreateWorkItemTemplate$1 2ee3976afe90697e +root CreateWorkItemType CreateWorkItemType$1 a6991cdbd618efa9 +root CreateWorkItemTypeWorkflowPins CreateWorkItemTypeWorkflowPins 1cce90b6e4672691 +root CreateWorkItemWorklog CreateWorkItemWorklog ce38f3901d43f6b0 +root CreateWorkLogRequest CreateWorkLogRequest 9333dc35b7d8fa83 +root CreateWorkspaceGroupMapping CreateWorkspaceGroupMapping 1eb4aa8836c63273 +root CreateWorkspaceInvite CreateWorkspaceInvite 4ce3c7f684711bdc +root CreateWorkspacePageTemplate CreateWorkspacePageTemplate 43608a353360882d +root CreateWorkspaceProjectLabel CreateWorkspaceProjectLabel 58f37b5cba89259b +root CreateWorkspaceProjectState CreateWorkspaceProjectState c2c1f3be901f0961 +root CreateWorkspaceProjectTemplate CreateWorkspaceProjectTemplate 442aa46dd845ab96 +root CreateWorkspaceState CreateWorkspaceState 1aa053de91e02df5 +root CreateWorkspaceWorkflow CreateWorkspaceWorkflow 7dd4a86e65f2f1c5 +root CreateWorkspaceWorkflowTransition CreateWorkspaceWorkflowTransition d69af02fd6c94d6d +root CreateWorkspaceWorkItemTemplate CreateWorkspaceWorkItemTemplate 79d631796155ad45 +root CursorPage CursorPage fcc2a5033696f854 +root Customer Customer$1 a82d7994b4b6594a +root CustomerField CustomerField 039dd6a06995ee5f +root CustomerOrderBy CustomerOrderBy f7a9e1ab0c718d10 +root CustomerProperties Properties 1d1c9c2934eb5b6d +root CustomerProperty CustomerProperty$1 b0f376acacc1899a +root CustomerPropertyField CustomerPropertyField 2c47c1217ab07847 +root CustomerPropertyOrderBy CustomerPropertyOrderBy dfdb2d89b5562988 +root CustomerPropertyRelationType CustomerPropertyRelationType 2bfd7d84e1fefe5e +root CustomerPropertyType CustomerPropertyType bc8c90c3a66852ae +root CustomerPropertyValue CustomerPropertyValue fdc1e31a279eab61 +root CustomerPropertyValuesMap CustomerPropertyValuesMap 2938d2ca1c056e61 +root CustomerRequest CustomerRequest$1 874a4ddd78db455e +root CustomerRequestField CustomerRequestField b9db5f28b94dda8b +root CustomerRequestOrderBy CustomerRequestOrderBy c7f657f358bd2825 +root CustomerRequests Requests 4e0b0b2bb21f5bca +root Customers Customers$1 3f5710bb71eda78f +root CustomerWorkItemManageRequest CustomerWorkItemManageRequest 1cc9f352a02fcc08 +root CustomerWorkItemManageResponse CustomerWorkItemManageResponse 4546c88beb8fe10f +root CustomPropertyValueResponse CustomPropertyValueResponse fa33185084680be9 +root Cycle Cycle$1 bfd9f11c6db78913 +root CycleExpand CycleExpand 0262965cca15fe32 +root CycleField CycleField bfc78230b96b361d +root CycleLite CycleLite 7ba4d2abb0b3c00e +root CycleOrderBy CycleOrderBy 6b31c08b310b702d +root Cycles Cycles$1 98a3584b97aea82a +root CycleTransferRequest CycleTransferRequest e7f43182d7f1d576 +root CycleTransferResult CycleTransferResult d042aace96311191 +root CycleWorkItem CycleWorkItem af003efccbfafd8b +root CycleWorkItemManageRequest CycleWorkItemManageRequest 3801aec38b5ef633 +root CycleWorkItemManageResponse CycleWorkItemManageResponse 376a295ca755ca42 +root DependencyType DependencyType 3ed943095fdce55a +root EffectivePermissions EffectivePermissions 5d3fedb6e24b57e8 +root EmojiProps EmojiProps 2b5b186e421c9ec0 +root Epic Epic 317091a44bc58efc +root EpicIssue EpicIssue a7deff31aba8c4c9 +root Epics Epics f0f88f2f8e9a53f8 +root Estimate Estimate$1 50073ee60e066cec +root EstimateExpand EstimateExpand c8abfa612422fc68 +root EstimateField EstimateField a72670e931819453 +root EstimateOrderBy EstimateOrderBy e8f920d7a421c8fc +root EstimatePoint EstimatePoint$1 f9e824bb7eb2b0e4 +root EstimatePointField EstimatePointField 73543bf4db89824c +root EstimatePointOrderBy EstimatePointOrderBy a173c2a18bef005b +root Estimates Estimates$1 c6ad93728df328f2 +root EstimateType EstimateType$1 4a8b55aaf47d8ddc +root FieldError FieldError df6098511a10e607 +root GovernanceAllowlistEntry GovernanceAllowlistEntry b619fc6304300ab2 +root GovernancePreview GovernancePreview 5a0f9602158da11d +root GovernanceProjectRef GovernanceProjectRef 81341f1bf0bac27a +root GroupEnum GroupEnum 5bb159d3ed7c8729 +root GroupMapping GroupMapping ff3db5f0bfbcf8f7 +root GroupSyncConfig GroupSyncConfig 4455eac9705c96b0 +root GroupSyncProjectMappingField GroupSyncProjectMappingField cf293d1a76286806 +root GroupSyncProjectMappingOrderBy GroupSyncProjectMappingOrderBy 6cbe8f93433ebcd8 +root GroupSyncWorkspaceMappingField GroupSyncWorkspaceMappingField d3d387ed1a378977 +root GroupSyncWorkspaceMappingOrderBy GroupSyncWorkspaceMappingOrderBy 017930c76d4c1a70 +root HttpError HttpError 294e2313a6d41394 +root IconProps IconProps 6eb6c3e4073ada62 +root Initiative Initiative$1 4142dc37060b0b1b +root InitiativeChildManageRequest InitiativeChildManageRequest 26984f1c6dc5001a +root InitiativeChildManageResponse InitiativeChildManageResponse 3dd2aaf9bc0892e0 +root InitiativeEpics Epics$1 ac4849a10fb57f35 +root InitiativeExpand InitiativeExpand ad4566bf4bd06be5 +root InitiativeField InitiativeField 877efa7176c4065d +root InitiativeLabel InitiativeLabel$1 81b0b7affe1af58e +root InitiativeLabelField InitiativeLabelField ea1813f5569232ab +root InitiativeLabelOrderBy InitiativeLabelOrderBy bf922e9aeb78ea1c +root InitiativeLabels Labels$2 bd9986928d799bd4 +root InitiativeOrderBy InitiativeOrderBy 14d95f84f079cbb4 +root InitiativeProjects Projects$3 e83cb7de84a03405 +root Initiatives Initiatives$1 61b33657c48439c5 +root InitiativeState InitiativeState$1 d5be5f442a985ecc +root Intake Intake c78459a12fde46c4 +root IntakeWorkItem IntakeWorkItem$1 a54033b5c1d929fb +root IntakeWorkItemCreateRequest IntakeWorkItemCreateRequest b1f2db6caa073ad0 +root IntakeWorkItemField IntakeWorkItemField 153a1ead61185be2 +root IntakeWorkItemOrderBy IntakeWorkItemOrderBy 4f0bf5b0c4ec5626 +root IntakeWorkItemPriority IntakeWorkItemPriority 76f519c9e14b0883 +root IntakeWorkItemStatus IntakeWorkItemStatus 0392eaefd6792093 +root IntakeWorkItemStatusEnum IntakeWorkItemStatusEnum a6c4a890a453255c +root IssueRelationCreateRelationTypeEnum IssueRelationCreateRelationTypeEnum d26cd83acef741bb +root Label Label$1 1a3d206eaf66b328 +root LabelField LabelField 1cb4954299d1f58d +root LabelOrderBy LabelOrderBy 78061de0aa62f19a +root Labels Labels$1 a929eeae9b34c9e6 +root Link Link 928f7dcf8df3f5f9 +root LinkedIssue LinkedIssue 639cf20123331779 +root LinkIssuesToCustomerResponse LinkIssuesToCustomerResponse 38629d299193dffe +root Links Links$2 d2e65c95ee6eac69 +root ListAttachmentsParams ListAttachmentsParams 97f2be8c1a10aa2d +root ListAuditLogsParams ListAuditLogsParams 127e7e04aa016361 +root ListCollectionMembersParams ListCollectionMembersParams 1e7688adef363b6a +root ListCollectionPagesParams ListCollectionPagesParams 56567de1aa6953a0 +root ListCollectionsParams ListCollectionsParams c4090e86646b29d1 +root ListCommentsParams ListCommentsParams 2166686f7b03fde3 +root ListCustomerPropertiesParams ListCustomerPropertiesParams d68c184ddb2ae4e4 +root ListCustomerPropertiesParams ListCustomerPropertiesParams$1 871a93ce25a0243d +root ListCustomerPropertyValuesParams ListCustomerPropertyValuesParams d33d7943eb66b22c +root ListCustomerRequestsParams ListCustomerRequestsParams ca279d195d38a4f8 +root ListCustomerRequestsParams ListCustomerRequestsParams$1 7b1f7d6168d79468 +root ListCustomersParams ListCustomersParams 5b9fd4ff1008caf9 +root ListCustomersParams ListCustomersParams$1 8ab3b319d7924e70 +root ListCyclesLiteParams ListCyclesLiteParams 77cde90f2cf29adb +root ListCyclesParams ListCyclesParams 84497f1dba29c81d +root ListEstimatePointsParams ListEstimatePointsParams 6ce3ab8b6283ba42 +root ListEstimatesParams ListEstimatesParams 54c49f03977afe0b +root ListGroupSyncProjectMappingsParams ListGroupSyncProjectMappingsParams fcf04225a53a55ad +root ListGroupSyncWorkspaceMappingsParams ListGroupSyncWorkspaceMappingsParams e35c08913566efcc +root ListInitiativeLabelsParams ListInitiativeLabelsParams 6c9e512c8bb66b73 +root ListInitiativeLabelsParams ListInitiativeLabelsParams$1 1f240d14b7dd66e4 +root ListInitiativesParams ListInitiativesParams beb02c6bad4518ef +root ListInitiativesParams ListInitiativesParams$1 a8adc5407126753e +root ListIntakeWorkItemsParams ListIntakeWorkItemsParams cf64373c9046b061 +root ListInvitationsParams ListInvitationsParams fc471ff6e0e7c9d8 +root ListLabelsParams ListLabelsParams$1 e67ed5e903ccc1b0 +root ListLinksParams ListLinksParams 5d7f2058bba289aa +root ListMembersLiteParams ListMembersLiteParams 9fcb98c48eae947b +root ListMembersParams ListMembersParams ac4f33949067d6af +root ListMilestonesParams ListMilestonesParams 04dbbba27aee9293 +root ListModulesLiteParams ListModulesLiteParams 8b9bee78a786c225 +root ListModulesParams ListModulesParams f022eddc3da235b8 +root ListModulesParamsRequest ListModulesParamsRequest 9e1d663fd3174e0d +root ListPermissionSchemesParams ListPermissionSchemesParams c100bafbdc25b3f0 +root ListProjectAutomationActivitiesParams ListProjectAutomationActivitiesParams f8b9eea0990e43a6 +root ListProjectAutomationEdgesParams ListProjectAutomationEdgesParams d5f56ca6e4fb47a8 +root ListProjectAutomationNodesParams ListProjectAutomationNodesParams fb0f1d5ca16bc843 +root ListProjectAutomationsParams ListProjectAutomationsParams 5af857e6ff339645 +root ListProjectsLiteParams ListProjectsLiteParams 384f15d309be85b0 +root ListProjectsParams ListProjectsParams 795d6c2d945d08e1 +root ListProjectsParams ListProjectsParams$1 3db78e5a6a1ab3ba +root ListProjectViewsParams ListProjectViewsParams b61a0702c09b47cb +root ListProjectWorkItemTemplatesParams ListProjectWorkItemTemplatesParams 497c7be73e9ae288 +root ListReleaseCommentsParams ListReleaseCommentsParams 43b83e25a86994d0 +root ListReleaseLabelsParams ListReleaseLabelsParams b6f80d94e0ce7441 +root ListReleaseLinksParams ListReleaseLinksParams e7c06a524f4b6497 +root ListReleasesParams ListReleasesParams fc56513d1ecaff7b +root ListReleaseTagsParams ListReleaseTagsParams d0e040cdf31c107b +root ListRolesParams ListRolesParams e6b1c7152c75f276 +root ListRolesParams ListRolesParams$1 e0263b024e3faf4e +root ListStatesParams ListStatesParams$1 6e2fa0377d3f052d +root ListStickiesParams ListStickiesParams 78ca0e10e41f8cc5 +root ListStickiesParams ListStickiesParams$1 1cd379921f5a7c4f +root ListTeamspacesParams ListTeamspacesParams a2530356b285b185 +root ListTeamspacesParams ListTeamspacesParams$1 c28f2812c77dc449 +root ListUserAssetsParams ListUserAssetsParams 955c44dd793cf6f0 +root ListWebhookLogsParams ListWebhookLogsParams bfbc15559a0b7c16 +root ListWebhooksParams ListWebhooksParams 9ed9c2ea096b3cca +root ListWikiPagesParams ListWikiPagesParams 6d5816b8746c8f1d +root ListWorkflowActivitiesParams ListWorkflowActivitiesParams 0ff243eda596d2a1 +root ListWorkflowsParams ListWorkflowsParams bd77ea1f700e6d76 +root ListWorkflowStatesParams ListWorkflowStatesParams 6247782d6f999c56 +root ListWorkflowTransitionsParams ListWorkflowTransitionsParams 2efc137e7d812c99 +root ListWorkItemActivitiesParams ListWorkItemActivitiesParams f863e2ecd451c43d +root ListWorkItemAttachmentsParams ListWorkItemAttachmentsParams cd08f68361df001b +root ListWorkItemCommentsParams ListWorkItemCommentsParams 9162f8e580935db4 +root ListWorkItemLinksParams ListWorkItemLinksParams 83738f24f5a9ce43 +root ListWorkItemPropertiesParams ListWorkItemPropertiesParams 623b8ae8384aab35 +root ListWorkItemPropertiesParams ListWorkItemPropertiesParams$1 7bb5f97bbe5f93ae +root ListWorkItemPropertyContextsParams ListWorkItemPropertyContextsParams 8c28bd3585bc12bf +root ListWorkItemPropertyOptionsParams ListWorkItemPropertyOptionsParams 888744e881004fc9 +root ListWorkItemPropertyOptionsParams ListWorkItemPropertyOptionsParams$1 2211c81203ad46d1 +root ListWorkItemPropertyValuesParams ListWorkItemPropertyValuesParams b91f550591ccf565 +root ListWorkItemRelationDefinitionsParams ListWorkItemRelationDefinitionsParams 7f1eb6a23a69fb3d +root ListWorkItemRelationDefinitionsParams ListWorkItemRelationDefinitionsParams$1 f38025d690e196d5 +root ListWorkItemsParams ListWorkItemsParams a5075292c7b7b724 +root ListWorkItemsParams ListWorkItemsParams$1 3e1475a522170b3f +root ListWorkItemTypePropertiesParams ListWorkItemTypePropertiesParams 8768b3170b9e68a4 +root ListWorkItemTypesParams ListWorkItemTypesParams$1 62b35a8a7e7ccc91 +root ListWorkItemWorklogsParams ListWorkItemWorklogsParams 08c9bd0a5b7009d2 +root ListWorkspaceAssetsParams ListWorkspaceAssetsParams a5fc15e5155f33f6 +root ListWorkspaceAutomationActivitiesParams ListWorkspaceAutomationActivitiesParams c838a6e59b30663c +root ListWorkspaceAutomationEdgesParams ListWorkspaceAutomationEdgesParams 89bde391d647971a +root ListWorkspaceAutomationNodesParams ListWorkspaceAutomationNodesParams 0ccb3fce24f3c47b +root ListWorkspaceAutomationsParams ListWorkspaceAutomationsParams 673071924b8dcbd1 +root ListWorkspaceStatesParams ListWorkspaceStatesParams 3afb153072d53080 +root ListWorkspaceViewsParams ListWorkspaceViewsParams af6b06e643e452a6 +root ListWorkspaceWorkflowActivitiesParams ListWorkspaceWorkflowActivitiesParams 97336af9841ade9b +root ListWorkspaceWorkflowsParams ListWorkspaceWorkflowsParams 3c21f8db4cd86158 +root ListWorkspaceWorkItemPropertiesParams ListWorkspaceWorkItemPropertiesParams 12fd5963f5cb85ba +root ListWorkspaceWorkItemPropertyOptionsParams ListWorkspaceWorkItemPropertyOptionsParams f066d5a150834da4 +root ListWorkspaceWorkItemTemplatesParams ListWorkspaceWorkItemTemplatesParams 3f2626a07ef947cf +root LogoProps LogoProps ce15740131cd3ada +root Milestone Milestone$1 df91e57ba002bb01 +root MilestoneField MilestoneField 74ee192821873a9d +root MilestoneLite MilestoneLite 964b4d0922ba828c +root MilestoneOrderBy MilestoneOrderBy 63669b4c202a0277 +root Milestones Milestones$1 4e051ac6c7c6fe10 +root MilestoneWorkItem MilestoneWorkItem ee266b1578b23afb +root MilestoneWorkItemManageRequest MilestoneWorkItemManageRequest d1bd62275d63e8a6 +root MilestoneWorkItemManageResponse MilestoneWorkItemManageResponse 21ccd825af69df65 +root Module Module$1 afd67b25123ff3e5 +root ModuleExpand ModuleExpand 3ca14255e4d68f8b +root ModuleField ModuleField b7c2ad060968d034 +root ModuleLite ModuleLite 6527c072304c231e +root ModuleOrderBy ModuleOrderBy 13e4a0d13d4e219f +root Modules Modules$1 e832a9adee5f631f +root ModuleStatus ModuleStatus 979b917001040ec1 +root ModuleStatusEnum ModuleStatusEnum 36a3095d7a795797 +root ModuleWorkItem ModuleWorkItem 0e1ee923a31cf533 +root ModuleWorkItemManageRequest ModuleWorkItemManageRequest 9e48a701cdce7586 +root ModuleWorkItemManageResponse ModuleWorkItemManageResponse 8c55c81162f81356 +root MultipleMatchesFoundError MultipleMatchesFoundError a43d516b20ffd8de +root NoMatchFoundError NoMatchFoundError 516c9f16597fbaf8 +root OAuthClient OAuthClient 6d42abee5ec71281 +root OffsetPage OffsetPage 3639ecb8335d995a +root OperationId OperationId 3f2e44003f343483 +root Page Page$2 9b5ee3ba6a3dd55c +root PageAccess PageAccess c29bd17f6f76b771 +root Pages Pages$1 face42f8ba3d9a6b +root PageTemplate PageTemplate 14210776c729ed6c +root PageTypeFilter PageTypeFilter 5052d179f8b2b6e3 +root PaginatedResponse PaginatedResponse bb56e5d1db659d1c +root PaginatedWorkspaceWorkflowResponse PaginatedWorkspaceWorkflowResponse ff6b64123b21de04 +root PermissionScheme PermissionScheme 9c0370380767af8f +root PermissionSchemeField PermissionSchemeField faeff22d67396fa5 +root PermissionSchemeNamespace PermissionSchemeNamespace 8c46326a7bc467f7 +root PermissionSchemeOrderBy PermissionSchemeOrderBy 3e26629a8e0ccce0 +root PlaneApiError PlaneApiError 7e2374a3de80221b +root PlaneClient PlaneClient 0a85fda8d02f1bbc +root PlaneError PlaneError 82e771135cd4b51d +root PlaneNetworkError PlaneNetworkError 0bb41c61cfdfebd6 +root PlaneOAuthAppInstallation PlaneOAuthAppInstallation d6ac941eb8e46193 +root PlaneOAuthTokenResponse PlaneOAuthTokenResponse 79f6ccc603405fab +root PrincipalKind PrincipalKind 64efd7e371867254 +root PriorityEnum PriorityEnum f63712631f62b6d5 +root ProblemDetail ProblemDetail e770bfd2a35c1616 +root Project Project$2 b46f504d4b8d4a25 +root ProjectAutomationActivityField ProjectAutomationActivityField dd421bca3ca52c68 +root ProjectAutomationActivityOrderBy ProjectAutomationActivityOrderBy 6b5183d1b9cf9fcf +root ProjectAutomationEdgeField ProjectAutomationEdgeField 29ac63649e456137 +root ProjectAutomationEdgeOrderBy ProjectAutomationEdgeOrderBy a519ba1c88058c72 +root ProjectAutomationField ProjectAutomationField d400335313e35e77 +root ProjectAutomationNodeField ProjectAutomationNodeField 8c9b05ce4d597e4e +root ProjectAutomationNodeOrderBy ProjectAutomationNodeOrderBy 244ec346f7bb3cbf +root ProjectAutomationOrderBy ProjectAutomationOrderBy 2a3e9f3ba5cfb0bf +root ProjectExpand ProjectExpand a0fc9f9b5cac2cb6 +root ProjectFeature ProjectFeature 42b4d6e963929de7 +root ProjectFeatures ProjectFeatures$1 2bf5a904eb398333 +root ProjectField ProjectField 9b8ee9892cac9e0a +root ProjectLite ProjectLite c7c2914df465a309 +root ProjectMember ProjectMember$1 453b07502998963f +root ProjectMemberExpand ProjectMemberExpand 9976c35da35a0126 +root ProjectMemberField ProjectMemberField 68271db1c9f5988f +root ProjectMemberOrderBy ProjectMemberOrderBy e202223c48fc34a9 +root ProjectNetwork ProjectNetwork 892c9609df0af367 +root ProjectOrderBy ProjectOrderBy 769c526f6d4d34dc +root ProjectPageTemplates Pages$4 d1026e9ce53705ae +root ProjectPriority ProjectPriority 88a469bcef56ac01 +root ProjectRoleDistribution ProjectRoleDistribution$1 688e06f112d79bf6 +root ProjectRoleDistributionEntry ProjectRoleDistributionEntry$1 bef4bda2848946b5 +root Projects Projects$1 b6859ec15a50a48d +root ProjectSummary ProjectSummary d65cc65ce9e01fe5 +root ProjectSummaryCount ProjectSummaryCount a56d0cafb6046549 +root ProjectTemplates ProjectTemplates b1e0bab17e0c95dc +root ProjectTimezone ProjectTimezone 2af873c204b08948 +root ProjectTypeWorkflow ProjectTypeWorkflow dcadb1ebcca53d7c +root ProjectTypeWorkflows ProjectWorkflows b7c56692cb749a18 +root ProjectViewOrderBy ProjectViewOrderBy ad8cf1c8aef1ae5a +root ProjectWorkflowPickResult ProjectWorkflowPickResult 30eae8d7c955a00c +root ProjectWorkItemTemplates WorkItems$4 5ce2a347cfa3551a +root PropertyRelationType PropertyRelationType 5f402ef77ff8b22e +root PropertyType PropertyType 6cd58d6f37f54af9 +root Release Release$1 cf6bbf767217dc91 +root ReleaseChangelog ReleaseChangelog$1 66538285fea72acc +root ReleaseChangelogResource Changelog$1 9ba6e3cb0b90f118 +root ReleaseChildManageRequest ReleaseChildManageRequest 84c11c460805adfa +root ReleaseChildManageResponse ReleaseChildManageResponse efba3f700f21df9b +root ReleaseComment ReleaseComment$1 580102eb6a0aee1c +root ReleaseCommentField ReleaseCommentField 349df34fc725a8c8 +root ReleaseCommentOrderBy ReleaseCommentOrderBy cef45ad092a34e2f +root ReleaseComments Comments$3 ca9157f84aacbc09 +root ReleaseExpand ReleaseExpand 3502617cca8d61d4 +root ReleaseField ReleaseField 499ab3818f4b3109 +root ReleaseItemLabels ItemLabels 507a4fefa2055d70 +root ReleaseLabel ReleaseLabel$1 c515088b6f17aa92 +root ReleaseLabelField ReleaseLabelField d289559fa32ee5d4 +root ReleaseLabelOrderBy ReleaseLabelOrderBy b8f49f6ce063c845 +root ReleaseLabels Labels$3 3ea0932e400673b6 +root ReleaseLink ReleaseLink$1 05527c80608a1c37 +root ReleaseLinkField ReleaseLinkField d9aed3beb7b7341f +root ReleaseLinkOrderBy ReleaseLinkOrderBy 848c452b7755dda7 +root ReleaseLinks Links$3 55229b3f4762953e +root ReleaseOrderBy ReleaseOrderBy a7f347071a76ae95 +root Releases Releases$1 ba35112122cbd4b9 +root ReleaseStatus ReleaseStatus$1 6ff81d7c7dbd4413 +root ReleaseStatusFilter ReleaseStatusFilter d7d8095303a2d206 +root ReleaseTag ReleaseTag$1 0dd988c4efa89124 +root ReleaseTagField ReleaseTagField 04b2d3c20f2d15cc +root ReleaseTagOrderBy ReleaseTagOrderBy 235fab9b00a78cd7 +root ReleaseTags Tags 0e7155950d78390d +root ReleaseWorkItem ReleaseWorkItem 197e573f1a5b1c83 +root ReleaseWorkItems WorkItems$3 5be6361eba6d2074 +root RemoveCycleIssuesRequestRequest RemoveCycleIssuesRequestRequest 4f49b7fff51d6a19 +root RemoveInitiativeEpicsRequest RemoveInitiativeEpicsRequest baad4f6ec5b883d3 +root RemoveInitiativeLabelsRequest RemoveInitiativeLabelsRequest b5735e3f255e412c +root RemoveInitiativeProjectsRequest RemoveInitiativeProjectsRequest 57db26014fd0b23e +root RemoveReleaseItemLabel RemoveReleaseItemLabel e773b24b75b94c9d +root RemoveReleaseWorkItems RemoveReleaseWorkItems bfbddac452d9649d +root RemoveTeamspaceMembersRequest RemoveTeamspaceMembersRequest 3fdb94634e5a0385 +root RemoveTeamspaceProjectsRequest RemoveTeamspaceProjectsRequest 86bd33d72e7a34f6 +root RemoveWorkspaceWorkflowState RemoveWorkspaceWorkflowState 0e9bf5130afa56f1 +root ResponseEntity ResponseEntity f4502bde26dca136 +root Role Role$1 5dc96afcd19d6bb0 +root RoleField RoleField 685a79b673e0226d +root RoleNamespace RoleNamespace$1 201562db38902823 +root RoleOrderBy RoleOrderBy 8b385fd82025b4a7 +root Roles Roles$1 6e2ebb7857f091b0 +root RoleStatus RoleStatus c4c913d1c1e34f5c +root ServerGeneratedFields ServerGeneratedFields 27110874988a2fab +root SetAutomationStatus SetAutomationStatus 3381db7b291bf701 +root SetCustomerPropertyValues SetCustomerPropertyValues 7821df6fee56f26b +root SetProjectWorkflowPick SetProjectWorkflowPick 8b78068c250f413a +root State State$1 40646a1277c241ff +root StateField StateField 2cfc8b18cdcd8b6c +root StateGroup StateGroup 727c5fd9e0bc44fc +root StateOrderBy StateOrderBy e774918b4ce3928b +root States States$1 ca29e07575b6897f +root Stickies Stickies$1 b681c2e17eb5bfa1 +root Sticky Sticky$1 254b45a34412a145 +root StickyField StickyField 643b8430d75e9720 +root StickyOrderBy StickyOrderBy bd49f4cf606fd7fa +root SubmitWorkItemApproval SubmitWorkItemApproval e05baade0aeb8934 +root Teamspace Teamspace$1 897aaec6f2d51519 +root TeamspaceExpand TeamspaceExpand e9abd665df475ac7 +root TeamspaceField TeamspaceField 24a982f0a3a951d9 +root TeamspaceMembers Members$1 3f93a7125d087847 +root TeamspaceOrderBy TeamspaceOrderBy 4f18b39476c75a5b +root TeamspaceProjects Projects$2 706ea8cafb88fa2c +root Teamspaces Teamspaces$1 744a560ad586760c +root TextSettings TextSettings f690e547b649db3e +root TimezoneEnum TimezoneEnum 43d1fc5dc5ede582 +root TransferCycleIssueRequestRequest TransferCycleIssueRequestRequest 2d7cc9f1a7455d3d +root TransferCycleWorkItemRequest TransferCycleWorkItemRequest 25e69cc1b8fed867 +root TypeGovernance TypeGovernance 7be13b50fed6b8d5 +root TypeGovernanceMode TypeGovernanceMode ac8294550a15f1b5 +root TypeGovernancePreviewRequest TypeGovernancePreviewRequest 6aeaac4c32788449 +root UpdateArtifactUpdate UpdateArtifactUpdate 08a79442bfe70e67 +root UpdateAutomation UpdateAutomation 3952af2d12b710c8 +root UpdateAutomationEdge UpdateAutomationEdge ba474c409312db8f +root UpdateAutomationNode UpdateAutomationNode e33b9e2bc159abb0 +root UpdateCollection UpdateCollection$1 37f1c6cb1077ee55 +root UpdateCollectionMember UpdateCollectionMember 666db61788c83904 +root UpdateCollectionPage UpdateCollectionPage f1ba419b598788d8 +root UpdateCustomer UpdateCustomer$1 07514df5c6112dc4 +root UpdateCustomerProperty UpdateCustomerProperty 58cdd9a89580f0e0 +root UpdateCustomerPropertyRequest UpdateCustomerPropertyRequest e907cf34064f40a7 +root UpdateCustomerPropertyValue UpdateCustomerPropertyValue 60f25edbb6c8a557 +root UpdateCustomerRequest UpdateCustomerRequest$1 9492d2887887f4bf +root UpdateCycle UpdateCycle d7a6321443f778fc +root UpdateCycleRequest UpdateCycleRequest 633c449f7634a34a +root UpdateEntity UpdateEntity 42b752b777fbae51 +root UpdateEpic UpdateEpic 803b8f8ab713d25e +root UpdateEstimate UpdateEstimate 0fae5e80e8f23562 +root UpdateEstimatePoint UpdateEstimatePoint b364d256f416d2c4 +root UpdateEstimatePointRequest UpdateEstimatePointRequest 0d2700291698bd82 +root UpdateEstimateRequest UpdateEstimateRequest d1e8d47ab64d2351 +root UpdateGroupMapping UpdateGroupMapping a8b0103ea9545567 +root UpdateGroupSyncConfig UpdateGroupSyncConfig 5d4a6061b7cac084 +root UpdateInitiative UpdateInitiative$1 c286793b59869f2c +root UpdateInitiativeLabel UpdateInitiativeLabel$1 85574564f25c6d82 +root UpdateIntakeStatusRequest UpdateIntakeStatusRequest 8412b63b697c0a05 +root UpdateIntakeWorkItem UpdateIntakeWorkItem 0819548552b05e34 +root UpdateIntakeWorkItemRequest UpdateIntakeWorkItemRequest 9d8d147108bbdb83 +root UpdateLabel UpdateLabel$1 a16d7926d0e985d8 +root UpdateLink UpdateLink d14e5d588bd33b63 +root UpdateMilestone UpdateMilestone 708a4ffb2af887e7 +root UpdateMilestoneRequest UpdateMilestoneRequest f8477d6638c3d8fa +root UpdateModule UpdateModule 46f5948435452482 +root UpdateModuleRequest UpdateModuleRequest 732071ee96c0d820 +root UpdatePage UpdatePage$1 d0d0dc396e2c19bd +root UpdatePageTemplate UpdatePageTemplate 259408ee90aa4f03 +root UpdateProject UpdateProject$1 80e2890a74be44c2 +root UpdateProjectFeature UpdateProjectFeature 9b0f329f380ff2bf +root UpdateProjectFeatures UpdateProjectFeatures b9524e9021285417 +root UpdateProjectMember UpdateProjectMember bde5f9197f382551 +root UpdateRelease UpdateRelease$1 795308db5cd700fb +root UpdateReleaseChangelog UpdateReleaseChangelog$1 cda3498087a583ef +root UpdateReleaseComment UpdateReleaseComment$1 bf24526453e45986 +root UpdateReleaseLabel UpdateReleaseLabel$1 d3ce80cc6c6eae46 +root UpdateReleaseLink UpdateReleaseLink$1 847f78db8b86661e +root UpdateReleaseTag UpdateReleaseTag$1 6336b55277b8084d +root UpdateState UpdateState$1 37156716d4054994 +root UpdateSticky UpdateSticky$1 2bb4bad0e1d9bfc6 +root UpdateTeamspace UpdateTeamspace$1 8d4d0691624dc911 +root UpdateTypeGovernance UpdateTypeGovernance ba2fff182138554f +root UpdateView UpdateView 6040aff91b83ecc6 +root UpdateWebhook UpdateWebhook 8045e2f55d040ebb +root UpdateWorkflow UpdateWorkflow$1 0929b3752ee0fe44 +root UpdateWorkflowState UpdateWorkflowState$1 ecb713c892cf7421 +root UpdateWorkflowTransition UpdateWorkflowTransition$1 9190e212b49f3955 +root UpdateWorkflowTransitionHook UpdateWorkflowTransitionHook 5b56015072b853f6 +root UpdateWorkItem UpdateWorkItem$1 77833463edc21c90 +root UpdateWorkItemAttachmentRequest UpdateWorkItemAttachmentRequest 22b4f17db1cfe987 +root UpdateWorkItemComment UpdateWorkItemComment 4f6aaf6666082c30 +root UpdateWorkItemLink UpdateWorkItemLink 67f7ea8ef968edfb +root UpdateWorkItemProperty UpdateWorkItemProperty$1 c062887b65f5eaa7 +root UpdateWorkItemPropertyContext UpdateWorkItemPropertyContext b19d5a82a8ce76ef +root UpdateWorkItemPropertyOption UpdateWorkItemPropertyOption$1 6d23dbf98435bcec +root UpdateWorkItemPropertyValue UpdateWorkItemPropertyValue 223f7ca36e4bcee8 +root UpdateWorkItemRelationDefinition UpdateWorkItemRelationDefinition$1 dad02a1ef882b7c4 +root UpdateWorkItemTemplate UpdateWorkItemTemplate$1 856cdfea975105b7 +root UpdateWorkItemType UpdateWorkItemType$1 7db0326070f3a59e +root UpdateWorkItemWorklog UpdateWorkItemWorklog a5682731a39d9298 +root UpdateWorkLogRequest UpdateWorkLogRequest ae5e55219d580cc8 +root UpdateWorkspaceFeature UpdateWorkspaceFeature e40bf6d71e4227e2 +root UpdateWorkspaceFeatures UpdateWorkspaceFeatures 42d3696fd8c8c922 +root UpdateWorkspaceGroupMapping UpdateWorkspaceGroupMapping fc0284ad874d00d5 +root UpdateWorkspacePageTemplate UpdateWorkspacePageTemplate 8b1ff26fc4e2783f +root UpdateWorkspaceProjectLabel UpdateWorkspaceProjectLabel 8443ec6b0a284355 +root UpdateWorkspaceProjectState UpdateWorkspaceProjectState 00fd3ff563ecec7b +root UpdateWorkspaceProjectTemplate UpdateWorkspaceProjectTemplate 2c0dad03b52fa838 +root UpdateWorkspaceState UpdateWorkspaceState fecf5d3acae6acff +root UpdateWorkspaceWorkflow UpdateWorkspaceWorkflow dc4db1c67129ee1c +root UpdateWorkspaceWorkflowState UpdateWorkspaceWorkflowState d74723a3cc89e845 +root UpdateWorkspaceWorkflowTransition UpdateWorkspaceWorkflowTransition c2d01e699e1eb072 +root UpdateWorkspaceWorkItemTemplate UpdateWorkspaceWorkItemTemplate 6e5293515308c1f1 +root User User 339dcd9f1e12d3c7 +root UserAsset UserAsset 6e7bd857178f4602 +root UserAssetConfirmRequest UserAssetConfirmRequest af6c3faa9c7ad67b +root UserAssetEntityType UserAssetEntityType$1 a8816e0206acc619 +root UserAssetField UserAssetField 0e0bf67e1a131656 +root UserAssetOrderBy UserAssetOrderBy 4e2343a9f5de9e0f +root UserAssetUploadRequest UserAssetUploadRequest$1 305081144f9f5742 +root UserAssetUploadResponse UserAssetUploadResponse 4cd2bb8a9ebe30dc +root Users Users$1 bbcfbceee7cd2c83 +root v2 v2 namespace +root V2Collection Collection b3da5314afe85263 +root V2CollectionMember CollectionMember e44b8601044d34fa +root V2CollectionMemberAccess CollectionMemberAccess 65f60ad10486e9bc +root V2CreateCollection CreateCollection 3afdde594a24fc08 +root V2CreateCustomer CreateCustomer 2753bb4021ecdd7c +root V2CreateCustomerRequest CreateCustomerRequest 533215d178fc1df4 +root V2CreateInitiative CreateInitiative 8f4099f47c7638b6 +root V2CreateInitiativeLabel CreateInitiativeLabel 8c644464f2bb02b1 +root V2CreateLabel CreateLabel 406ce08dd73c9cfa +root V2CreatePage CreatePage 6bee3e8079aa1aca +root V2CreateProject CreateProject 8a133e5f6907c361 +root V2CreateRelease CreateRelease e8f88902aef95ae2 +root V2CreateReleaseComment CreateReleaseComment b3bf0f1fdf14e191 +root V2CreateReleaseLabel CreateReleaseLabel cb65eda9e6cb2d93 +root V2CreateReleaseLink CreateReleaseLink eadfa787c5d284bf +root V2CreateReleaseTag CreateReleaseTag 5b3e084f8c0a45b0 +root V2CreateState CreateState e0e6d597796ba45d +root V2CreateSticky CreateSticky 663e956c171ed192 +root V2CreateTeamspace CreateTeamspace 5c83a8d5ff4fb9b3 +root V2CreateWorkflow CreateWorkflow 9f847ecc05a6e64f +root V2CreateWorkflowTransition CreateWorkflowTransition 08c3078eb1e4ad81 +root V2CreateWorkItem CreateWorkItem eb2dde4ebf77e21e +root V2CreateWorkItemProperty CreateWorkItemProperty ebc861a8f3b03b82 +root V2CreateWorkItemPropertyOption CreateWorkItemPropertyOption 52dda92e24675925 +root V2CreateWorkItemRelationDefinition CreateWorkItemRelationDefinition 80a9d077d3a7df4d +root V2CreateWorkItemTemplate CreateWorkItemTemplate 82d42c0b427052e8 +root V2CreateWorkItemType CreateWorkItemType 6455106b39dd4b1d +root V2Customer Customer 89d52a530f3465fc +root V2CustomerProperty CustomerProperty 36edbe2c51ea4a4e +root V2CustomerRequest CustomerRequest 918f9ce3c12e4dab +root V2Cycle Cycle 0fbe8469e892070f +root V2Estimate Estimate 66f37d2b160c0e65 +root V2EstimatePoint EstimatePoint a3601e3fbc67fd61 +root V2EstimateType EstimateType 0c64e6b657463cb7 +root V2Initiative Initiative 4bda43ed6c5b8ff0 +root V2InitiativeLabel InitiativeLabel 4c230e92ee25c1d5 +root V2InitiativeState InitiativeState 131e07d51d1f5490 +root V2IntakeWorkItem IntakeWorkItem 5f0ba6c0b1237377 +root V2Label Label 0d571a0f4f949e70 +root V2ListLabelsParams ListLabelsParams 5dad39f1052a3722 +root V2ListStatesParams ListStatesParams a60ca9f12fd8849e +root V2ListWorkItemTypesParams ListWorkItemTypesParams 090890210f2122c7 +root V2Milestone Milestone 836c22d96d67bb88 +root v2models v2models namespace +root V2Module Module 117398c9173cc59d +root V2Page Page$1 20725d97c3eeef0b +root V2PageEnvelope Page b84ccdfa1fd8b168 +root V2Project Project$1 0a71c767c7fa97d0 +root V2ProjectMember ProjectMember 0d4bfd30ad66bcd7 +root V2ProjectRoleDistribution ProjectRoleDistribution 85401e979a918a6a +root V2ProjectRoleDistributionEntry ProjectRoleDistributionEntry 7e4a87a4cfa6eca3 +root V2Release Release 0940bc25daf39998 +root V2ReleaseChangelog ReleaseChangelog 98833192273238f9 +root V2ReleaseComment ReleaseComment c237f08be061127a +root V2ReleaseLabel ReleaseLabel 75322f8f368c87ac +root V2ReleaseLink ReleaseLink 6e2e4a9915346ab1 +root V2ReleaseStatus ReleaseStatus 8fb6f688ae374061 +root V2ReleaseTag ReleaseTag efbdb2a4feba1308 +root V2Role Role df26fef9334fb8b0 +root V2RoleNamespace RoleNamespace c5203a2ede46846a +root V2State State 8217bc51d82bec16 +root V2Sticky Sticky 44d29dcba60165af +root V2Teamspace Teamspace bf5b6bfb03068eb1 +root V2UpdateCollection UpdateCollection 75adbf48b2a7ae2d +root V2UpdateCustomer UpdateCustomer 6b5748efdd6f51f2 +root V2UpdateCustomerRequest UpdateCustomerRequest 56dc022c5393d39f +root V2UpdateInitiative UpdateInitiative aa23a9f356198987 +root V2UpdateInitiativeLabel UpdateInitiativeLabel 3678adfeb73cd0e1 +root V2UpdateLabel UpdateLabel 591b4c25ca9c0b30 +root V2UpdatePage UpdatePage 4a178c9c56e1811d +root V2UpdateProject UpdateProject f460a40c9e894342 +root V2UpdateRelease UpdateRelease bca361ca10ce6c55 +root V2UpdateReleaseChangelog UpdateReleaseChangelog f6da33b1e5b55ec4 +root V2UpdateReleaseComment UpdateReleaseComment 6ce61cb3a7a40f50 +root V2UpdateReleaseLabel UpdateReleaseLabel ee822e7b91513027 +root V2UpdateReleaseLink UpdateReleaseLink 5ab44dd4e75cf5a3 +root V2UpdateReleaseTag UpdateReleaseTag 3ffffa4220c586c7 +root V2UpdateState UpdateState 2bb063c3ae85f516 +root V2UpdateSticky UpdateSticky 11183a46f2ad7aaa +root V2UpdateTeamspace UpdateTeamspace 5b94d58a57096af9 +root V2UpdateWorkflow UpdateWorkflow 2514997086df26d2 +root V2UpdateWorkflowState UpdateWorkflowState 1481f93616e5580a +root V2UpdateWorkflowTransition UpdateWorkflowTransition fd3e0df1661fd28b +root V2UpdateWorkItem UpdateWorkItem 7ddc6dda7f7b9655 +root V2UpdateWorkItemProperty UpdateWorkItemProperty 8e153af041482f4a +root V2UpdateWorkItemPropertyOption UpdateWorkItemPropertyOption 2101d5a2cd79e7a3 +root V2UpdateWorkItemRelationDefinition UpdateWorkItemRelationDefinition 3dfeb24782588c6d +root V2UpdateWorkItemTemplate UpdateWorkItemTemplate d0b70c45fd61c1ae +root V2UpdateWorkItemType UpdateWorkItemType f8a49123a0320ccf +root V2UserAssetEntityType UserAssetEntityType c2ff0464a0ca1955 +root V2UserAssetUploadRequest UserAssetUploadRequest 8196be1c483125df +root V2Workflow Workflow af044ee329fcfaea +root V2WorkflowState WorkflowState dcdeb244246c7a20 +root V2WorkflowTransition WorkflowTransition 91709ea37dd8f80d +root V2WorkItem WorkItem cf8e4c901f20f86b +root V2WorkItemActivity WorkItemActivity 479b9e62504dc90b +root V2WorkItemAttachment WorkItemAttachment 5f0ed46fecab1c34 +root V2WorkItemAttachmentUploadRequest WorkItemAttachmentUploadRequest db4f35af2983de91 +root V2WorkItemComment WorkItemComment 53ab830e7b16b0fb +root V2WorkItemProperty WorkItemProperty efe53b7ffc0846c4 +root V2WorkItemRelationCreateRequest WorkItemRelationCreateRequest 4b7dad64fafb3e86 +root V2WorkItemRelationDefinition WorkItemRelationDefinition b82ddab4e7b520fe +root V2WorkItemTemplate WorkItemTemplate 4331780b7911b0dc +root V2WorkItemType WorkItemType 508bb2d35eae8095 +root V2WorkspaceMember WorkspaceMember 70091e0cd3a80c10 +root View View 91c7781125f9509a +root ViewAccess ViewAccess cc7d00685fed9c95 +root ViewExpand ViewExpand 1b6d596512904eda +root ViewField ViewField e3bb957bde62e66d +root Webhook Webhook 51fb46f978ac1b19 +root WebhookContentType WebhookContentType d3f26efdb3421ac9 +root WebhookCreateResponse WebhookCreateResponse 00f2ef9f126d731b +root WebhookField WebhookField 487ec757ba2ac851 +root WebhookLog WebhookLog 86648f9796a85528 +root WebhookLogField WebhookLogField ef841fe1b9e60c05 +root WebhookLogOrderBy WebhookLogOrderBy ec2dca9ddef07b93 +root WebhookOrderBy WebhookOrderBy 8208ef1cf8b386b0 +root WhoAmI WhoAmI 9bda88ee24634842 +root WikiPageExpand WikiPageExpand b41bd04e55582fc9 +root WikiPageField WikiPageField bd8a2930ea927502 +root WikiPageOrderBy WikiPageOrderBy 3a466d4c1bcc4994 +root Workflow Workflow$1 258dbb8188bcec47 +root WorkflowActivity WorkflowActivity f5a287a1bcfad9d3 +root WorkflowFallbackPreviewRequest WorkflowFallbackPreviewRequest a9bfc23284a8fa2b +root WorkflowField WorkflowField 74d9d0fd10d60571 +root WorkflowLite WorkflowLite 9585a012d83a0c30 +root WorkflowOption WorkflowOption 687f630c19165ac0 +root WorkflowOrderBy WorkflowOrderBy bd7965a04fd6edf7 +root Workflows Workflows$1 8dec1eee61b10b41 +root WorkflowState WorkflowState$1 f3c62c3b84e3ab40 +root WorkflowStateAttachRequest WorkflowStateAttachRequest 05957276dd6fdf7c +root WorkflowStateField WorkflowStateField 3e42b0eab3eed710 +root WorkflowStateKind WorkflowStateKind 9cca0502be00b262 +root WorkflowStateOrderBy WorkflowStateOrderBy e862a2637af72d50 +root WorkflowStates States$2 f5955ad502f80ecd +root WorkflowTransition WorkflowTransition$1 8c18fb9f4eaba9e7 +root WorkflowTransitionField WorkflowTransitionField f49e34b220daf994 +root WorkflowTransitionHook WorkflowTransitionHook 17409c8325d5a5c7 +root WorkflowTransitionHookExecution WorkflowTransitionHookExecution 55c07ef948066f6e +root WorkflowTransitionHooks Hooks 3ca69b55cd24e3eb +root WorkflowTransitionOrderBy WorkflowTransitionOrderBy fe6d5dbce6768210 +root WorkflowTransitions Transitions d78d09a868c4283d +root WorkItem WorkItem$1 6ee991ad576d8328 +root WorkItemActivities Activities$1 7a61b22a76724886 +root WorkItemActivity WorkItemActivity$1 9759a6909b603479 +root WorkItemActivityExpand WorkItemActivityExpand 1f6069e8442bdf0b +root WorkItemActivityField WorkItemActivityField 93ed28cb0f94c0a5 +root WorkItemActivityOrderBy WorkItemActivityOrderBy 938abeedca40289e +root WorkItemApprovalResult WorkItemApprovalResult a7034f7d0b20584b +root WorkItemAttachment WorkItemAttachment$1 3645cc7f74c0b55a +root WorkItemAttachmentConfirmRequest WorkItemAttachmentConfirmRequest 93bb2e58834936d3 +root WorkItemAttachmentField WorkItemAttachmentField 3ebfd0e73543fc29 +root WorkItemAttachmentOrderBy WorkItemAttachmentOrderBy f3288ee4ddf801a3 +root WorkItemAttachments Attachments$1 03fdeda6ecb8be20 +root WorkItemAttachmentUploadRequest WorkItemAttachmentUploadRequest$1 c1edb7f528e1ea4f +root WorkItemBase WorkItemBase 04945c0510272045 +root WorkItemComment WorkItemComment$1 43271f534e4cc6e5 +root WorkItemCommentAccess WorkItemCommentAccess 05a11ed083397eb5 +root WorkItemCommentCreateRequest WorkItemCommentCreateRequest 07d78a40ec0ce67f +root WorkItemCommentExpand WorkItemCommentExpand 8508c4526c7d0719 +root WorkItemCommentField WorkItemCommentField 6f0675f65f277f55 +root WorkItemCommentOrderBy WorkItemCommentOrderBy 6046a2fd92081ccd +root WorkItemComments Comments$2 3ba0e5993575993e +root WorkItemCommentUpdateRequest WorkItemCommentUpdateRequest 3edc552ca299f371 +root WorkItemCountEntry WorkItemCountEntry 2d655d7fdc53fb12 +root WorkItemCountParams WorkItemCountParams 09d72dd63ff6c054 +root WorkItemCountResponse WorkItemCountResponse 0a86c8921cc260eb +root WorkItemCustomFieldValue WorkItemCustomFieldValue e9d45e16f022cdb5 +root WorkItemCustomRelations CustomRelations 786cb45e5dd03424 +root WorkItemDependencies Dependencies$1 39cd651f8e883c6a +root WorkItemDependencyCreateRequest WorkItemDependencyCreateRequest b8a59553ddf19322 +root WorkItemDependencyList WorkItemDependencyList 4e605d3fd59e4d2c +root WorkItemDependencyRelationType WorkItemDependencyRelationType 6d2ce316fb1cbec2 +root WorkItemDependencyResponse WorkItemDependencyResponse 7db06250de5c479c +root WorkItemExpand WorkItemExpand 000e10aff7eb660e +root WorkItemExpandableFieldName WorkItemExpandableFieldName f7d3a7d57858f315 +root WorkItemExpandableFields WorkItemExpandableFields 9d296ae907b979fb +root WorkItemField WorkItemField 3da484aec508edd0 +root WorkItemForIntakeRequest WorkItemForIntakeRequest bd564e8d9e5d5f0c +root WorkItemLink WorkItemLink 19a1c8cc227f3eaf +root WorkItemLinkField WorkItemLinkField 1f060447b94fe3cc +root WorkItemLinkOrderBy WorkItemLinkOrderBy c76aba0c76a92eb5 +root WorkItemOrderBy WorkItemOrderBy 2e5db248118b1c9a +root WorkItemPage WorkItemPage 70e819a503f44a9c +root WorkItemPageLite WorkItemPageLite 622ee1ba3ab9149e +root WorkItemPages Pages f899173491a5d272 +root WorkItemPriority WorkItemPriority 2efcd2f83558fee6 +root WorkItemProperties WorkItemProperties$1 348f8acba214a1df +root WorkItemProperty WorkItemProperty$1 0b43021be7acb02d +root WorkItemPropertyContext WorkItemPropertyContext 6ee5c4e6cbde3ada +root WorkItemPropertyContextField WorkItemPropertyContextField dab2e8d14c4ae57d +root WorkItemPropertyContextOptionInput WorkItemPropertyContextOptionInput f611f84abd40fd6d +root WorkItemPropertyContextOrderBy WorkItemPropertyContextOrderBy 576846614cee13f5 +root WorkItemPropertyField WorkItemPropertyField 18992abd11aa30cb +root WorkItemPropertyOption WorkItemPropertyOption 0ce3034b458a4346 +root WorkItemPropertyOptionLite WorkItemPropertyOptionLite 0a8ba2fe5b710f2f +root WorkItemPropertyOptionOrderBy WorkItemPropertyOptionOrderBy 608a0ee69288e0f1 +root WorkItemPropertyOptions Options 9e9bfd84a3eb69aa +root WorkItemPropertyOptionSeed WorkItemPropertyOptionSeed 97a5ebc1ee2a0dab +root WorkItemPropertyOrderBy WorkItemPropertyOrderBy 91d69cd9ef13522d +root WorkItemPropertyRelationType WorkItemPropertyRelationType 2d2fc54f868bc762 +root WorkItemPropertySettings WorkItemPropertySettings 655ea56b1c16fdb3 +root WorkItemPropertyType WorkItemPropertyType e60994cc895bf11c +root WorkItemPropertyValue WorkItemPropertyValue 91e586665aacbe28 +root WorkItemPropertyValues WorkItemPropertyValues d4014050c7e0fea4 +root WorkItemPropertyValues Values cb2abfa681e961da +root WorkItemRelation WorkItemRelation 1b48e223ba35b073 +root WorkItemRelationCreateRequest WorkItemRelationCreateRequest$1 18172f4acc699cd0 +root WorkItemRelationDefinition WorkItemRelationDefinition$1 d217e346ff9547b4 +root WorkItemRelationDefinitionField WorkItemRelationDefinitionField 1739d027f8b0010c +root WorkItemRelationDefinitions WorkItemRelationDefinitions$1 8465249de7fba55a +root WorkItemRelationList WorkItemRelationList 6d5e946713382898 +root WorkItemRelationRemoveRequest WorkItemRelationRemoveRequest 5bbb93afefc32be0 +root WorkItemRelationResponse WorkItemRelationResponse a27e536becf02792 +root WorkItemRelations Relations$1 ae94a158bb9515c7 +root WorkItems WorkItems$1 69ead42d2e6929e5 +root WorkItemSearch WorkItemSearch 974da631fd7583d2 +root WorkItemSearchItem WorkItemSearchItem a666d687bce31d3d +root WorkItemTemplate WorkItemTemplate$1 2245da839e698489 +root WorkItemTemplateData WorkItemTemplateData fb644987980a439b +root WorkItemTemplateField WorkItemTemplateField b0fcbb132ca82025 +root WorkItemTemplateOrderBy WorkItemTemplateOrderBy 391d22d3b2f31757 +root WorkItemTemplateUseExpand WorkItemTemplateUseExpand 2d45a17a6c1d10c6 +root WorkItemTemplateUseField WorkItemTemplateUseField f5af67d618e36cf0 +root WorkItemTemplateUseRequest WorkItemTemplateUseRequest 6537904f31cda000 +root WorkItemType WorkItemType$1 01eeeb141ef15af1 +root WorkItemTypeField WorkItemTypeField 702e15690b1756be +root WorkItemTypeGovernance WorkItemTypeGovernance 305c480624c9086f +root WorkItemTypeOrderBy WorkItemTypeOrderBy 5df979b220808473 +root WorkItemTypePropertyField WorkItemTypePropertyField 544a8fef7a54d7cf +root WorkItemTypePropertyOrderBy WorkItemTypePropertyOrderBy 246f6cfc2091e45a +root WorkItemTypes WorkItemTypes$1 f9af8727552226a2 +root WorkItemTypeSchema WorkItemTypeSchema 08bbf210ab26071c +root WorkItemTypeWorkflowPin WorkItemTypeWorkflowPin f0b441091b42917d +root WorkItemTypeWorkflowPins Pins 595986b56f2456a1 +root WorkItemWithRelationType WorkItemWithRelationType 6b85b4e89016b942 +root WorkItemWorklog WorkItemWorklog 9c2fc684c856b4db +root WorkItemWorklogExpand WorkItemWorklogExpand d3067d396ca81f99 +root WorkItemWorklogField WorkItemWorklogField a159745004fd7286 +root WorkItemWorklogOrderBy WorkItemWorklogOrderBy e545e73884253e5c +root WorkLog WorkLog 90f273ede3ad2d88 +root WorkLogs WorkLogs$1 222ab67fa4d6bdc6 +root WorklogSummaryEntry WorklogSummaryEntry 62a9c9c9b87b025d +root Workspace Workspace$1 7870bade783326a9 +root WorkspaceAsset WorkspaceAsset 158f63c15d06b6c0 +root WorkspaceAssetConfirmRequest WorkspaceAssetConfirmRequest a9b006b236b1b790 +root WorkspaceAssetField WorkspaceAssetField 827cba08b2a129af +root WorkspaceAssetOrderBy WorkspaceAssetOrderBy 8aee13377cf9a336 +root WorkspaceAssetUploadRequest WorkspaceAssetUploadRequest 7ff4c2d40ba7438e +root WorkspaceAutomationActivityField WorkspaceAutomationActivityField 169b57a6aa3b95e4 +root WorkspaceAutomationActivityOrderBy WorkspaceAutomationActivityOrderBy 9cc50fe8dc5ddb4d +root WorkspaceAutomationEdgeField WorkspaceAutomationEdgeField 397b3073460f41a0 +root WorkspaceAutomationEdgeOrderBy WorkspaceAutomationEdgeOrderBy a755074d62760b66 +root WorkspaceAutomationField WorkspaceAutomationField 4e6252f8f09c63f2 +root WorkspaceAutomationNodeField WorkspaceAutomationNodeField f0953c79e1515c4b +root WorkspaceAutomationNodeOrderBy WorkspaceAutomationNodeOrderBy f7fd3c0a4e9ceac3 +root WorkspaceAutomationOrderBy WorkspaceAutomationOrderBy 44ed646668929c83 +root WorkspaceDetail WorkspaceDetail a54e4e7727b0aca5 +root WorkspaceFeature WorkspaceFeature 8ec1b6093060db65 +root WorkspaceFeatures WorkspaceFeatures$1 1f15501ed0a76740 +root WorkspaceGroupMapping WorkspaceGroupMapping fc4060333bc9b839 +root WorkspaceInvite WorkspaceInvite 4827ad84b88afe36 +root WorkspaceInviteField WorkspaceInviteField 3a2b66d4197c572d +root WorkspaceInviteOrderBy WorkspaceInviteOrderBy d1901ca37563d14d +root WorkspaceMember WorkspaceMember$1 b61f7162ec8d5356 +root WorkspaceMemberRemoveRequest WorkspaceMemberRemoveRequest 4aa6efab146d5e24 +root WorkspacePageTemplate WorkspacePageTemplate d209e4164ca13886 +root WorkspacePageTemplates Pages$3 2cc15181e9ebcbf7 +root WorkspaceProjectLabel WorkspaceProjectLabel a429972341041c5e +root WorkspaceProjectLabels WorkspaceProjectLabels 03315c043d99f7f9 +root WorkspaceProjectState WorkspaceProjectState 19f02430a5345b8c +root WorkspaceProjectStates WorkspaceProjectStates b62090f3daa94215 +root WorkspaceProjectTemplate WorkspaceProjectTemplate 44e9b4a4f2108f7a +root WorkspaceProjectTemplates Projects$4 cd08047c8ba2bd05 +root WorkspaceStates WorkspaceStates aaa1c34fc4c585b2 +root WorkspaceTemplates WorkspaceTemplates e5c624f470f55546 +root WorkspaceViewOrderBy WorkspaceViewOrderBy ea48a52e1e6e629d +root WorkspaceWorkflow WorkspaceWorkflow c6f13f923af229f1 +root WorkspaceWorkflows WorkspaceWorkflows 68b5cca36b2e6514 +root WorkspaceWorkflowState WorkspaceWorkflowState ed765acf73ba8486 +root WorkspaceWorkflowStates States$3 84dbe30bf3135afa +root WorkspaceWorkflowTransition WorkspaceWorkflowTransition 3eee80d675759ef4 +root WorkspaceWorkflowTransitionHooks Hooks$1 3f00b7d719086e68 +root WorkspaceWorkflowTransitions Transitions$1 ab0625d38c779cff +root WorkspaceWorkflowUsage WorkspaceWorkflowUsage f0c3dd27260ac953 +root WorkspaceWorkflowUsageProject WorkspaceWorkflowUsageProject ff3344a9852f8b68 +root WorkspaceWorkItemProperties WorkspaceWorkItemProperties$1 ad3ea260eee97aec +root WorkspaceWorkItemPropertyField WorkspaceWorkItemPropertyField 088f4f0bd82e7a26 +root WorkspaceWorkItemPropertyOptionOrderBy WorkspaceWorkItemPropertyOptionOrderBy 13382d34c16f6f57 +root WorkspaceWorkItemPropertyOptions Options$1 aeac9cf219f049c1 +root WorkspaceWorkItemPropertyOrderBy WorkspaceWorkItemPropertyOrderBy dcb582a7109e424a +root WorkspaceWorkItemTemplate WorkspaceWorkItemTemplate 353773bbf7425bbf +root WorkspaceWorkItemTemplateField WorkspaceWorkItemTemplateField ebccf9986a66dcd6 +root WorkspaceWorkItemTemplateOrderBy WorkspaceWorkItemTemplateOrderBy 96cf8171f05f86e8 +root WorkspaceWorkItemTemplates WorkItems$2 e41f16d6ba508918 +root WorkspaceWorkItemTypeProperties Properties$1 b6f1cc8592d0b98a +root WorkspaceWorkItemTypePropertyLink WorkspaceWorkItemTypePropertyLink 84e083962677ce8e +root WorkspaceWorkItemTypes WorkspaceWorkItemTypes$1 67c98e1797a2cb5e +v2 Activities Activities c0b15d8bddee749a +v2 Artifacts Artifacts 8fca422c0f9b1454 +v2 Assets Assets 18876d07931bec55 +v2 AttachedWorkItemTypeProperties AttachedWorkItemTypeProperties acd010d0807a6bde +v2 Attachments Attachments 2047834e19ff0404 +v2 AuditLogField AuditLogField de42bf6a11cdc85b +v2 AuditLogOrderBy AuditLogOrderBy e5a46079550cdac9 +v2 AuditLogs AuditLogs 0de9f440008702e8 +v2 Automations Automations f328793ab0dd71ed +v2 BULK_MAX_ITEMS BULK_MAX_ITEMS e8b374c37c376df9 +v2 bulkFailures bulkFailures b1f34c1e48580e6b +v2 CollectionExpand CollectionExpand 68923a08b96dccdf +v2 CollectionField CollectionField fa33e727203e0006 +v2 CollectionMemberExpand CollectionMemberExpand 2e8c17318ee22d9d +v2 CollectionMemberField CollectionMemberField 5ad47417381b3fca +v2 CollectionMembers CollectionMembers 56cf635d64e383c3 +v2 CollectionOrderBy CollectionOrderBy b141c12a97dab0c5 +v2 CollectionPages CollectionPages bb57f7fc3ea8835c +v2 CollectionPageSearchField CollectionPageSearchField 6ae76235d2a3b1ac +v2 Collections Collections b40a780ee83f3f85 +v2 Comments Comments bebcf53f55596389 +v2 CustomerField CustomerField 039dd6a06995ee5f +v2 CustomerOrderBy CustomerOrderBy f7a9e1ab0c718d10 +v2 CustomerProperties CustomerProperties d8012f7d9b0e5ab9 +v2 CustomerPropertyField CustomerPropertyField 2c47c1217ab07847 +v2 CustomerPropertyOrderBy CustomerPropertyOrderBy dfdb2d89b5562988 +v2 CustomerPropertyValues CustomerPropertyValues 8c221fad219fa892 +v2 CustomerRequestField CustomerRequestField b9db5f28b94dda8b +v2 CustomerRequestOrderBy CustomerRequestOrderBy c7f657f358bd2825 +v2 CustomerRequests CustomerRequests 68a496c059df0e6f +v2 Customers Customers 4c9e2207f22dc1e5 +v2 CycleExpand CycleExpand 0262965cca15fe32 +v2 CycleField CycleField bfc78230b96b361d +v2 CycleOrderBy CycleOrderBy 6b31c08b310b702d +v2 Cycles Cycles 0e7aec1d6b671559 +v2 Dependencies Dependencies bd35d189bee33133 +v2 EstimateExpand EstimateExpand c8abfa612422fc68 +v2 EstimateField EstimateField a72670e931819453 +v2 EstimateOrderBy EstimateOrderBy e8f920d7a421c8fc +v2 EstimatePointField EstimatePointField 73543bf4db89824c +v2 EstimatePointOrderBy EstimatePointOrderBy a173c2a18bef005b +v2 EstimatePoints EstimatePoints 18c728374d49ca6a +v2 Estimates Estimates 759798f0dc5bb370 +v2 EXPAND EXPAND 142e756475b2b6e3 +v2 FIELDS FIELDS 27c4afa6101bae31 +v2 GroupSync GroupSync d45169b6d64b731a +v2 GroupSyncConfigResource GroupSyncConfigResource bb1dc07cee95ec25 +v2 GroupSyncProjectMappingField GroupSyncProjectMappingField cf293d1a76286806 +v2 GroupSyncProjectMappingOrderBy GroupSyncProjectMappingOrderBy 6cbe8f93433ebcd8 +v2 GroupSyncProjectMappings GroupSyncProjectMappings e18f314771012f0e +v2 GroupSyncWorkspaceMappingField GroupSyncWorkspaceMappingField d3d387ed1a378977 +v2 GroupSyncWorkspaceMappingOrderBy GroupSyncWorkspaceMappingOrderBy 017930c76d4c1a70 +v2 GroupSyncWorkspaceMappings GroupSyncWorkspaceMappings a41ed9ebd7bf966f +v2 InitiativeExpand InitiativeExpand ad4566bf4bd06be5 +v2 InitiativeField InitiativeField 877efa7176c4065d +v2 InitiativeLabelField InitiativeLabelField ea1813f5569232ab +v2 InitiativeLabelOrderBy InitiativeLabelOrderBy bf922e9aeb78ea1c +v2 InitiativeLabels InitiativeLabels a29e2d0daf7f5cec +v2 InitiativeOrderBy InitiativeOrderBy 14d95f84f079cbb4 +v2 Initiatives Initiatives 86ceba8105630902 +v2 Intakes Intakes 8824e1a61743a685 +v2 IntakeWorkItemField IntakeWorkItemField 153a1ead61185be2 +v2 IntakeWorkItemOrderBy IntakeWorkItemOrderBy 4f0bf5b0c4ec5626 +v2 Invitations Invitations bf0c1b338fe19443 +v2 isBulkFailure isBulkFailure 66dd8bb47f1d20ce +v2 isCursorPage isCursorPage 7ad9cbee4c37b874 +v2 isOffsetPage isOffsetPage 47013f88bde92ac6 +v2 LabelField LabelField 1cb4954299d1f58d +v2 LabelOrderBy LabelOrderBy 78061de0aa62f19a +v2 Labels Labels 7654a8506526eccf +v2 Links Links 594acdaff9eeafd1 +v2 ListAuditLogsParams ListAuditLogsParams 127e7e04aa016361 +v2 ListCollectionMembersParams ListCollectionMembersParams 1e7688adef363b6a +v2 ListCollectionsParams ListCollectionsParams c4090e86646b29d1 +v2 ListCustomerPropertiesParams ListCustomerPropertiesParams d68c184ddb2ae4e4 +v2 ListCustomerRequestsParams ListCustomerRequestsParams ca279d195d38a4f8 +v2 ListCustomersParams ListCustomersParams 5b9fd4ff1008caf9 +v2 ListCyclesParams ListCyclesParams 84497f1dba29c81d +v2 ListEstimatePointsParams ListEstimatePointsParams 6ce3ab8b6283ba42 +v2 ListEstimatesParams ListEstimatesParams 54c49f03977afe0b +v2 ListGroupSyncProjectMappingsParams ListGroupSyncProjectMappingsParams fcf04225a53a55ad +v2 ListGroupSyncWorkspaceMappingsParams ListGroupSyncWorkspaceMappingsParams e35c08913566efcc +v2 ListInitiativeLabelsParams ListInitiativeLabelsParams 6c9e512c8bb66b73 +v2 ListInitiativesParams ListInitiativesParams beb02c6bad4518ef +v2 ListIntakeWorkItemsParams ListIntakeWorkItemsParams cf64373c9046b061 +v2 ListInvitationsParams ListInvitationsParams fc471ff6e0e7c9d8 +v2 ListMembersParams ListMembersParams ac4f33949067d6af +v2 ListMilestonesParams ListMilestonesParams 04dbbba27aee9293 +v2 ListModulesParams ListModulesParams f022eddc3da235b8 +v2 ListPermissionSchemesParams ListPermissionSchemesParams c100bafbdc25b3f0 +v2 ListProjectAutomationActivitiesParams ListProjectAutomationActivitiesParams f8b9eea0990e43a6 +v2 ListProjectAutomationEdgesParams ListProjectAutomationEdgesParams d5f56ca6e4fb47a8 +v2 ListProjectAutomationNodesParams ListProjectAutomationNodesParams fb0f1d5ca16bc843 +v2 ListProjectAutomationsParams ListProjectAutomationsParams 5af857e6ff339645 +v2 ListProjectsParams ListProjectsParams 795d6c2d945d08e1 +v2 ListProjectViewsParams ListProjectViewsParams b61a0702c09b47cb +v2 ListProjectWorkItemTemplatesParams ListProjectWorkItemTemplatesParams 497c7be73e9ae288 +v2 ListReleaseCommentsParams ListReleaseCommentsParams 43b83e25a86994d0 +v2 ListReleaseLabelsParams ListReleaseLabelsParams b6f80d94e0ce7441 +v2 ListReleaseLinksParams ListReleaseLinksParams e7c06a524f4b6497 +v2 ListReleasesParams ListReleasesParams fc56513d1ecaff7b +v2 ListReleaseTagsParams ListReleaseTagsParams d0e040cdf31c107b +v2 ListRolesParams ListRolesParams e6b1c7152c75f276 +v2 ListStickiesParams ListStickiesParams 78ca0e10e41f8cc5 +v2 ListTeamspacesParams ListTeamspacesParams a2530356b285b185 +v2 ListUserAssetsParams ListUserAssetsParams 955c44dd793cf6f0 +v2 ListWebhookLogsParams ListWebhookLogsParams bfbc15559a0b7c16 +v2 ListWebhooksParams ListWebhooksParams 9ed9c2ea096b3cca +v2 ListWikiPagesParams ListWikiPagesParams 6d5816b8746c8f1d +v2 ListWorkflowsParams ListWorkflowsParams bd77ea1f700e6d76 +v2 ListWorkflowStatesParams ListWorkflowStatesParams 6247782d6f999c56 +v2 ListWorkflowTransitionsParams ListWorkflowTransitionsParams 2efc137e7d812c99 +v2 ListWorkItemActivitiesParams ListWorkItemActivitiesParams f863e2ecd451c43d +v2 ListWorkItemAttachmentsParams ListWorkItemAttachmentsParams cd08f68361df001b +v2 ListWorkItemCommentsParams ListWorkItemCommentsParams 9162f8e580935db4 +v2 ListWorkItemLinksParams ListWorkItemLinksParams 83738f24f5a9ce43 +v2 ListWorkItemPropertiesParams ListWorkItemPropertiesParams 623b8ae8384aab35 +v2 ListWorkItemPropertyContextsParams ListWorkItemPropertyContextsParams 8c28bd3585bc12bf +v2 ListWorkItemPropertyOptionsParams ListWorkItemPropertyOptionsParams 888744e881004fc9 +v2 ListWorkItemRelationDefinitionsParams ListWorkItemRelationDefinitionsParams 7f1eb6a23a69fb3d +v2 ListWorkItemsParams ListWorkItemsParams a5075292c7b7b724 +v2 ListWorkItemTypePropertiesParams ListWorkItemTypePropertiesParams 8768b3170b9e68a4 +v2 ListWorkItemTypesParams ListWorkItemTypesParams 090890210f2122c7 +v2 ListWorkItemWorklogsParams ListWorkItemWorklogsParams 08c9bd0a5b7009d2 +v2 ListWorkspaceAssetsParams ListWorkspaceAssetsParams a5fc15e5155f33f6 +v2 ListWorkspaceAutomationActivitiesParams ListWorkspaceAutomationActivitiesParams c838a6e59b30663c +v2 ListWorkspaceAutomationEdgesParams ListWorkspaceAutomationEdgesParams 89bde391d647971a +v2 ListWorkspaceAutomationNodesParams ListWorkspaceAutomationNodesParams 0ccb3fce24f3c47b +v2 ListWorkspaceAutomationsParams ListWorkspaceAutomationsParams 673071924b8dcbd1 +v2 ListWorkspaceViewsParams ListWorkspaceViewsParams af6b06e643e452a6 +v2 ListWorkspaceWorkItemPropertiesParams ListWorkspaceWorkItemPropertiesParams 12fd5963f5cb85ba +v2 ListWorkspaceWorkItemPropertyOptionsParams ListWorkspaceWorkItemPropertyOptionsParams f066d5a150834da4 +v2 ListWorkspaceWorkItemTemplatesParams ListWorkspaceWorkItemTemplatesParams 3f2626a07ef947cf +v2 MilestoneField MilestoneField 74ee192821873a9d +v2 MilestoneOrderBy MilestoneOrderBy 63669b4c202a0277 +v2 Milestones Milestones 8a1ea9ed74fa77ec +v2 ModuleExpand ModuleExpand 3ca14255e4d68f8b +v2 ModuleField ModuleField b7c2ad060968d034 +v2 ModuleOrderBy ModuleOrderBy 13e4a0d13d4e219f +v2 Modules Modules 9e176f8f6fdae225 +v2 OPENAPI_VERSION OPENAPI_VERSION 1a18ca7e9c72b223 +v2 ORDER_BY ORDER_BY 70cab4aa87392d31 +v2 PermissionSchemeField PermissionSchemeField faeff22d67396fa5 +v2 PermissionSchemeOrderBy PermissionSchemeOrderBy 3e26629a8e0ccce0 +v2 PermissionSchemes PermissionSchemes 9febb69961b9a593 +v2 Project Project 8158b13b6d660706 +v2 ProjectAutomationActivities ProjectAutomationActivities c4051ce6479c8f6c +v2 ProjectAutomationActivityField ProjectAutomationActivityField dd421bca3ca52c68 +v2 ProjectAutomationActivityOrderBy ProjectAutomationActivityOrderBy 6b5183d1b9cf9fcf +v2 ProjectAutomationEdgeField ProjectAutomationEdgeField 29ac63649e456137 +v2 ProjectAutomationEdgeOrderBy ProjectAutomationEdgeOrderBy a519ba1c88058c72 +v2 ProjectAutomationEdges ProjectAutomationEdges 0a04b074585b6d95 +v2 ProjectAutomationField ProjectAutomationField d400335313e35e77 +v2 ProjectAutomationNodeField ProjectAutomationNodeField 8c9b05ce4d597e4e +v2 ProjectAutomationNodeOrderBy ProjectAutomationNodeOrderBy 244ec346f7bb3cbf +v2 ProjectAutomationNodes ProjectAutomationNodes 8321b974297efa78 +v2 ProjectAutomationOrderBy ProjectAutomationOrderBy 2a3e9f3ba5cfb0bf +v2 ProjectAutomations ProjectAutomations 259731a37e1c8b2e +v2 ProjectExpand ProjectExpand a0fc9f9b5cac2cb6 +v2 ProjectFeatures ProjectFeatures 1ce1327d5d9ebb12 +v2 ProjectField ProjectField 9b8ee9892cac9e0a +v2 ProjectMemberExpand ProjectMemberExpand 9976c35da35a0126 +v2 ProjectMemberField ProjectMemberField 68271db1c9f5988f +v2 ProjectMemberOrderBy ProjectMemberOrderBy e202223c48fc34a9 +v2 ProjectMembers ProjectMembers 5cabe227cc45d350 +v2 ProjectOrderBy ProjectOrderBy 769c526f6d4d34dc +v2 ProjectPages ProjectPages 63bb1e75c601b206 +v2 ProjectPermissions ProjectPermissions a5b50799a5594920 +v2 Projects Projects 744aed32ed74e419 +v2 ProjectSummaryCount ProjectSummaryCount a56d0cafb6046549 +v2 ProjectViewOrderBy ProjectViewOrderBy ad8cf1c8aef1ae5a +v2 ProjectViews ProjectViews bc17f1d82a25bef2 +v2 ProjectWorkItemTemplates ProjectWorkItemTemplates a91ed7a4da9a2c97 +v2 ProjectWorklogs ProjectWorklogs 8bc19d477df33f6b +v2 raiseForFailures raiseForFailures 9519ea6d57725723 +v2 Relations Relations a7443858f51a69a2 +v2 ReleaseChangelogResource Changelog 835a08cbbf6abd7e +v2 ReleaseCommentField ReleaseCommentField 349df34fc725a8c8 +v2 ReleaseCommentOrderBy ReleaseCommentOrderBy cef45ad092a34e2f +v2 ReleaseComments Comments$1 15ac63352e4005ad +v2 ReleaseExpand ReleaseExpand 3502617cca8d61d4 +v2 ReleaseField ReleaseField 499ab3818f4b3109 +v2 ReleaseLabelField ReleaseLabelField d289559fa32ee5d4 +v2 ReleaseLabelOrderBy ReleaseLabelOrderBy b8f49f6ce063c845 +v2 ReleaseLabels ReleaseLabels 1dd560f3924ca28c +v2 ReleaseLinkField ReleaseLinkField d9aed3beb7b7341f +v2 ReleaseLinkOrderBy ReleaseLinkOrderBy 848c452b7755dda7 +v2 ReleaseLinks Links$1 da15bb9e49f05d4c +v2 ReleaseOrderBy ReleaseOrderBy a7f347071a76ae95 +v2 Releases Releases 34b3cc11c41c9a5f +v2 ReleaseStatusFilter ReleaseStatusFilter d7d8095303a2d206 +v2 ReleaseTagField ReleaseTagField 04b2d3c20f2d15cc +v2 ReleaseTagOrderBy ReleaseTagOrderBy 235fab9b00a78cd7 +v2 ReleaseTags ReleaseTags d7069745aac04d4f +v2 RoleField RoleField 685a79b673e0226d +v2 RoleOrderBy RoleOrderBy 8b385fd82025b4a7 +v2 Roles Roles c8c307015d785e80 +v2 StateField StateField 2cfc8b18cdcd8b6c +v2 StateOrderBy StateOrderBy e774918b4ce3928b +v2 States States e861ad90e2f32991 +v2 Stickies Stickies fa2641bfc5240779 +v2 StickyField StickyField 643b8430d75e9720 +v2 StickyOrderBy StickyOrderBy bd49f4cf606fd7fa +v2 TeamspaceExpand TeamspaceExpand e9abd665df475ac7 +v2 TeamspaceField TeamspaceField 24a982f0a3a951d9 +v2 TeamspaceOrderBy TeamspaceOrderBy 4f18b39476c75a5b +v2 Teamspaces Teamspaces 13c6bae406ac3d66 +v2 UserAssetField UserAssetField 0e0bf67e1a131656 +v2 UserAssetOrderBy UserAssetOrderBy 4e2343a9f5de9e0f +v2 UserAssets UserAssets 0e6b1983912abefc +v2 Users Users ef9fca201ec76474 +v2 V2Namespace V2Namespace bcc148b1dd984c40 +v2 V2Transport V2Transport 6ed3872d0260e6bd +v2 ViewExpand ViewExpand 1b6d596512904eda +v2 ViewField ViewField e3bb957bde62e66d +v2 WebhookField WebhookField 487ec757ba2ac851 +v2 WebhookLogField WebhookLogField ef841fe1b9e60c05 +v2 WebhookLogOrderBy WebhookLogOrderBy ec2dca9ddef07b93 +v2 WebhookLogs WebhookLogs beb4deaa1b7cd9b8 +v2 WebhookOrderBy WebhookOrderBy 8208ef1cf8b386b0 +v2 Webhooks Webhooks 4eef184c23204063 +v2 Wiki Wiki 722cbe434431f32f +v2 WikiPageExpand WikiPageExpand b41bd04e55582fc9 +v2 WikiPageField WikiPageField bd8a2930ea927502 +v2 WikiPageOrderBy WikiPageOrderBy 3a466d4c1bcc4994 +v2 WikiPages WikiPages a9fc89307a4e09be +v2 WorkflowField WorkflowField 74d9d0fd10d60571 +v2 WorkflowOrderBy WorkflowOrderBy bd7965a04fd6edf7 +v2 Workflows Workflows 4510c543bcb4b3aa +v2 WorkflowStateField WorkflowStateField 3e42b0eab3eed710 +v2 WorkflowStateOrderBy WorkflowStateOrderBy e862a2637af72d50 +v2 WorkflowStates WorkflowStates db44ade82fdf542e +v2 WorkflowTransitionField WorkflowTransitionField f49e34b220daf994 +v2 WorkflowTransitionOrderBy WorkflowTransitionOrderBy fe6d5dbce6768210 +v2 WorkflowTransitions WorkflowTransitions 411d105688fdd05b +v2 WorkItemActivityExpand WorkItemActivityExpand 1f6069e8442bdf0b +v2 WorkItemActivityField WorkItemActivityField 93ed28cb0f94c0a5 +v2 WorkItemActivityOrderBy WorkItemActivityOrderBy 938abeedca40289e +v2 WorkItemAttachmentField WorkItemAttachmentField 3ebfd0e73543fc29 +v2 WorkItemAttachmentOrderBy WorkItemAttachmentOrderBy f3288ee4ddf801a3 +v2 WorkItemCommentExpand WorkItemCommentExpand 8508c4526c7d0719 +v2 WorkItemCommentField WorkItemCommentField 6f0675f65f277f55 +v2 WorkItemCommentOrderBy WorkItemCommentOrderBy 6046a2fd92081ccd +v2 WorkItemExpand WorkItemExpand 000e10aff7eb660e +v2 WorkItemField WorkItemField 3da484aec508edd0 +v2 WorkItemLinkField WorkItemLinkField 1f060447b94fe3cc +v2 WorkItemLinkOrderBy WorkItemLinkOrderBy c76aba0c76a92eb5 +v2 WorkItemOrderBy WorkItemOrderBy 2e5db248118b1c9a +v2 WorkItemProperties WorkItemProperties 2772074e1b2b5c92 +v2 WorkItemPropertyContextOrderBy WorkItemPropertyContextOrderBy 576846614cee13f5 +v2 WorkItemPropertyContexts WorkItemPropertyContexts c3eaf61b9111ce50 +v2 WorkItemPropertyField WorkItemPropertyField 18992abd11aa30cb +v2 WorkItemPropertyOptionOrderBy WorkItemPropertyOptionOrderBy 608a0ee69288e0f1 +v2 WorkItemPropertyOptions WorkItemPropertyOptions 7ba4ad7c44018a09 +v2 WorkItemPropertyOrderBy WorkItemPropertyOrderBy 91d69cd9ef13522d +v2 WorkItemRelationDefinitionField WorkItemRelationDefinitionField 1739d027f8b0010c +v2 WorkItemRelationDefinitions WorkItemRelationDefinitions d517ae949c472ec4 +v2 WorkItems WorkItems e9c6711227cca90f +v2 WorkItemTemplateField WorkItemTemplateField b0fcbb132ca82025 +v2 WorkItemTemplateOrderBy WorkItemTemplateOrderBy 391d22d3b2f31757 +v2 WorkItemTemplates WorkItemTemplates 1e29bc673ce6241e +v2 WorkItemTemplateUseExpand WorkItemTemplateUseExpand 2d45a17a6c1d10c6 +v2 WorkItemTemplateUseField WorkItemTemplateUseField f5af67d618e36cf0 +v2 WorkItemTypeField WorkItemTypeField 702e15690b1756be +v2 WorkItemTypeOrderBy WorkItemTypeOrderBy 5df979b220808473 +v2 WorkItemTypeProperties WorkItemTypeProperties 03a560835e11f16f +v2 WorkItemTypePropertyField WorkItemTypePropertyField 544a8fef7a54d7cf +v2 WorkItemTypePropertyOrderBy WorkItemTypePropertyOrderBy 246f6cfc2091e45a +v2 WorkItemTypes WorkItemTypes f11d401c29149dd9 +v2 WorkItemWorklogExpand WorkItemWorklogExpand d3067d396ca81f99 +v2 WorkItemWorklogField WorkItemWorklogField a159745004fd7286 +v2 WorkItemWorklogOrderBy WorkItemWorklogOrderBy e545e73884253e5c +v2 WorkLogs WorkLogs 9f6dc7025881b273 +v2 Workspace Workspace 2d351430f10474ba +v2 WorkspaceAssetField WorkspaceAssetField 827cba08b2a129af +v2 WorkspaceAssetOrderBy WorkspaceAssetOrderBy 8aee13377cf9a336 +v2 WorkspaceAutomationActivities WorkspaceAutomationActivities a00cd7813c100666 +v2 WorkspaceAutomationActivityField WorkspaceAutomationActivityField 169b57a6aa3b95e4 +v2 WorkspaceAutomationActivityOrderBy WorkspaceAutomationActivityOrderBy 9cc50fe8dc5ddb4d +v2 WorkspaceAutomationEdgeField WorkspaceAutomationEdgeField 397b3073460f41a0 +v2 WorkspaceAutomationEdgeOrderBy WorkspaceAutomationEdgeOrderBy a755074d62760b66 +v2 WorkspaceAutomationEdges WorkspaceAutomationEdges eb1cf3038612bfd4 +v2 WorkspaceAutomationField WorkspaceAutomationField 4e6252f8f09c63f2 +v2 WorkspaceAutomationNodeField WorkspaceAutomationNodeField f0953c79e1515c4b +v2 WorkspaceAutomationNodeOrderBy WorkspaceAutomationNodeOrderBy f7fd3c0a4e9ceac3 +v2 WorkspaceAutomationNodes WorkspaceAutomationNodes 654fec7fb5e94b3c +v2 WorkspaceAutomationOrderBy WorkspaceAutomationOrderBy 44ed646668929c83 +v2 WorkspaceAutomations WorkspaceAutomations 3e262851b98cdade +v2 WorkspaceFeatures WorkspaceFeatures a2c6de4a85fcc1d9 +v2 WorkspaceInviteField WorkspaceInviteField 3a2b66d4197c572d +v2 WorkspaceInviteOrderBy WorkspaceInviteOrderBy d1901ca37563d14d +v2 WorkspaceMembers WorkspaceMembers ee484fee9d2d4bc0 +v2 WorkspacePermissions WorkspacePermissions 09ea4f33df25e790 +v2 WorkspaceViewOrderBy WorkspaceViewOrderBy ea48a52e1e6e629d +v2 WorkspaceViews WorkspaceViews 2266cd5a8ec2fff7 +v2 WorkspaceWorkItemProperties WorkspaceWorkItemProperties 56f879322147b866 +v2 WorkspaceWorkItemPropertyField WorkspaceWorkItemPropertyField 088f4f0bd82e7a26 +v2 WorkspaceWorkItemPropertyOptionOrderBy WorkspaceWorkItemPropertyOptionOrderBy 13382d34c16f6f57 +v2 WorkspaceWorkItemPropertyOptions WorkspaceWorkItemPropertyOptions dbc4ba741bc8ec7c +v2 WorkspaceWorkItemPropertyOrderBy WorkspaceWorkItemPropertyOrderBy dcb582a7109e424a +v2 WorkspaceWorkItems WorkspaceWorkItems 360ebabb44545fc6 +v2 WorkspaceWorkItemTemplateField WorkspaceWorkItemTemplateField ebccf9986a66dcd6 +v2 WorkspaceWorkItemTemplateOrderBy WorkspaceWorkItemTemplateOrderBy 96cf8171f05f86e8 +v2 WorkspaceWorkItemTemplates WorkspaceWorkItemTemplates 73ea85cba99de27e +v2 WorkspaceWorkItemTypeProperties WorkspaceWorkItemTypeProperties 6f1ced76ea5c9889 +v2 WorkspaceWorkItemTypes WorkspaceWorkItemTypes 0a62a2f5d3c41ecd +v2models Artifact Artifact 8f4f4ab71cb8c53d +v2models ArtifactDataMode ArtifactDataMode 29c277b65f52892b +v2models ArtifactDetail ArtifactDetail 87aff13ed4468ffb +v2models ArtifactPublishResult ArtifactPublishResult fba408b8f4b397eb +v2models ArtifactUpdateResult ArtifactUpdateResult 8d2f0f1e3dcefafa +v2models AttachedWorkItemTypeProperties AttachedWorkItemTypeProperties acd010d0807a6bde +v2models AuditLog AuditLog 5748cf85faae47c1 +v2models AuditLogActorType AuditLogActorType 35e22038eafe4c59 +v2models AuditLogCategory AuditLogCategory 1484076310a18487 +v2models AuditLogOutcome AuditLogOutcome 4900c934d786a2b0 +v2models AuditLogSource AuditLogSource 9327151c9a43f7fd +v2models Automation Automation 6ae3a789e2ea73e4 +v2models AutomationActivity AutomationActivity 7ee11f52c7d2fb62 +v2models AutomationEdge AutomationEdge 49c515a820d1bfe6 +v2models AutomationNode AutomationNode 40cfbb6523392f48 +v2models AutomationNodeType AutomationNodeType ab4ea99462a019fe +v2models AutomationStatus AutomationStatus 2dee24e5da80571d +v2models AutomationWebhookSecret AutomationWebhookSecret fad7965f0cf62061 +v2models BulkCreateWorkspaceInvites BulkCreateWorkspaceInvites b1a680f16ffd3ece +v2models BulkRowFailure BulkRowFailure 3a63c31df60f367c +v2models BulkRowSuccess BulkRowSuccess 6840350f1463f1ca +v2models BulkUpdateItem BulkUpdateItem f74590a8eeabea42 +v2models BulkWriteResponse BulkWriteResponse a62766eda2d9e61f +v2models BulkWriteRow BulkWriteRow b749b40b311a9124 +v2models Collection Collection b3da5314afe85263 +v2models CollectionMember CollectionMember e44b8601044d34fa +v2models CollectionMemberAccess CollectionMemberAccess 65f60ad10486e9bc +v2models CollectionMemberAddItem CollectionMemberAddItem 95e143cfa1f45db6 +v2models CollectionMembersManageRequest CollectionMembersManageRequest 4bf7110404b254eb +v2models CollectionMembersManageResponse CollectionMembersManageResponse 5ef005598104a071 +v2models CollectionMemberSource CollectionMemberSource 277b9eb3f44a2f5b +v2models CollectionPageSearch CollectionPageSearch 8b51dfba5d6fd2b3 +v2models CollectionPagesManageRequest CollectionPagesManageRequest 83a731634d038b58 +v2models CollectionPagesManageResponse CollectionPagesManageResponse ac5dddd044fb4f9e +v2models CreateArtifact CreateArtifact a1a0c90fb34f4ef3 +v2models CreateAutomation CreateAutomation 9a9a62c5ec5118bc +v2models CreateAutomationEdge CreateAutomationEdge 736ef458b14f945d +v2models CreateAutomationNode CreateAutomationNode 543b8b4e3387b54f +v2models CreateCollection CreateCollection 3afdde594a24fc08 +v2models CreateCustomer CreateCustomer 2753bb4021ecdd7c +v2models CreateCustomerProperty CreateCustomerProperty 420db71864a79391 +v2models CreateCustomerPropertyOption CreateCustomerPropertyOption e818442a4ce6c3a0 +v2models CreateCustomerPropertyValues CreateCustomerPropertyValues da41ca7f5977895d +v2models CreateCustomerRequest CreateCustomerRequest 533215d178fc1df4 +v2models CreateCycle CreateCycle 23f0ebe512ec0384 +v2models CreateEstimate CreateEstimate 0413e51a22cb269a +v2models CreateEstimatePoint CreateEstimatePoint 1cb096c34f59af7d +v2models CreateGroupMapping CreateGroupMapping b2dd47de6138a93d +v2models CreateInitiative CreateInitiative 8f4099f47c7638b6 +v2models CreateInitiativeLabel CreateInitiativeLabel 8c644464f2bb02b1 +v2models CreateIntakeWorkItem CreateIntakeWorkItem e63583cdd19753c0 +v2models CreateLabel CreateLabel 406ce08dd73c9cfa +v2models CreateMilestone CreateMilestone c343a49181fdedc7 +v2models CreateModule CreateModule 5a93c1c805962604 +v2models CreatePage CreatePage 6bee3e8079aa1aca +v2models CreateProject CreateProject 8a133e5f6907c361 +v2models CreateProjectMember CreateProjectMember cc74eb3e229f28dc +v2models CreateRelease CreateRelease e8f88902aef95ae2 +v2models CreateReleaseComment CreateReleaseComment b3bf0f1fdf14e191 +v2models CreateReleaseLabel CreateReleaseLabel cb65eda9e6cb2d93 +v2models CreateReleaseLink CreateReleaseLink eadfa787c5d284bf +v2models CreateReleaseTag CreateReleaseTag 5b3e084f8c0a45b0 +v2models CreateState CreateState e0e6d597796ba45d +v2models CreateSticky CreateSticky 663e956c171ed192 +v2models CreateTeamspace CreateTeamspace 5c83a8d5ff4fb9b3 +v2models CreateView CreateView c45c383521d10adb +v2models CreateWebhook CreateWebhook cf78dd312a0d05ba +v2models CreateWorkflow CreateWorkflow 9f847ecc05a6e64f +v2models CreateWorkflowTransition CreateWorkflowTransition 08c3078eb1e4ad81 +v2models CreateWorkItem CreateWorkItem eb2dde4ebf77e21e +v2models CreateWorkItemComment CreateWorkItemComment fda978bfd6dcfc04 +v2models CreateWorkItemLink CreateWorkItemLink 0ffd0c540f660d6c +v2models CreateWorkItemProperty CreateWorkItemProperty ebc861a8f3b03b82 +v2models CreateWorkItemPropertyContext CreateWorkItemPropertyContext 76702715f55a1cd6 +v2models CreateWorkItemPropertyOption CreateWorkItemPropertyOption 52dda92e24675925 +v2models CreateWorkItemRelationDefinition CreateWorkItemRelationDefinition 80a9d077d3a7df4d +v2models CreateWorkItemTemplate CreateWorkItemTemplate 82d42c0b427052e8 +v2models CreateWorkItemType CreateWorkItemType 6455106b39dd4b1d +v2models CreateWorkItemWorklog CreateWorkItemWorklog ce38f3901d43f6b0 +v2models CreateWorkspaceGroupMapping CreateWorkspaceGroupMapping 1eb4aa8836c63273 +v2models CreateWorkspaceInvite CreateWorkspaceInvite 4ce3c7f684711bdc +v2models CursorPage CursorPage fcc2a5033696f854 +v2models Customer Customer 89d52a530f3465fc +v2models CustomerProperty CustomerProperty 36edbe2c51ea4a4e +v2models CustomerPropertyRelationType CustomerPropertyRelationType 2bfd7d84e1fefe5e +v2models CustomerPropertyType CustomerPropertyType bc8c90c3a66852ae +v2models CustomerPropertyValuesMap CustomerPropertyValuesMap 2938d2ca1c056e61 +v2models CustomerRequest CustomerRequest 918f9ce3c12e4dab +v2models CustomerWorkItemManageRequest CustomerWorkItemManageRequest 1cc9f352a02fcc08 +v2models CustomerWorkItemManageResponse CustomerWorkItemManageResponse 4546c88beb8fe10f +v2models Cycle Cycle 0fbe8469e892070f +v2models CycleTransferRequest CycleTransferRequest e7f43182d7f1d576 +v2models CycleTransferResult CycleTransferResult d042aace96311191 +v2models CycleWorkItemManageRequest CycleWorkItemManageRequest 3801aec38b5ef633 +v2models CycleWorkItemManageResponse CycleWorkItemManageResponse 376a295ca755ca42 +v2models EffectivePermissions EffectivePermissions 5d3fedb6e24b57e8 +v2models Estimate Estimate 66f37d2b160c0e65 +v2models EstimatePoint EstimatePoint a3601e3fbc67fd61 +v2models EstimateType EstimateType 0c64e6b657463cb7 +v2models GroupMapping GroupMapping ff3db5f0bfbcf8f7 +v2models GroupSyncConfig GroupSyncConfig 4455eac9705c96b0 +v2models Initiative Initiative 4bda43ed6c5b8ff0 +v2models InitiativeChildManageRequest InitiativeChildManageRequest 26984f1c6dc5001a +v2models InitiativeChildManageResponse InitiativeChildManageResponse 3dd2aaf9bc0892e0 +v2models InitiativeLabel InitiativeLabel 4c230e92ee25c1d5 +v2models InitiativeState InitiativeState 131e07d51d1f5490 +v2models IntakeWorkItem IntakeWorkItem 5f0ba6c0b1237377 +v2models IntakeWorkItemPriority IntakeWorkItemPriority 76f519c9e14b0883 +v2models IntakeWorkItemStatus IntakeWorkItemStatus 0392eaefd6792093 +v2models Label Label 0d571a0f4f949e70 +v2models Milestone Milestone 836c22d96d67bb88 +v2models MilestoneWorkItemManageRequest MilestoneWorkItemManageRequest d1bd62275d63e8a6 +v2models MilestoneWorkItemManageResponse MilestoneWorkItemManageResponse 21ccd825af69df65 +v2models Module Module 117398c9173cc59d +v2models ModuleStatus ModuleStatus 979b917001040ec1 +v2models ModuleWorkItemManageRequest ModuleWorkItemManageRequest 9e48a701cdce7586 +v2models ModuleWorkItemManageResponse ModuleWorkItemManageResponse 8c55c81162f81356 +v2models OffsetPage OffsetPage 3639ecb8335d995a +v2models Page Page$1 20725d97c3eeef0b +v2models PageAccess PageAccess c29bd17f6f76b771 +v2models PageTypeFilter PageTypeFilter 5052d179f8b2b6e3 +v2models PermissionScheme PermissionScheme 9c0370380767af8f +v2models PermissionSchemeNamespace PermissionSchemeNamespace 8c46326a7bc467f7 +v2models PrincipalKind PrincipalKind 64efd7e371867254 +v2models Project Project$1 0a71c767c7fa97d0 +v2models ProjectFeature ProjectFeature 42b4d6e963929de7 +v2models ProjectMember ProjectMember 0d4bfd30ad66bcd7 +v2models ProjectNetwork ProjectNetwork 892c9609df0af367 +v2models ProjectPriority ProjectPriority 88a469bcef56ac01 +v2models ProjectRoleDistribution ProjectRoleDistribution 85401e979a918a6a +v2models ProjectRoleDistributionEntry ProjectRoleDistributionEntry 7e4a87a4cfa6eca3 +v2models ProjectSummary ProjectSummary d65cc65ce9e01fe5 +v2models ProjectTimezone ProjectTimezone 2af873c204b08948 +v2models Release Release 0940bc25daf39998 +v2models ReleaseChangelog ReleaseChangelog 98833192273238f9 +v2models ReleaseChildManageRequest ReleaseChildManageRequest 84c11c460805adfa +v2models ReleaseChildManageResponse ReleaseChildManageResponse efba3f700f21df9b +v2models ReleaseComment ReleaseComment c237f08be061127a +v2models ReleaseLabel ReleaseLabel 75322f8f368c87ac +v2models ReleaseLink ReleaseLink 6e2e4a9915346ab1 +v2models ReleaseStatus ReleaseStatus 8fb6f688ae374061 +v2models ReleaseTag ReleaseTag efbdb2a4feba1308 +v2models Role Role df26fef9334fb8b0 +v2models RoleNamespace RoleNamespace c5203a2ede46846a +v2models RoleStatus RoleStatus c4c913d1c1e34f5c +v2models SetAutomationStatus SetAutomationStatus 3381db7b291bf701 +v2models State State 8217bc51d82bec16 +v2models StateGroup StateGroup 727c5fd9e0bc44fc +v2models Sticky Sticky 44d29dcba60165af +v2models Teamspace Teamspace bf5b6bfb03068eb1 +v2models UpdateArtifactUpdate UpdateArtifactUpdate 08a79442bfe70e67 +v2models UpdateAutomation UpdateAutomation 3952af2d12b710c8 +v2models UpdateAutomationEdge UpdateAutomationEdge ba474c409312db8f +v2models UpdateAutomationNode UpdateAutomationNode e33b9e2bc159abb0 +v2models UpdateCollection UpdateCollection 75adbf48b2a7ae2d +v2models UpdateCustomer UpdateCustomer 6b5748efdd6f51f2 +v2models UpdateCustomerProperty UpdateCustomerProperty 58cdd9a89580f0e0 +v2models UpdateCustomerRequest UpdateCustomerRequest 56dc022c5393d39f +v2models UpdateCycle UpdateCycle d7a6321443f778fc +v2models UpdateEstimate UpdateEstimate 0fae5e80e8f23562 +v2models UpdateEstimatePoint UpdateEstimatePoint b364d256f416d2c4 +v2models UpdateGroupMapping UpdateGroupMapping a8b0103ea9545567 +v2models UpdateGroupSyncConfig UpdateGroupSyncConfig 5d4a6061b7cac084 +v2models UpdateInitiative UpdateInitiative aa23a9f356198987 +v2models UpdateInitiativeLabel UpdateInitiativeLabel 3678adfeb73cd0e1 +v2models UpdateIntakeWorkItem UpdateIntakeWorkItem 0819548552b05e34 +v2models UpdateLabel UpdateLabel 591b4c25ca9c0b30 +v2models UpdateMilestone UpdateMilestone 708a4ffb2af887e7 +v2models UpdateModule UpdateModule 46f5948435452482 +v2models UpdatePage UpdatePage 4a178c9c56e1811d +v2models UpdateProject UpdateProject f460a40c9e894342 +v2models UpdateProjectFeature UpdateProjectFeature 9b0f329f380ff2bf +v2models UpdateProjectMember UpdateProjectMember bde5f9197f382551 +v2models UpdateRelease UpdateRelease bca361ca10ce6c55 +v2models UpdateReleaseChangelog UpdateReleaseChangelog f6da33b1e5b55ec4 +v2models UpdateReleaseComment UpdateReleaseComment 6ce61cb3a7a40f50 +v2models UpdateReleaseLabel UpdateReleaseLabel ee822e7b91513027 +v2models UpdateReleaseLink UpdateReleaseLink 5ab44dd4e75cf5a3 +v2models UpdateReleaseTag UpdateReleaseTag 3ffffa4220c586c7 +v2models UpdateState UpdateState 2bb063c3ae85f516 +v2models UpdateSticky UpdateSticky 11183a46f2ad7aaa +v2models UpdateTeamspace UpdateTeamspace 5b94d58a57096af9 +v2models UpdateView UpdateView 6040aff91b83ecc6 +v2models UpdateWebhook UpdateWebhook 8045e2f55d040ebb +v2models UpdateWorkflow UpdateWorkflow 2514997086df26d2 +v2models UpdateWorkflowState UpdateWorkflowState 1481f93616e5580a +v2models UpdateWorkflowTransition UpdateWorkflowTransition fd3e0df1661fd28b +v2models UpdateWorkItem UpdateWorkItem 7ddc6dda7f7b9655 +v2models UpdateWorkItemComment UpdateWorkItemComment 4f6aaf6666082c30 +v2models UpdateWorkItemLink UpdateWorkItemLink 67f7ea8ef968edfb +v2models UpdateWorkItemProperty UpdateWorkItemProperty 8e153af041482f4a +v2models UpdateWorkItemPropertyContext UpdateWorkItemPropertyContext b19d5a82a8ce76ef +v2models UpdateWorkItemPropertyOption UpdateWorkItemPropertyOption 2101d5a2cd79e7a3 +v2models UpdateWorkItemRelationDefinition UpdateWorkItemRelationDefinition 3dfeb24782588c6d +v2models UpdateWorkItemTemplate UpdateWorkItemTemplate d0b70c45fd61c1ae +v2models UpdateWorkItemType UpdateWorkItemType f8a49123a0320ccf +v2models UpdateWorkItemWorklog UpdateWorkItemWorklog a5682731a39d9298 +v2models UpdateWorkspaceFeature UpdateWorkspaceFeature e40bf6d71e4227e2 +v2models UpdateWorkspaceGroupMapping UpdateWorkspaceGroupMapping fc0284ad874d00d5 +v2models UserAsset UserAsset 6e7bd857178f4602 +v2models UserAssetConfirmRequest UserAssetConfirmRequest af6c3faa9c7ad67b +v2models UserAssetEntityType UserAssetEntityType c2ff0464a0ca1955 +v2models UserAssetUploadRequest UserAssetUploadRequest 8196be1c483125df +v2models View View 91c7781125f9509a +v2models ViewAccess ViewAccess cc7d00685fed9c95 +v2models Webhook Webhook 51fb46f978ac1b19 +v2models WebhookContentType WebhookContentType d3f26efdb3421ac9 +v2models WebhookCreateResponse WebhookCreateResponse 00f2ef9f126d731b +v2models WebhookLog WebhookLog 86648f9796a85528 +v2models WhoAmI WhoAmI 9bda88ee24634842 +v2models Workflow Workflow af044ee329fcfaea +v2models WorkflowState WorkflowState dcdeb244246c7a20 +v2models WorkflowStateAttachRequest WorkflowStateAttachRequest 05957276dd6fdf7c +v2models WorkflowStateKind WorkflowStateKind 9cca0502be00b262 +v2models WorkflowTransition WorkflowTransition 91709ea37dd8f80d +v2models WorkItem WorkItem cf8e4c901f20f86b +v2models WorkItemActivity WorkItemActivity 479b9e62504dc90b +v2models WorkItemAttachment WorkItemAttachment 5f0ed46fecab1c34 +v2models WorkItemAttachmentConfirmRequest WorkItemAttachmentConfirmRequest 93bb2e58834936d3 +v2models WorkItemAttachmentUploadRequest WorkItemAttachmentUploadRequest db4f35af2983de91 +v2models WorkItemComment WorkItemComment 53ab830e7b16b0fb +v2models WorkItemCommentAccess WorkItemCommentAccess 05a11ed083397eb5 +v2models WorkItemCustomFieldValue WorkItemCustomFieldValue e9d45e16f022cdb5 +v2models WorkItemDependencyCreateRequest WorkItemDependencyCreateRequest b8a59553ddf19322 +v2models WorkItemDependencyList WorkItemDependencyList 4e605d3fd59e4d2c +v2models WorkItemDependencyRelationType WorkItemDependencyRelationType 6d2ce316fb1cbec2 +v2models WorkItemLink WorkItemLink 19a1c8cc227f3eaf +v2models WorkItemPriority WorkItemPriority 2efcd2f83558fee6 +v2models WorkItemProperty WorkItemProperty efe53b7ffc0846c4 +v2models WorkItemPropertyContext WorkItemPropertyContext 6ee5c4e6cbde3ada +v2models WorkItemPropertyContextOptionInput WorkItemPropertyContextOptionInput f611f84abd40fd6d +v2models WorkItemPropertyOptionLite WorkItemPropertyOptionLite 0a8ba2fe5b710f2f +v2models WorkItemPropertyOptionSeed WorkItemPropertyOptionSeed 97a5ebc1ee2a0dab +v2models WorkItemPropertyRelationType WorkItemPropertyRelationType 2d2fc54f868bc762 +v2models WorkItemPropertyType WorkItemPropertyType e60994cc895bf11c +v2models WorkItemRelationCreateRequest WorkItemRelationCreateRequest 4b7dad64fafb3e86 +v2models WorkItemRelationDefinition WorkItemRelationDefinition b82ddab4e7b520fe +v2models WorkItemRelationList WorkItemRelationList 6d5e946713382898 +v2models WorkItemTemplate WorkItemTemplate 4331780b7911b0dc +v2models WorkItemTemplateData WorkItemTemplateData fb644987980a439b +v2models WorkItemTemplateUseRequest WorkItemTemplateUseRequest 6537904f31cda000 +v2models WorkItemType WorkItemType 508bb2d35eae8095 +v2models WorkItemTypeSchema WorkItemTypeSchema 08bbf210ab26071c +v2models WorkItemWorklog WorkItemWorklog 9c2fc684c856b4db +v2models WorklogSummaryEntry WorklogSummaryEntry 62a9c9c9b87b025d +v2models WorkspaceAsset WorkspaceAsset 158f63c15d06b6c0 +v2models WorkspaceAssetConfirmRequest WorkspaceAssetConfirmRequest a9b006b236b1b790 +v2models WorkspaceAssetUploadRequest WorkspaceAssetUploadRequest 7ff4c2d40ba7438e +v2models WorkspaceFeature WorkspaceFeature 8ec1b6093060db65 +v2models WorkspaceGroupMapping WorkspaceGroupMapping fc4060333bc9b839 +v2models WorkspaceInvite WorkspaceInvite 4827ad84b88afe36 +v2models WorkspaceMember WorkspaceMember 70091e0cd3a80c10 +v2models WorkspaceMemberRemoveRequest WorkspaceMemberRemoveRequest 4aa6efab146d5e24 diff --git a/scripts/check-types-bundle.mjs b/scripts/check-types-bundle.mjs new file mode 100644 index 0000000..d1bf053 --- /dev/null +++ b/scripts/check-types-bundle.mjs @@ -0,0 +1,219 @@ +/** Guards against a v2/v1 type-name collision swapping which shape a public export resolves to. Usage: node scripts/check-types-bundle.mjs [--write] */ +import { createHash } from "node:crypto"; +import { existsSync, readFileSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const repoRoot = join(scriptDir, ".."); +const bundlePath = join(repoRoot, "dist/types.bundle.d.ts"); +const snapshotPath = join(scriptDir, "__fixtures__/types-bundle-exports.snapshot.txt"); + +/** A single `export { local as external, ... }` (or bare `export { name, ... }`) block's content. */ +function parseExportBlockContent(content) { + return content + .split(",") + .map((item) => item.replace(/\s+/g, " ").trim()) + .filter((item) => item.length > 0) + .map((item) => { + const asMatch = /^(\S+)\s+as\s+(\S+)$/.exec(item); + if (asMatch) return { local: asMatch[1], external: asMatch[2] }; + return { local: item, external: item }; + }); +} + +/** Splits the bundle into `{ scope, text }` regions per top-level `declare namespace` block, plus a "root" region. */ +function splitIntoScopes(source) { + const namespaceRe = /^declare namespace (\w+) \{\n([\s\S]*?)\n\}\n/gm; + const regions = []; + let cursor = 0; + let match; + while ((match = namespaceRe.exec(source))) { + if (match.index > cursor) regions.push({ scope: "root", text: source.slice(cursor, match.index) }); + regions.push({ scope: match[1], text: match[2] }); + cursor = match.index + match[0].length; + } + if (cursor < source.length) regions.push({ scope: "root", text: source.slice(cursor) }); + return regions; +} + +/** Splits root-scope text into top-level chunks: a non-indented line starts a new chunk (dts-bundle-generator indents continuations). */ +function splitIntoTopLevelChunks(text) { + const chunks = []; + let current = null; + for (const line of text.split("\n")) { + const isTopLevel = line.length > 0 && !/^\s/.test(line); + if (isTopLevel) { + if (current) chunks.push(current); + current = [line]; + } else if (current) { + current.push(line); + } + } + if (current) chunks.push(current); + return chunks.map((lines) => lines.join("\n")); +} + +const DECLARATION_START_RE = + /^(?:export )?(?:declare )?(?:abstract )?(interface|type|class|function|const|enum) ([A-Za-z0-9_$]+)/; + +/** Strips comments and collapses whitespace so the hash reflects shape, not formatting or doc comments. */ +function normalizeBody(text) { + const withoutComments = text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|\s)\/\/.*$/gm, "$1"); + return withoutComments + .split("\n") + .map((line) => line.replace(/\s+/g, " ").trim()) + .filter((line) => line.length > 0) + .join("\n"); +} + +function hashBody(text) { + return createHash("sha256").update(normalizeBody(text)).digest("hex").slice(0, 16); +} + +/** local declaration name -> normalized-body hash, built once from the root scope's text. */ +function buildDeclarationHashes(rootText) { + const hashes = new Map(); + for (const chunk of splitIntoTopLevelChunks(rootText)) { + const firstLine = chunk.split("\n")[0]; + const match = DECLARATION_START_RE.exec(firstLine); + if (!match) continue; // comment chunks, the trailing `export {}` block, `export {};`, blank chunks + const name = match[2]; + hashes.set(name, hashBody(chunk)); + } + return hashes; +} + +/** The full public export surface: one `{ scope, external, local, hash }` entry per exported name, deduped and sorted. */ +function extractExportSurface(source) { + const regions = splitIntoScopes(source); + const rootText = regions + .filter((r) => r.scope === "root") + .map((r) => r.text) + .join("\n"); + const declarationHashes = buildDeclarationHashes(rootText); + const namespaceNames = new Set(regions.map((r) => r.scope).filter((s) => s !== "root")); + + const entries = []; + const exportBlockRe = /export\s*\{([^}]*)\}/g; + const directExportRe = + /^export (?:declare )?(?:abstract )?(?:interface|type|class|function|const|enum) ([A-Za-z0-9_$]+)/; + + for (const { scope, text } of regions) { + let match; + exportBlockRe.lastIndex = 0; + while ((match = exportBlockRe.exec(text))) { + for (const { local, external } of parseExportBlockContent(match[1])) { + entries.push({ scope, external, local }); + } + } + if (scope === "root") { + for (const line of text.split("\n")) { + const directMatch = directExportRe.exec(line); + if (directMatch) entries.push({ scope, external: directMatch[1], local: directMatch[1] }); + } + } + } + + const seen = new Set(); + const deduped = []; + for (const entry of entries) { + const key = `${entry.scope}\t${entry.external}\t${entry.local}`; + if (seen.has(key)) continue; + seen.add(key); + // Bare namespace re-exports have no declaration body of their own to hash; + // everything else must resolve to a real declaration. + const hash = namespaceNames.has(entry.local) ? "namespace" : (declarationHashes.get(entry.local) ?? "UNRESOLVED"); + deduped.push({ ...entry, hash }); + } + + deduped.sort((a, b) => `${a.scope}\t${a.external}`.localeCompare(`${b.scope}\t${b.external}`)); + return deduped; +} + +function formatSurface(entries) { + return entries.map((entry) => `${entry.scope}\t${entry.external}\t${entry.local}\t${entry.hash}`).join("\n") + "\n"; +} + +if (!existsSync(bundlePath)) { + console.error(`check-types-bundle: expected ${bundlePath} to exist. Run \`pnpm run build:types-bundle\` first.`); + process.exit(1); +} + +const bundleSource = readFileSync(bundlePath, "utf8"); +const surface = extractExportSurface(bundleSource); +const formatted = formatSurface(surface); + +if (process.argv.includes("--write")) { + writeFileSync(snapshotPath, formatted); + console.log(`check-types-bundle: wrote ${surface.length} export entries to ${snapshotPath}.`); + process.exit(0); +} + +if (!existsSync(snapshotPath)) { + console.error(`check-types-bundle: no snapshot at ${snapshotPath}. Run with --write to create one.`); + process.exit(1); +} + +const expectedLines = readFileSync(snapshotPath, "utf8") + .split("\n") + .filter((l) => l.length > 0); +const actualLines = formatted.split("\n").filter((l) => l.length > 0); + +const parseLine = (line) => { + const [scope, external, local, hash] = line.split("\t"); + return { scope, external, local, hash }; +}; +const keyOf = (e) => `${e.scope}\t${e.external}`; + +const expectedByKey = new Map(expectedLines.map(parseLine).map((e) => [keyOf(e), e])); +const actualByKey = new Map(actualLines.map(parseLine).map((e) => [keyOf(e), e])); + +const removed = []; +const added = []; +const changed = []; +for (const [key, before] of expectedByKey) { + const after = actualByKey.get(key); + if (!after) { + removed.push(before); + } else if (after.local !== before.local || after.hash !== before.hash) { + changed.push({ before, after }); + } +} +for (const [key, after] of actualByKey) { + if (!expectedByKey.has(key)) added.push(after); +} + +if (removed.length > 0 || added.length > 0 || changed.length > 0) { + console.error( + `check-types-bundle: dist/types.bundle.d.ts's public export surface no longer matches ${snapshotPath}.` + ); + console.error( + "This usually means a new v2 type collides with a v1 type's bare name -- a public export name now " + + "resolves through a different (or differently-shaped) local declaration than before, or vice versa." + ); + if (changed.length > 0) { + console.error("\nExport names whose backing declaration changed shape or identity:"); + for (const { before, after } of changed) { + console.error(` ~ ${keyOf(before)}\t${before.local}@${before.hash} -> ${after.local}@${after.hash}`); + } + } + if (removed.length > 0) { + console.error("\nEntries the snapshot expected but the bundle no longer has:"); + console.error(removed.map((e) => ` - ${keyOf(e)}\t${e.local}@${e.hash}`).join("\n")); + } + if (added.length > 0) { + console.error("\nEntries the bundle now has that the snapshot didn't expect:"); + console.error(added.map((e) => ` + ${keyOf(e)}\t${e.local}@${e.hash}`).join("\n")); + } + console.error( + "\nIf this change is intentional (a deliberate new export, or a deliberate alias for a new v2 type per " + + "the pattern in src/index.ts), review the diff above and regenerate with:\n" + + " node scripts/check-types-bundle.mjs --write" + ); + process.exit(1); +} + +console.log( + `check-types-bundle: dist/types.bundle.d.ts's public export surface matches the snapshot (${surface.length} entries).` +); diff --git a/scripts/generate-v2-constants.mjs b/scripts/generate-v2-constants.mjs new file mode 100644 index 0000000..fccadf3 --- /dev/null +++ b/scripts/generate-v2-constants.mjs @@ -0,0 +1,267 @@ +/** Regenerates src/api/v2/generated/constants.ts. Usage: pnpm codegen:v2 ../plane-ee/apps/api/plane/api_v2/core/schema/openapi */ +import { execFileSync } from "node:child_process"; +import { readdirSync, readFileSync, mkdirSync, writeFileSync, existsSync } from "node:fs"; +import { join, dirname, relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const repoRoot = join(scriptDir, ".."); + +const openapiDirArg = process.argv[2]; +if (!openapiDirArg) { + console.error("usage: node scripts/generate-v2-constants.mjs /api_v2/core/schema/openapi"); + process.exit(1); +} +// Normalized once so every invocation of the same golden checkout produces a +// byte-identical header, regardless of how the path was typed. +const openapiDir = resolve(openapiDirArg); +const normalizedOpenapiDir = relative(repoRoot, openapiDir) || "."; + +/** Reads and JSON-parses a golden file, failing loudly (with the file path) if it's missing or malformed. */ +function readJson(path, label) { + if (!existsSync(path)) { + console.error(`golden shape drift: expected ${label} at ${path}, but the file does not exist`); + process.exit(1); + } + try { + return JSON.parse(readFileSync(path, "utf8")); + } catch (error) { + console.error(`golden shape drift: ${label} at ${path} is not valid JSON (${error.message})`); + process.exit(1); + } +} + +/** Looks up a dotted key path, failing loudly with the exact missing segment. */ +function requireKeyPath(root, rootLabel, keyPath) { + let cursor = root; + const segments = keyPath.split("."); + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + if (cursor == null || typeof cursor !== "object" || !(segment in cursor)) { + const seen = segments.slice(0, i).join("."); + console.error( + `golden shape drift: ${rootLabel}${seen ? `.${seen}` : ""}.${segment} is missing (expected ${rootLabel}.${keyPath})` + ); + process.exit(1); + } + cursor = cursor[segment]; + } + return cursor; +} + +const root = readJson(join(openapiDir, "root.json"), "root.json"); +const openapiVersion = requireKeyPath(root, "root.json", "info.version"); + +const pathsDir = join(openapiDir, "paths"); +if (!existsSync(pathsDir)) { + console.error(`golden shape drift: expected a paths/ directory at ${pathsDir}, but it does not exist`); + process.exit(1); +} + +const shardFiles = readdirSync(pathsDir) + .filter((name) => name.endsWith(".json")) + .sort(); +if (shardFiles.length === 0) { + console.error(`golden shape drift: ${pathsDir} contains no *.json shards`); + process.exit(1); +} + +const paths = {}; +for (const shard of shardFiles) { + const document = readJson(join(pathsDir, shard), `paths/${shard}`); + Object.assign(paths, document.paths ?? document); +} + +const operationIds = new Set(); +const fields = {}; +const orderBy = {}; +const expand = {}; +const METHODS = new Set(["get", "post", "patch", "delete", "put"]); + +for (const operations of Object.values(paths)) { + for (const [method, operation] of Object.entries(operations)) { + if (!METHODS.has(method) || !operation.operationId) continue; + operationIds.add(operation.operationId); + for (const parameter of operation.parameters ?? []) { + const values = parameter.schema?.enum; + if (!values) continue; + if (parameter.name === "fields") fields[operation.operationId] = [...values].sort(); + if (parameter.name === "order_by") orderBy[operation.operationId] = [...values].sort(); + if (parameter.name === "expand") expand[operation.operationId] = [...values].sort(); + } + } +} + +if (operationIds.size === 0) { + console.error("golden shape drift: extracted zero operationIds across all path shards — expected roughly 406"); + process.exit(1); +} + +if (Object.keys(fields).length === 0) { + console.error("golden shape drift: extracted zero `fields` enums across all path shards — expected roughly 316"); + process.exit(1); +} +if (Object.keys(orderBy).length === 0) { + console.error("golden shape drift: extracted zero `order_by` enums across all path shards — expected roughly 67"); + process.exit(1); +} +if (Object.keys(expand).length === 0) { + console.error("golden shape drift: extracted zero `expand` enums across all path shards — expected roughly 95"); + process.exit(1); +} + +const components = readJson(join(openapiDir, "components.json"), "components.json"); +const schemas = requireKeyPath(components, "components.json", "schemas"); +const schemaCount = Object.keys(schemas).length; +const bulkMax = requireKeyPath(components, "components.json", "schemas.BulkDeleteRequest.properties.ids.maxItems"); +if (typeof bulkMax !== "number") { + console.error( + `golden shape drift: components.json.schemas.BulkDeleteRequest.properties.ids.maxItems is ${JSON.stringify(bulkMax)}, expected a number` + ); + process.exit(1); +} + +for (const [convenienceName, operationId] of [ + ["STATE_FIELDS", "states_list"], + ["LABEL_FIELDS", "labels_list"], + ["WORK_ITEM_FIELDS", "work_items_list"], + ["CYCLE_FIELDS", "cycles_list"], + ["MODULE_FIELDS", "modules_list"], + ["MILESTONE_FIELDS", "milestones_list"], +]) { + if (!(operationId in fields)) { + console.error( + `golden shape drift: ${convenienceName} needs FIELDS["${operationId}"], but operation "${operationId}" carries no \`fields\` enum in the golden` + ); + process.exit(1); + } +} + +for (const [convenienceName, operationId] of [ + ["STATE_ORDER_BY", "states_list"], + ["LABEL_ORDER_BY", "labels_list"], + ["WORK_ITEM_ORDER_BY", "work_items_list"], + ["CYCLE_ORDER_BY", "cycles_list"], + ["MODULE_ORDER_BY", "modules_list"], + ["MILESTONE_ORDER_BY", "milestones_list"], +]) { + if (!(operationId in orderBy)) { + console.error( + `golden shape drift: ${convenienceName} needs ORDER_BY["${operationId}"], but operation "${operationId}" carries no \`order_by\` enum in the golden` + ); + process.exit(1); + } +} + +// `expand` is opt-in per operation (95 of ~316); WORK_ITEM_EXPAND gets the same +// named-convenience treatment as WORK_ITEM_FIELDS. Others stay reachable via EXPAND["operationId"]. +for (const [convenienceName, operationId] of [["WORK_ITEM_EXPAND", "work_items_list"]]) { + if (!(operationId in expand)) { + console.error( + `golden shape drift: ${convenienceName} needs EXPAND["${operationId}"], but operation "${operationId}" carries no \`expand\` enum in the golden` + ); + process.exit(1); + } +} + +const tuple = (values) => `[${values.map((value) => JSON.stringify(value)).join(", ")}] as const`; +// A plain comparator, not String#localeCompare — the keys are ASCII snake_case operation +// ids, and localeCompare's ordering can vary across ICU builds. Determinism over locale-awareness. +const compareAscii = (a, b) => (a < b ? -1 : a > b ? 1 : 0); +const record = (entries) => + Object.entries(entries) + .sort(([a], [b]) => compareAscii(a, b)) + .map(([key, values]) => ` ${JSON.stringify(key)}: ${tuple(values)},`) + .join("\n"); + +const sourceGoldenLine = `// Source golden: ${normalizedOpenapiDir}`; +const versionHeaderLine = `// api_v2 OpenAPI version: ${openapiVersion}`; +const versionExportLine = `export const OPENAPI_VERSION = ${JSON.stringify(openapiVersion)};`; + +const output = `// Generated from the api_v2 OpenAPI golden. Do not edit by hand. +${sourceGoldenLine} +${versionHeaderLine} +// Regenerate with: pnpm codegen:v2 /api_v2/core/schema/openapi + +${versionExportLine} + +export const BULK_MAX_ITEMS = ${bulkMax}; + +export const OPERATION_IDS = ${tuple([...operationIds].sort(compareAscii))}; + +export type OperationId = (typeof OPERATION_IDS)[number]; + +export const FIELDS = { +${record(fields)} +} as const; + +export const ORDER_BY = { +${record(orderBy)} +} as const; + +export const EXPAND = { +${record(expand)} +} as const; + +export const STATE_FIELDS = FIELDS["states_list"]; +export const LABEL_FIELDS = FIELDS["labels_list"]; +export const WORK_ITEM_FIELDS = FIELDS["work_items_list"]; +export const CYCLE_FIELDS = FIELDS["cycles_list"]; +export const MODULE_FIELDS = FIELDS["modules_list"]; +export const MILESTONE_FIELDS = FIELDS["milestones_list"]; + +export type StateField = (typeof STATE_FIELDS)[number]; +export type LabelField = (typeof LABEL_FIELDS)[number]; +export type WorkItemField = (typeof WORK_ITEM_FIELDS)[number]; +export type CycleField = (typeof CYCLE_FIELDS)[number]; +export type ModuleField = (typeof MODULE_FIELDS)[number]; +export type MilestoneField = (typeof MILESTONE_FIELDS)[number]; + +export const STATE_ORDER_BY = ORDER_BY["states_list"]; +export const LABEL_ORDER_BY = ORDER_BY["labels_list"]; +export const WORK_ITEM_ORDER_BY = ORDER_BY["work_items_list"]; +export const CYCLE_ORDER_BY = ORDER_BY["cycles_list"]; +export const MODULE_ORDER_BY = ORDER_BY["modules_list"]; +export const MILESTONE_ORDER_BY = ORDER_BY["milestones_list"]; + +export type StateOrderBy = (typeof STATE_ORDER_BY)[number]; +export type LabelOrderBy = (typeof LABEL_ORDER_BY)[number]; +export type WorkItemOrderBy = (typeof WORK_ITEM_ORDER_BY)[number]; +export type CycleOrderBy = (typeof CYCLE_ORDER_BY)[number]; +export type ModuleOrderBy = (typeof MODULE_ORDER_BY)[number]; +export type MilestoneOrderBy = (typeof MILESTONE_ORDER_BY)[number]; + +export const WORK_ITEM_EXPAND = EXPAND["work_items_list"]; + +export type WorkItemExpand = (typeof WORK_ITEM_EXPAND)[number]; +`; + +const target = join(repoRoot, "src", "api", "v2", "generated"); +mkdirSync(target, { recursive: true }); +const targetFile = join(target, "constants.ts"); +writeFileSync(targetFile, output); + +// Format the file ourselves so the documented single command reproduces the +// committed file exactly — no separate "now run the formatter" step to forget. +const oxfmtBin = join(repoRoot, "node_modules", ".bin", "oxfmt"); +execFileSync(oxfmtBin, [targetFile], { cwd: repoRoot, stdio: "inherit" }); + +// Confirm formatting didn't mangle or drop the header/export naming which golden +// version this file describes. +const written = readFileSync(targetFile, "utf8"); +for (const [label, line] of [ + ["source golden header", sourceGoldenLine], + ["version header", versionHeaderLine], + ["OPENAPI_VERSION export", versionExportLine], +]) { + if (!written.includes(line)) { + console.error(`golden shape drift: generated ${targetFile} is missing its ${label} ("${line}")`); + process.exit(1); + } +} + +console.log( + `wrote ${operationIds.size} operation ids, ${Object.keys(fields).length} field enums, ` + + `${Object.keys(orderBy).length} order_by enums, and ${Object.keys(expand).length} expand enums ` + + `(from ${schemaCount} schemas, ${shardFiles.length} path shards, api_v2 ${openapiVersion}) to ${targetFile}` +); diff --git a/src/api/v2/Artifacts.ts b/src/api/v2/Artifacts.ts new file mode 100644 index 0000000..66cc423 --- /dev/null +++ b/src/api/v2/Artifacts.ts @@ -0,0 +1,42 @@ +import { + Artifact, + ArtifactDetail, + ArtifactPublishResult, + UpdateArtifactUpdate, + ArtifactUpdateResult, + CreateArtifact, +} from "../../models/v2/Artifact"; +import { AnyOperationId, V2Resource } from "./kernel/resource"; + +/** Shareable HTML artifacts (api_v2), at `client.v2.workspace(slug).artifacts`. */ +export class Artifacts extends V2Resource { + protected path = "/workspaces/{slug}/artifacts/"; + protected operations: Record = { + create: "workspaces_artifacts_create", + retrieve: "workspaces_artifacts_retrieve", + publish: "workspaces_artifacts_publish_create", + update: "workspaces_artifacts_update_partial_update", + }; + + /** Create an artifact. Returns the summary row ({@link Artifact}), not the full detail — `retrieve` for that. */ + async create(data: CreateArtifact): Promise { + return this.transport.request("POST", this.collectionUrl({}), { data }); + } + + /** The full artifact, including its `html`. */ + async retrieve(artifactId: string): Promise { + return this.transport.request("GET", this.detailUrl({ pk: artifactId })); + } + + /** Publish the artifact, minting (or reusing) its public anchor. No request body — a plain `doAction`. */ + async publish(artifactId: string): Promise { + return this.doAction("publish", { pk: artifactId }); + } + + /** Updates `html`/`prompt`, bumping `current_version`. Hand-rolled PATCH-with-body — not `doAction`. */ + async update(artifactId: string, data: UpdateArtifactUpdate): Promise { + return this.transport.request("PATCH", `${this.detailUrl({ pk: artifactId })}update/`, { + data, + }); + } +} diff --git a/src/api/v2/Assets.ts b/src/api/v2/Assets.ts new file mode 100644 index 0000000..dcad7f2 --- /dev/null +++ b/src/api/v2/Assets.ts @@ -0,0 +1,73 @@ +import { Page } from "../../models/v2/common"; +import { + WorkspaceAsset, + WorkspaceAssetConfirmRequest, + WorkspaceAssetUploadRequest, +} from "../../models/v2/WorkspaceAsset"; +import { FIELDS, ORDER_BY } from "./generated/constants"; +import { OperationId, V2Resource } from "./kernel/resource"; + +export type WorkspaceAssetField = (typeof FIELDS)["assets_list"][number]; +export type WorkspaceAssetOrderBy = (typeof ORDER_BY)["assets_list"][number]; + +export interface ListWorkspaceAssetsParams { + fields?: readonly WorkspaceAssetField[]; + order_by?: WorkspaceAssetOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Workspace file assets — two-step upload: `create` returns S3 credentials, `update` (empty PATCH) confirms. `list` only shows uploaded assets. */ +export class Assets extends V2Resource { + protected path = "/workspaces/{slug}/assets/"; + protected operations: Record = { + list: "assets_list", + retrieve: "assets_retrieve", + create: "assets_create", + update: "assets_partial_update", + delete: "assets_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof WorkspaceAsset>( + params: ListWorkspaceAssetsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListWorkspaceAssetsParams): Promise>; + list(params?: ListWorkspaceAssetsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every uploaded asset, following pages automatically. */ + iterate(params?: ListWorkspaceAssetsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof WorkspaceAsset>( + assetId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(assetId: string, params?: { fields?: readonly WorkspaceAssetField[] }): Promise; + retrieve(assetId: string, params?: { fields?: readonly WorkspaceAssetField[] }): Promise { + return this.doRetrieve({ pk: assetId }, params as Record); + } + + /** Step 1: get upload credentials. Follow up with `update(...)` once the bytes land. */ + create( + data: WorkspaceAssetUploadRequest, + params?: { fields?: readonly WorkspaceAssetField[] } + ): Promise { + return this.doCreate(data, {}, params as Record); + } + + /** Step 2: confirm the upload. Takes no body — see {@link WorkspaceAssetConfirmRequest}. */ + update(assetId: string, params?: { fields?: readonly WorkspaceAssetField[] }): Promise { + return this.doUpdate({}, { pk: assetId }, params as Record); + } + + delete(assetId: string): Promise { + return this.doDelete({ pk: assetId }); + } +} diff --git a/src/api/v2/AuditLogs.ts b/src/api/v2/AuditLogs.ts new file mode 100644 index 0000000..b4d11a4 --- /dev/null +++ b/src/api/v2/AuditLogs.ts @@ -0,0 +1,60 @@ +import { Page } from "../../models/v2/common"; +import { AuditLog, AuditLogCategory, AuditLogOutcome } from "../../models/v2/AuditLog"; +import { FIELDS, ORDER_BY } from "./generated/constants"; +import { OperationId, V2Resource } from "./kernel/resource"; + +export type AuditLogField = (typeof FIELDS)["audit_logs_list"][number]; +export type AuditLogOrderBy = (typeof ORDER_BY)["audit_logs_list"][number]; + +export interface ListAuditLogsParams { + fields?: readonly AuditLogField[]; + actor_id?: string; + category?: AuditLogCategory; + outcome?: AuditLogOutcome; + event_name?: string; + ip_address?: string; + project_id?: string; + target_id?: string; + target_type?: string; + created_after?: string; + created_before?: string; + search?: string; + order_by?: AuditLogOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Audit logs (api_v2), workspace-scoped, at `client.v2.workspace(slug).auditLogs`. Read-only. */ +export class AuditLogs extends V2Resource { + protected path = "/workspaces/{slug}/audit-logs/"; + protected operations: Record = { + list: "audit_logs_list", + retrieve: "audit_logs_retrieve", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AuditLog>( + params: ListAuditLogsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListAuditLogsParams): Promise>; + list(params?: ListAuditLogsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every audit log entry, following pages automatically. */ + iterate(params?: ListAuditLogsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof AuditLog>( + auditLogId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(auditLogId: string, params?: { fields?: readonly AuditLogField[] }): Promise; + retrieve(auditLogId: string, params?: { fields?: readonly AuditLogField[] }): Promise { + return this.doRetrieve({ pk: auditLogId }, params as Record); + } +} diff --git a/src/api/v2/Automations/ProjectAutomationActivities.ts b/src/api/v2/Automations/ProjectAutomationActivities.ts new file mode 100644 index 0000000..e961773 --- /dev/null +++ b/src/api/v2/Automations/ProjectAutomationActivities.ts @@ -0,0 +1,68 @@ +import { Page } from "../../../models/v2/common"; +import { AutomationActivity } from "../../../models/v2/AutomationActivity"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type ProjectAutomationActivityField = (typeof FIELDS)["project_automation_activities_list"][number]; +export type ProjectAutomationActivityOrderBy = (typeof ORDER_BY)["project_automation_activities_list"][number]; + +export interface ListProjectAutomationActivitiesParams { + fields?: readonly ProjectAutomationActivityField[]; + field?: string; + verb?: string; + created_at__gt?: string; + order_by?: ProjectAutomationActivityOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Audit log for a project-scoped automation, at `...automations.activities`. Read-only. */ +export class ProjectAutomationActivities extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/automations/{automation_id}/activities/"; + protected operations: Record = { + list: "project_automation_activities_list", + retrieve: "project_automation_activities_retrieve", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationActivity>( + automationId: string, + params: ListProjectAutomationActivitiesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListProjectAutomationActivitiesParams): Promise>; + list(automationId: string, params?: ListProjectAutomationActivitiesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every activity, following pages automatically. */ + iterate(automationId: string, params?: ListProjectAutomationActivitiesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationActivity>( + automationId: string, + activityId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + activityId: string, + params?: { fields?: readonly ProjectAutomationActivityField[] } + ): Promise; + retrieve( + automationId: string, + activityId: string, + params?: { fields?: readonly ProjectAutomationActivityField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, activityId), params as Record); + } +} diff --git a/src/api/v2/Automations/ProjectAutomationEdges.ts b/src/api/v2/Automations/ProjectAutomationEdges.ts new file mode 100644 index 0000000..4889c09 --- /dev/null +++ b/src/api/v2/Automations/ProjectAutomationEdges.ts @@ -0,0 +1,82 @@ +import { Page } from "../../../models/v2/common"; +import { AutomationEdge, UpdateAutomationEdge, CreateAutomationEdge } from "../../../models/v2/AutomationEdge"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type ProjectAutomationEdgeField = (typeof FIELDS)["project_automation_edges_list"][number]; +export type ProjectAutomationEdgeOrderBy = (typeof ORDER_BY)["project_automation_edges_list"][number]; + +export interface ListProjectAutomationEdgesParams { + fields?: readonly ProjectAutomationEdgeField[]; + source_node_id?: string; + target_node_id?: string; + order_by?: ProjectAutomationEdgeOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Edges between nodes of a project-scoped automation's graph, at `...automations.edges`. */ +export class ProjectAutomationEdges extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/automations/{automation_id}/edges/"; + protected operations: Record = { + list: "project_automation_edges_list", + retrieve: "project_automation_edges_retrieve", + create: "project_automation_edges_create", + update: "project_automation_edges_partial_update", + delete: "project_automation_edges_destroy", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationEdge>( + automationId: string, + params: ListProjectAutomationEdgesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListProjectAutomationEdgesParams): Promise>; + list(automationId: string, params?: ListProjectAutomationEdgesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every edge, following pages automatically. */ + iterate(automationId: string, params?: ListProjectAutomationEdgesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationEdge>( + automationId: string, + edgeId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + edgeId: string, + params?: { fields?: readonly ProjectAutomationEdgeField[] } + ): Promise; + retrieve( + automationId: string, + edgeId: string, + params?: { fields?: readonly ProjectAutomationEdgeField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, edgeId), params as Record); + } + + create(automationId: string, data: CreateAutomationEdge): Promise { + return this.doCreate(data, this.pk(automationId)); + } + + update(automationId: string, edgeId: string, data: UpdateAutomationEdge): Promise { + return this.doUpdate(data, this.pk(automationId, edgeId)); + } + + delete(automationId: string, edgeId: string): Promise { + return this.doDelete(this.pk(automationId, edgeId)); + } +} diff --git a/src/api/v2/Automations/ProjectAutomationNodes.ts b/src/api/v2/Automations/ProjectAutomationNodes.ts new file mode 100644 index 0000000..adb4f9c --- /dev/null +++ b/src/api/v2/Automations/ProjectAutomationNodes.ts @@ -0,0 +1,102 @@ +import { Page } from "../../../models/v2/common"; +import { + AutomationNode, + UpdateAutomationNode, + AutomationNodeType, + CreateAutomationNode, + AutomationWebhookSecret, +} from "../../../models/v2/AutomationNode"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +export type ProjectAutomationNodeField = (typeof FIELDS)["project_automation_nodes_list"][number]; +export type ProjectAutomationNodeOrderBy = (typeof ORDER_BY)["project_automation_nodes_list"][number]; + +export interface ListProjectAutomationNodesParams { + fields?: readonly ProjectAutomationNodeField[]; + handler_name?: string; + is_enabled?: boolean; + name?: string; + node_type?: AutomationNodeType | string; + search?: string; + order_by?: ProjectAutomationNodeOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Nodes in a project-scoped automation's trigger/action/condition graph, at `...automations.nodes`. */ +export class ProjectAutomationNodes extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/automations/{automation_id}/nodes/"; + protected operations: Record = { + list: "project_automation_nodes_list", + retrieve: "project_automation_nodes_retrieve", + create: "project_automation_nodes_create", + update: "project_automation_nodes_partial_update", + delete: "project_automation_nodes_destroy", + "regenerate-webhook-secret": "project_automation_nodes_regenerate_webhook_secret", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationNode>( + automationId: string, + params: ListProjectAutomationNodesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListProjectAutomationNodesParams): Promise>; + list(automationId: string, params?: ListProjectAutomationNodesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every node, following pages automatically. */ + iterate(automationId: string, params?: ListProjectAutomationNodesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationNode>( + automationId: string, + nodeId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + nodeId: string, + params?: { fields?: readonly ProjectAutomationNodeField[] } + ): Promise; + retrieve( + automationId: string, + nodeId: string, + params?: { fields?: readonly ProjectAutomationNodeField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, nodeId), params as Record); + } + + /** The one node with this name; throws if none or several match. */ + findByName(automationId: string, name: string): Promise { + return this.doFindOne({ name }, this.pk(automationId)); + } + + create(automationId: string, data: CreateAutomationNode): Promise { + return this.doCreate(data, this.pk(automationId)); + } + + update(automationId: string, nodeId: string, data: UpdateAutomationNode): Promise { + return this.doUpdate(data, this.pk(automationId, nodeId)); + } + + delete(automationId: string, nodeId: string): Promise { + return this.doDelete(this.pk(automationId, nodeId)); + } + + /** Invalidates this webhook-trigger node's current secret and issues a new one. */ + regenerateWebhookSecret(automationId: string, nodeId: string): Promise { + return this.doAction("regenerate-webhook-secret", this.pk(automationId, nodeId)); + } +} diff --git a/src/api/v2/Automations/ProjectAutomations.ts b/src/api/v2/Automations/ProjectAutomations.ts new file mode 100644 index 0000000..39510ac --- /dev/null +++ b/src/api/v2/Automations/ProjectAutomations.ts @@ -0,0 +1,110 @@ +import { + Automation, + UpdateAutomation, + AutomationStatus, + SetAutomationStatus, + CreateAutomation, +} from "../../../models/v2/Automation"; +import { Page } from "../../../models/v2/common"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { ProjectAutomationActivities } from "./ProjectAutomationActivities"; +import { ProjectAutomationEdges } from "./ProjectAutomationEdges"; +import { ProjectAutomationNodes } from "./ProjectAutomationNodes"; + +export type ProjectAutomationField = (typeof FIELDS)["project_automations_list"][number]; +export type ProjectAutomationOrderBy = (typeof ORDER_BY)["project_automations_list"][number]; + +export interface ListProjectAutomationsParams { + fields?: readonly ProjectAutomationField[]; + name?: string; + scope?: string; + status?: AutomationStatus | string; + is_enabled?: boolean; + is_global?: boolean; + search?: string; + order_by?: ProjectAutomationOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Automations scoped to one project — CRUD, `status`, and sub-resources `nodes`/`edges`/`activities`. */ +export class ProjectAutomations extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/automations/"; + protected operations: Record = { + list: "project_automations_list", + retrieve: "project_automations_retrieve", + create: "project_automations_create", + update: "project_automations_partial_update", + delete: "project_automations_destroy", + setStatus: "project_automations_status", + }; + + public nodes: ProjectAutomationNodes; + public edges: ProjectAutomationEdges; + public activities: ProjectAutomationActivities; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.nodes = new ProjectAutomationNodes(transport, scope); + this.edges = new ProjectAutomationEdges(transport, scope); + this.activities = new ProjectAutomationActivities(transport, scope); + } + + private pk(id?: string): Record { + const params: Record = {}; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Automation>( + params: ListProjectAutomationsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListProjectAutomationsParams): Promise>; + list(params?: ListProjectAutomationsParams): Promise> { + return this.doList(this.pk(), params as Record); + } + + /** Every automation in the project, following pages automatically. */ + iterate(params?: ListProjectAutomationsParams): AsyncGenerator { + return this.doIterate(this.pk(), params as Record); + } + + retrieve & keyof Automation>( + automationId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(automationId: string, params?: { fields?: readonly ProjectAutomationField[] }): Promise; + retrieve(automationId: string, params?: { fields?: readonly ProjectAutomationField[] }): Promise { + return this.doRetrieve(this.pk(automationId), params as Record); + } + + /** The one automation with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, this.pk()); + } + + create(data: CreateAutomation): Promise { + return this.doCreate(data, this.pk()); + } + + update(automationId: string, data: UpdateAutomation): Promise { + return this.doUpdate(data, this.pk(automationId)); + } + + delete(automationId: string): Promise { + return this.doDelete(this.pk(automationId)); + } + + /** Enable/disable the automation — the only way to flip `is_enabled`/`status`. */ + async setStatus(automationId: string, data: SetAutomationStatus): Promise { + await this.transport.request("POST", `${this.detailUrl(this.pk(automationId))}status/`, { + data, + }); + } +} diff --git a/src/api/v2/Automations/WorkspaceAutomationActivities.ts b/src/api/v2/Automations/WorkspaceAutomationActivities.ts new file mode 100644 index 0000000..40f201a --- /dev/null +++ b/src/api/v2/Automations/WorkspaceAutomationActivities.ts @@ -0,0 +1,68 @@ +import { Page } from "../../../models/v2/common"; +import { AutomationActivity } from "../../../models/v2/AutomationActivity"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type WorkspaceAutomationActivityField = (typeof FIELDS)["workspace_automation_activities_list"][number]; +export type WorkspaceAutomationActivityOrderBy = (typeof ORDER_BY)["workspace_automation_activities_list"][number]; + +export interface ListWorkspaceAutomationActivitiesParams { + fields?: readonly WorkspaceAutomationActivityField[]; + field?: string; + verb?: string; + created_at__gt?: string; + order_by?: WorkspaceAutomationActivityOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Audit log for a workspace-scoped (global) automation, at `...automations.activities`. Read-only. */ +export class WorkspaceAutomationActivities extends V2Resource { + protected path = "/workspaces/{slug}/automations/{automation_id}/activities/"; + protected operations: Record = { + list: "workspace_automation_activities_list", + retrieve: "workspace_automation_activities_retrieve", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationActivity>( + automationId: string, + params: ListWorkspaceAutomationActivitiesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListWorkspaceAutomationActivitiesParams): Promise>; + list(automationId: string, params?: ListWorkspaceAutomationActivitiesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every activity, following pages automatically. */ + iterate(automationId: string, params?: ListWorkspaceAutomationActivitiesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationActivity>( + automationId: string, + activityId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + activityId: string, + params?: { fields?: readonly WorkspaceAutomationActivityField[] } + ): Promise; + retrieve( + automationId: string, + activityId: string, + params?: { fields?: readonly WorkspaceAutomationActivityField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, activityId), params as Record); + } +} diff --git a/src/api/v2/Automations/WorkspaceAutomationEdges.ts b/src/api/v2/Automations/WorkspaceAutomationEdges.ts new file mode 100644 index 0000000..99fca0f --- /dev/null +++ b/src/api/v2/Automations/WorkspaceAutomationEdges.ts @@ -0,0 +1,82 @@ +import { Page } from "../../../models/v2/common"; +import { AutomationEdge, UpdateAutomationEdge, CreateAutomationEdge } from "../../../models/v2/AutomationEdge"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type WorkspaceAutomationEdgeField = (typeof FIELDS)["workspace_automation_edges_list"][number]; +export type WorkspaceAutomationEdgeOrderBy = (typeof ORDER_BY)["workspace_automation_edges_list"][number]; + +export interface ListWorkspaceAutomationEdgesParams { + fields?: readonly WorkspaceAutomationEdgeField[]; + source_node_id?: string; + target_node_id?: string; + order_by?: WorkspaceAutomationEdgeOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Edges between nodes of a workspace-scoped (global) automation's graph, at `...automations.edges`. */ +export class WorkspaceAutomationEdges extends V2Resource { + protected path = "/workspaces/{slug}/automations/{automation_id}/edges/"; + protected operations: Record = { + list: "workspace_automation_edges_list", + retrieve: "workspace_automation_edges_retrieve", + create: "workspace_automation_edges_create", + update: "workspace_automation_edges_partial_update", + delete: "workspace_automation_edges_destroy", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationEdge>( + automationId: string, + params: ListWorkspaceAutomationEdgesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListWorkspaceAutomationEdgesParams): Promise>; + list(automationId: string, params?: ListWorkspaceAutomationEdgesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every edge, following pages automatically. */ + iterate(automationId: string, params?: ListWorkspaceAutomationEdgesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationEdge>( + automationId: string, + edgeId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + edgeId: string, + params?: { fields?: readonly WorkspaceAutomationEdgeField[] } + ): Promise; + retrieve( + automationId: string, + edgeId: string, + params?: { fields?: readonly WorkspaceAutomationEdgeField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, edgeId), params as Record); + } + + create(automationId: string, data: CreateAutomationEdge): Promise { + return this.doCreate(data, this.pk(automationId)); + } + + update(automationId: string, edgeId: string, data: UpdateAutomationEdge): Promise { + return this.doUpdate(data, this.pk(automationId, edgeId)); + } + + delete(automationId: string, edgeId: string): Promise { + return this.doDelete(this.pk(automationId, edgeId)); + } +} diff --git a/src/api/v2/Automations/WorkspaceAutomationNodes.ts b/src/api/v2/Automations/WorkspaceAutomationNodes.ts new file mode 100644 index 0000000..0fa3e1f --- /dev/null +++ b/src/api/v2/Automations/WorkspaceAutomationNodes.ts @@ -0,0 +1,102 @@ +import { Page } from "../../../models/v2/common"; +import { + AutomationNode, + UpdateAutomationNode, + AutomationNodeType, + CreateAutomationNode, + AutomationWebhookSecret, +} from "../../../models/v2/AutomationNode"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +export type WorkspaceAutomationNodeField = (typeof FIELDS)["workspace_automation_nodes_list"][number]; +export type WorkspaceAutomationNodeOrderBy = (typeof ORDER_BY)["workspace_automation_nodes_list"][number]; + +export interface ListWorkspaceAutomationNodesParams { + fields?: readonly WorkspaceAutomationNodeField[]; + handler_name?: string; + is_enabled?: boolean; + name?: string; + node_type?: AutomationNodeType | string; + search?: string; + order_by?: WorkspaceAutomationNodeOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Nodes in a workspace-scoped (global) automation's trigger/action/condition graph, at `...automations.nodes`. */ +export class WorkspaceAutomationNodes extends V2Resource { + protected path = "/workspaces/{slug}/automations/{automation_id}/nodes/"; + protected operations: Record = { + list: "workspace_automation_nodes_list", + retrieve: "workspace_automation_nodes_retrieve", + create: "workspace_automation_nodes_create", + update: "workspace_automation_nodes_partial_update", + delete: "workspace_automation_nodes_destroy", + "regenerate-webhook-secret": "workspace_automation_nodes_regenerate_webhook_secret", + }; + + private pk(automationId: string, id?: string): Record { + const params: Record = { automation_id: automationId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof AutomationNode>( + automationId: string, + params: ListWorkspaceAutomationNodesParams & { fields: readonly F[] } + ): Promise>>; + list(automationId: string, params?: ListWorkspaceAutomationNodesParams): Promise>; + list(automationId: string, params?: ListWorkspaceAutomationNodesParams): Promise> { + return this.doList(this.pk(automationId), params as Record); + } + + /** Every node, following pages automatically. */ + iterate(automationId: string, params?: ListWorkspaceAutomationNodesParams): AsyncGenerator { + return this.doIterate(this.pk(automationId), params as Record); + } + + retrieve & keyof AutomationNode>( + automationId: string, + nodeId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + automationId: string, + nodeId: string, + params?: { fields?: readonly WorkspaceAutomationNodeField[] } + ): Promise; + retrieve( + automationId: string, + nodeId: string, + params?: { fields?: readonly WorkspaceAutomationNodeField[] } + ): Promise { + return this.doRetrieve(this.pk(automationId, nodeId), params as Record); + } + + /** The one node with this name; throws if none or several match. */ + findByName(automationId: string, name: string): Promise { + return this.doFindOne({ name }, this.pk(automationId)); + } + + create(automationId: string, data: CreateAutomationNode): Promise { + return this.doCreate(data, this.pk(automationId)); + } + + update(automationId: string, nodeId: string, data: UpdateAutomationNode): Promise { + return this.doUpdate(data, this.pk(automationId, nodeId)); + } + + delete(automationId: string, nodeId: string): Promise { + return this.doDelete(this.pk(automationId, nodeId)); + } + + /** Invalidates this webhook-trigger node's current secret and issues a new one. */ + regenerateWebhookSecret(automationId: string, nodeId: string): Promise { + return this.doAction("regenerate-webhook-secret", this.pk(automationId, nodeId)); + } +} diff --git a/src/api/v2/Automations/WorkspaceAutomations.ts b/src/api/v2/Automations/WorkspaceAutomations.ts new file mode 100644 index 0000000..b2af0ac --- /dev/null +++ b/src/api/v2/Automations/WorkspaceAutomations.ts @@ -0,0 +1,110 @@ +import { + Automation, + UpdateAutomation, + AutomationStatus, + SetAutomationStatus, + CreateAutomation, +} from "../../../models/v2/Automation"; +import { Page } from "../../../models/v2/common"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { WorkspaceAutomationActivities } from "./WorkspaceAutomationActivities"; +import { WorkspaceAutomationEdges } from "./WorkspaceAutomationEdges"; +import { WorkspaceAutomationNodes } from "./WorkspaceAutomationNodes"; + +export type WorkspaceAutomationField = (typeof FIELDS)["workspace_automations_list"][number]; +export type WorkspaceAutomationOrderBy = (typeof ORDER_BY)["workspace_automations_list"][number]; + +export interface ListWorkspaceAutomationsParams { + fields?: readonly WorkspaceAutomationField[]; + name?: string; + scope?: string; + status?: AutomationStatus | string; + is_enabled?: boolean; + is_global?: boolean; + search?: string; + order_by?: WorkspaceAutomationOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Automations scoped to the whole workspace (`is_global=True`) — project-less sibling of `ProjectAutomations`. */ +export class WorkspaceAutomations extends V2Resource { + protected path = "/workspaces/{slug}/automations/"; + protected operations: Record = { + list: "workspace_automations_list", + retrieve: "workspace_automations_retrieve", + create: "workspace_automations_create", + update: "workspace_automations_partial_update", + delete: "workspace_automations_destroy", + setStatus: "workspace_automations_status", + }; + + public nodes: WorkspaceAutomationNodes; + public edges: WorkspaceAutomationEdges; + public activities: WorkspaceAutomationActivities; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.nodes = new WorkspaceAutomationNodes(transport, scope); + this.edges = new WorkspaceAutomationEdges(transport, scope); + this.activities = new WorkspaceAutomationActivities(transport, scope); + } + + private pk(id?: string): Record { + const params: Record = {}; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Automation>( + params: ListWorkspaceAutomationsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListWorkspaceAutomationsParams): Promise>; + list(params?: ListWorkspaceAutomationsParams): Promise> { + return this.doList(this.pk(), params as Record); + } + + /** Every workspace-scoped automation, following pages automatically. */ + iterate(params?: ListWorkspaceAutomationsParams): AsyncGenerator { + return this.doIterate(this.pk(), params as Record); + } + + retrieve & keyof Automation>( + automationId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(automationId: string, params?: { fields?: readonly WorkspaceAutomationField[] }): Promise; + retrieve(automationId: string, params?: { fields?: readonly WorkspaceAutomationField[] }): Promise { + return this.doRetrieve(this.pk(automationId), params as Record); + } + + /** The one automation with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, this.pk()); + } + + create(data: CreateAutomation): Promise { + return this.doCreate(data, this.pk()); + } + + update(automationId: string, data: UpdateAutomation): Promise { + return this.doUpdate(data, this.pk(automationId)); + } + + delete(automationId: string): Promise { + return this.doDelete(this.pk(automationId)); + } + + /** Enable/disable the automation — the only way to flip `is_enabled`/`status`. */ + async setStatus(automationId: string, data: SetAutomationStatus): Promise { + await this.transport.request("POST", `${this.detailUrl(this.pk(automationId))}status/`, { + data, + }); + } +} diff --git a/src/api/v2/Automations/index.ts b/src/api/v2/Automations/index.ts new file mode 100644 index 0000000..67335a1 --- /dev/null +++ b/src/api/v2/Automations/index.ts @@ -0,0 +1,66 @@ +import { V2Transport } from "../kernel/transport"; +import { ProjectAutomations } from "./ProjectAutomations"; +import { WorkspaceAutomations } from "./WorkspaceAutomations"; + +/** Automations — project-scoped and workspace-scoped (global) variants, each with its own path/operation ids. */ +export class Automations { + public project: ProjectAutomations; + public workspace: WorkspaceAutomations; + + constructor(transport: V2Transport, scope: Record = {}) { + this.project = new ProjectAutomations(transport, scope); + this.workspace = new WorkspaceAutomations(transport, scope); + } +} + +export { ProjectAutomations } from "./ProjectAutomations"; +export type { + ListProjectAutomationsParams, + ProjectAutomationField, + ProjectAutomationOrderBy, +} from "./ProjectAutomations"; +export { WorkspaceAutomations } from "./WorkspaceAutomations"; +export type { + ListWorkspaceAutomationsParams, + WorkspaceAutomationField, + WorkspaceAutomationOrderBy, +} from "./WorkspaceAutomations"; + +export { ProjectAutomationNodes } from "./ProjectAutomationNodes"; +export type { + ListProjectAutomationNodesParams, + ProjectAutomationNodeField, + ProjectAutomationNodeOrderBy, +} from "./ProjectAutomationNodes"; +export { WorkspaceAutomationNodes } from "./WorkspaceAutomationNodes"; +export type { + ListWorkspaceAutomationNodesParams, + WorkspaceAutomationNodeField, + WorkspaceAutomationNodeOrderBy, +} from "./WorkspaceAutomationNodes"; + +export { ProjectAutomationEdges } from "./ProjectAutomationEdges"; +export type { + ListProjectAutomationEdgesParams, + ProjectAutomationEdgeField, + ProjectAutomationEdgeOrderBy, +} from "./ProjectAutomationEdges"; +export { WorkspaceAutomationEdges } from "./WorkspaceAutomationEdges"; +export type { + ListWorkspaceAutomationEdgesParams, + WorkspaceAutomationEdgeField, + WorkspaceAutomationEdgeOrderBy, +} from "./WorkspaceAutomationEdges"; + +export { ProjectAutomationActivities } from "./ProjectAutomationActivities"; +export type { + ListProjectAutomationActivitiesParams, + ProjectAutomationActivityField, + ProjectAutomationActivityOrderBy, +} from "./ProjectAutomationActivities"; +export { WorkspaceAutomationActivities } from "./WorkspaceAutomationActivities"; +export type { + ListWorkspaceAutomationActivitiesParams, + WorkspaceAutomationActivityField, + WorkspaceAutomationActivityOrderBy, +} from "./WorkspaceAutomationActivities"; diff --git a/src/api/v2/Collections/Members.ts b/src/api/v2/Collections/Members.ts new file mode 100644 index 0000000..f636887 --- /dev/null +++ b/src/api/v2/Collections/Members.ts @@ -0,0 +1,38 @@ +import { + CollectionMember, + CollectionMembersManageRequest, + CollectionMembersManageResponse, +} from "../../../models/v2/Collection"; +import { EXPAND, FIELDS } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +export type CollectionMemberField = (typeof FIELDS)["collections_members_list"][number]; +export type CollectionMemberExpand = (typeof EXPAND)["collections_members_list"][number]; + +export interface ListCollectionMembersParams { + fields?: readonly CollectionMemberField[]; + expand?: readonly CollectionMemberExpand[]; +} + +/** Collection membership, at `...collections.members`. Returns a raw `CollectionMember[]`, not `Page` — no pagination. */ +export class CollectionMembers extends V2Resource { + protected path = "/workspaces/{slug}/collections/{pk}/members/"; + protected operations: Record = { + list: "collections_members_list", + manage: "collections_members", + }; + + /** Every member row for the collection — not paginated; see the class doc comment. */ + async list(collectionId: string, params?: ListCollectionMembersParams): Promise { + return this.transport.request("GET", this.collectionUrl({ pk: collectionId }), { + params: this.query(params as Record, "list"), + }); + } + + /** Bulk add/remove members. Re-adding an existing member with a different `access` updates that row. */ + async manage(collectionId: string, data: CollectionMembersManageRequest): Promise { + return this.transport.request("POST", this.collectionUrl({ pk: collectionId }), { + data, + }); + } +} diff --git a/src/api/v2/Collections/Pages.ts b/src/api/v2/Collections/Pages.ts new file mode 100644 index 0000000..959b1d8 --- /dev/null +++ b/src/api/v2/Collections/Pages.ts @@ -0,0 +1,39 @@ +import { + CollectionPageSearch, + CollectionPagesManageRequest, + CollectionPagesManageResponse, +} from "../../../models/v2/Collection"; +import { FIELDS } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +export type CollectionPageSearchField = (typeof FIELDS)["collections_pages_search"][number]; + +const PAGES_SEARCH_PATH = "/workspaces/{slug}/collections/{pk}/pages-search/"; + +/** Bulk page membership of a collection, at `...wiki.collections.pages` — `{add, remove}` id arrays, plus `search`. */ +export class CollectionPages extends V2Resource { + protected path = "/workspaces/{slug}/collections/{pk}/pages/"; + protected operations: Record = { + search: "collections_pages_search", + manage: "collections_pages", + }; + + /** Attach/detach pages by id. */ + async manage(collectionId: string, data: CollectionPagesManageRequest): Promise { + return this.transport.request("POST", this.collectionUrl({ pk: collectionId }), { + data, + }); + } + + /** + * Pages eligible to attach; raw array, no pagination. `search` works live but is absent from the golden's declared params — passed through anyway. + */ + async search( + collectionId: string, + params?: { fields?: readonly CollectionPageSearchField[]; search?: string } + ): Promise { + return this.transport.request("GET", this.urlFor(PAGES_SEARCH_PATH, { pk: collectionId }), { + params: this.query(params as Record, "search"), + }); + } +} diff --git a/src/api/v2/Collections/index.ts b/src/api/v2/Collections/index.ts new file mode 100644 index 0000000..df0cb84 --- /dev/null +++ b/src/api/v2/Collections/index.ts @@ -0,0 +1,125 @@ +import { MultipleMatchesFoundError, NoMatchFoundError } from "../../../errors/PlaneApiError"; +import { Page } from "../../../models/v2/common"; +import { Collection, UpdateCollection, CreateCollection } from "../../../models/v2/Collection"; +import { PageAccess } from "../../../models/v2/Page"; +import { EXPAND, FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { CollectionMembers } from "./Members"; +import { CollectionPages } from "./Pages"; + +export type CollectionField = (typeof FIELDS)["pages_list"][number]; +export type CollectionOrderBy = (typeof ORDER_BY)["pages_list"][number]; +export type CollectionExpand = (typeof EXPAND)["pages_list"][number]; + +export interface ListCollectionsParams { + fields?: readonly CollectionField[]; + expand?: readonly CollectionExpand[]; + access?: PageAccess; + is_default?: boolean; + is_global?: boolean; + owned_by_id?: string; + search?: string; + order_by?: CollectionOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Wiki collections — CRUD plus `members`/`pages` sub-resources. Golden operation ids are `pages_*` (historical). */ +export class Collections extends V2Resource { + protected path = "/workspaces/{slug}/collections/"; + protected operations: Record = { + list: "pages_list", + retrieve: "pages_retrieve", + create: "pages_create", + update: "pages_partial_update", + delete: "pages_destroy", + }; + + public members: CollectionMembers; + public pages: CollectionPages; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.members = new CollectionMembers(transport, scope); + this.pages = new CollectionPages(transport, scope); + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Collection>( + params: ListCollectionsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListCollectionsParams): Promise>; + list(params?: ListCollectionsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every collection in the workspace, following pages automatically. */ + iterate(params?: ListCollectionsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof Collection>( + collectionId: string, + params: { fields: readonly F[]; expand?: readonly CollectionExpand[] } + ): Promise>; + retrieve( + collectionId: string, + params?: { fields?: readonly CollectionField[]; expand?: readonly CollectionExpand[] } + ): Promise; + retrieve( + collectionId: string, + params?: { fields?: readonly CollectionField[]; expand?: readonly CollectionExpand[] } + ): Promise { + return this.doRetrieve({ pk: collectionId }, params as Record); + } + + /** The one collection with this name; throws if none or several match. Filters client-side — no `?name=` filter exists. */ + async findByName(name: string): Promise { + const matches: Collection[] = []; + for await (const row of this.iterate()) { + if (row.name === name) matches.push(row); + } + if (matches.length === 0) { + throw new NoMatchFoundError(`No ${this.constructor.name} matched name=${JSON.stringify(name)}.`); + } + if (matches.length > 1) { + throw new MultipleMatchesFoundError( + `Multiple rows matched name=${JSON.stringify(name)}; use the id instead, or list to see every match.` + ); + } + return matches[0]; + } + + create( + data: CreateCollection, + params?: { fields?: readonly CollectionField[]; expand?: readonly CollectionExpand[] } + ): Promise { + return this.doCreate(data, {}, params as Record); + } + + update( + collectionId: string, + data: UpdateCollection, + params?: { fields?: readonly CollectionField[]; expand?: readonly CollectionExpand[] } + ): Promise { + return this.doUpdate(data, { pk: collectionId }, params as Record); + } + + delete(collectionId: string): Promise { + return this.doDelete({ pk: collectionId }); + } + + /** The workspace's default ("General") collection — the one with `is_default: true`. Every workspace has exactly one. */ + default(): Promise { + return this.doFindOne({ is_default: true }, {}); + } +} + +export { CollectionMembers } from "./Members"; +export { CollectionPages } from "./Pages"; +export type { CollectionMemberExpand, CollectionMemberField, ListCollectionMembersParams } from "./Members"; +export type { CollectionPageSearchField } from "./Pages"; diff --git a/src/api/v2/CustomerProperties.ts b/src/api/v2/CustomerProperties.ts new file mode 100644 index 0000000..8dc1b47 --- /dev/null +++ b/src/api/v2/CustomerProperties.ts @@ -0,0 +1,79 @@ +import { Page } from "../../models/v2/common"; +import { + CustomerProperty, + UpdateCustomerProperty, + CustomerPropertyType, + CreateCustomerProperty, +} from "../../models/v2/CustomerProperty"; +import { FIELDS, ORDER_BY } from "./generated/constants"; +import { OperationId, V2Resource } from "./kernel/resource"; + +export type CustomerPropertyField = (typeof FIELDS)["customer_properties_list"][number]; +export type CustomerPropertyOrderBy = (typeof ORDER_BY)["customer_properties_list"][number]; + +export interface ListCustomerPropertiesParams { + fields?: readonly CustomerPropertyField[]; + name?: string; + is_active?: boolean; + is_required?: boolean; + property_type?: CustomerPropertyType; + search?: string; + order_by?: CustomerPropertyOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Custom properties on a workspace's customers, at `...customerProperties`. Workspace-scoped, unrelated to work-item properties. */ +export class CustomerProperties extends V2Resource { + protected path = "/workspaces/{slug}/customer-properties/"; + protected operations: Record = { + list: "customer_properties_list", + retrieve: "customer_properties_retrieve", + create: "customer_properties_create", + update: "customer_properties_partial_update", + delete: "customer_properties_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof CustomerProperty>( + params: ListCustomerPropertiesParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListCustomerPropertiesParams): Promise>; + list(params?: ListCustomerPropertiesParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every customer property, following pages automatically. */ + iterate(params?: ListCustomerPropertiesParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof CustomerProperty>( + propertyId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(propertyId: string, params?: { fields?: readonly CustomerPropertyField[] }): Promise; + retrieve(propertyId: string, params?: { fields?: readonly CustomerPropertyField[] }): Promise { + return this.doRetrieve({ pk: propertyId }, params as Record); + } + + /** The one customer property with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create(data: CreateCustomerProperty): Promise { + return this.doCreate(data, {}); + } + + update(propertyId: string, data: UpdateCustomerProperty): Promise { + return this.doUpdate(data, { pk: propertyId }); + } + + delete(propertyId: string): Promise { + return this.doDelete({ pk: propertyId }); + } +} diff --git a/src/api/v2/Customers/PropertyValues.ts b/src/api/v2/Customers/PropertyValues.ts new file mode 100644 index 0000000..e81b872 --- /dev/null +++ b/src/api/v2/Customers/PropertyValues.ts @@ -0,0 +1,21 @@ +import { CustomerPropertyValuesMap, CreateCustomerPropertyValues } from "../../../models/v2/CustomerPropertyValue"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +/** Bulk customer property values, at `...customers.propertyValues`. `list` returns `{property_id: [value, ...]}`. */ +export class CustomerPropertyValues extends V2Resource { + protected path = "/workspaces/{slug}/customers/{customer_id}/property-values/"; + protected operations: Record = { + list: "customer_property_values_list", + create: "customer_property_values_create", + }; + + /** `{property_id: [value, ...]}` for this customer's active properties with stored values. */ + async list(customerId: string): Promise { + return this.transport.request("GET", this.collectionUrl({ customer_id: customerId })); + } + + /** Bulk-set: only the property ids present in `data.values` are replaced. */ + async create(customerId: string, data: CreateCustomerPropertyValues): Promise { + await this.transport.request("POST", this.collectionUrl({ customer_id: customerId }), { data }); + } +} diff --git a/src/api/v2/Customers/Requests.ts b/src/api/v2/Customers/Requests.ts new file mode 100644 index 0000000..53b56ef --- /dev/null +++ b/src/api/v2/Customers/Requests.ts @@ -0,0 +1,81 @@ +import { Page } from "../../../models/v2/common"; +import { CustomerRequest, UpdateCustomerRequest, CreateCustomerRequest } from "../../../models/v2/CustomerRequest"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type CustomerRequestField = (typeof FIELDS)["customer_requests_list"][number]; +export type CustomerRequestOrderBy = (typeof ORDER_BY)["customer_requests_list"][number]; + +export interface ListCustomerRequestsParams { + fields?: readonly CustomerRequestField[]; + search?: string; + order_by?: CustomerRequestOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Requests raised by a customer, at `...customers.requests`. Nested under a customer via `customerId`. */ +export class CustomerRequests extends V2Resource { + protected path = "/workspaces/{slug}/customers/{customer_id}/requests/"; + protected operations: Record = { + list: "customer_requests_list", + retrieve: "customer_requests_retrieve", + create: "customer_requests_create", + update: "customer_requests_partial_update", + delete: "customer_requests_destroy", + }; + + private pk(customerId: string, id?: string): Record { + const params: Record = { customer_id: customerId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof CustomerRequest>( + customerId: string, + params: ListCustomerRequestsParams & { fields: readonly F[] } + ): Promise>>; + list(customerId: string, params?: ListCustomerRequestsParams): Promise>; + list(customerId: string, params?: ListCustomerRequestsParams): Promise> { + return this.doList(this.pk(customerId), params as Record); + } + + /** Every request, following pages automatically. */ + iterate(customerId: string, params?: ListCustomerRequestsParams): AsyncGenerator { + return this.doIterate(this.pk(customerId), params as Record); + } + + retrieve & keyof CustomerRequest>( + customerId: string, + requestId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + customerId: string, + requestId: string, + params?: { fields?: readonly CustomerRequestField[] } + ): Promise; + retrieve( + customerId: string, + requestId: string, + params?: { fields?: readonly CustomerRequestField[] } + ): Promise { + return this.doRetrieve(this.pk(customerId, requestId), params as Record); + } + + create(customerId: string, data: CreateCustomerRequest): Promise { + return this.doCreate(data, this.pk(customerId)); + } + + update(customerId: string, requestId: string, data: UpdateCustomerRequest): Promise { + return this.doUpdate(data, this.pk(customerId, requestId)); + } + + delete(customerId: string, requestId: string): Promise { + return this.doDelete(this.pk(customerId, requestId)); + } +} diff --git a/src/api/v2/Customers/index.ts b/src/api/v2/Customers/index.ts new file mode 100644 index 0000000..86b9eb2 --- /dev/null +++ b/src/api/v2/Customers/index.ts @@ -0,0 +1,117 @@ +import { Page } from "../../../models/v2/common"; +import { + Customer, + UpdateCustomer, + CustomerWorkItemManageRequest, + CustomerWorkItemManageResponse, + CreateCustomer, +} from "../../../models/v2/Customer"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { CustomerPropertyValues } from "./PropertyValues"; +import { CustomerRequests } from "./Requests"; + +export type CustomerField = (typeof FIELDS)["customers_list"][number]; +export type CustomerOrderBy = (typeof ORDER_BY)["customers_list"][number]; + +export interface ListCustomersParams { + fields?: readonly CustomerField[]; + name?: string; + domain?: string; + stage?: string; + contract_status?: string; + external_id?: string; + external_source?: string; + search?: string; + order_by?: CustomerOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Workspace CRM customers, at `...customers` — CRUD, `upsert`, and sub-resources `requests`/`propertyValues`. */ +export class Customers extends V2Resource { + protected path = "/workspaces/{slug}/customers/"; + protected operations: Record = { + list: "customers_list", + retrieve: "customers_retrieve", + create: "customers_create", + update: "customers_partial_update", + upsert: "customers_upsert", + delete: "customers_destroy", + manageWorkItems: "customers_work_items", + }; + + public requests: CustomerRequests; + public propertyValues: CustomerPropertyValues; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.requests = new CustomerRequests(transport, scope); + this.propertyValues = new CustomerPropertyValues(transport, scope); + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Customer>( + params: ListCustomersParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListCustomersParams): Promise>; + list(params?: ListCustomersParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every customer, following pages automatically. */ + iterate(params?: ListCustomersParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof Customer>( + customerId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(customerId: string, params?: { fields?: readonly CustomerField[] }): Promise; + retrieve(customerId: string, params?: { fields?: readonly CustomerField[] }): Promise { + return this.doRetrieve({ pk: customerId }, params as Record); + } + + /** The one customer with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create(data: CreateCustomer): Promise { + return this.doCreate(data, {}); + } + + update(customerId: string, data: UpdateCustomer): Promise { + return this.doUpdate(data, { pk: customerId }); + } + + delete(customerId: string): Promise { + return this.doDelete({ pk: customerId }); + } + + /** Reconciles on (external_source, external_id) when both are set. */ + upsert(data: CreateCustomer): Promise { + return this.doUpsert(data, {}); + } + + /** Bulk add/remove work items linked directly to this customer. Invalid/archived ids are silently skipped. */ + async manageWorkItems( + customerId: string, + data: CustomerWorkItemManageRequest + ): Promise { + return this.transport.request( + "POST", + `${this.detailUrl({ pk: customerId })}work-items/`, + { data } + ); + } +} + +export { CustomerPropertyValues } from "./PropertyValues"; +export { CustomerRequests } from "./Requests"; +export type { ListCustomerRequestsParams, CustomerRequestField, CustomerRequestOrderBy } from "./Requests"; diff --git a/src/api/v2/Cycles.ts b/src/api/v2/Cycles.ts new file mode 100644 index 0000000..9959e9d --- /dev/null +++ b/src/api/v2/Cycles.ts @@ -0,0 +1,126 @@ +import { BulkUpdateItem, BulkWriteResponse, Page } from "../../models/v2/common"; +import { Cycle, UpdateCycle, CreateCycle } from "../../models/v2/Cycle"; +import { + CycleTransferRequest, + CycleTransferResult, + CycleWorkItemManageRequest, + CycleWorkItemManageResponse, +} from "../../models/v2/CycleTransfer"; +import { CycleField, CycleOrderBy, EXPAND } from "./generated/constants"; +import { AnyOperationId, V2Resource } from "./kernel/resource"; + +/** `cycles_list`'s only expand target — the cycle's owner as a full object instead of `owned_by_id`. */ +export type CycleExpand = (typeof EXPAND)["cycles_list"][number]; + +export interface ListCyclesParams { + fields?: readonly CycleField[]; + name?: string; + owned_by_id?: string; + external_id?: string; + external_source?: string; + search?: string; + expand?: readonly CycleExpand[]; + order_by?: CycleOrderBy; + offset?: number; + per_page?: number; + /** `"cursor"` opts into the cursor envelope; pair with a cursor-safe `order_by` or expect a 400. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Project cycles, reached bound to a project. `transfer`/`manageWorkItems` are hand-written since `doAction` only issues a bodiless POST. */ +export class Cycles extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/cycles/"; + protected operations: Record = { + list: "cycles_list", + retrieve: "cycles_retrieve", + create: "cycles_create", + update: "cycles_partial_update", + upsert: "cycles_upsert", + delete: "cycles_destroy", + bulkCreate: "cycles_bulk_create", + bulkUpdate: "cycles_bulk_update", + bulkDelete: "cycles_bulk_delete", + transfer: "cycles_transfer", + manageWorkItems: "cycles_work_items_manage", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Cycle>( + params: ListCyclesParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListCyclesParams): Promise>; + list(params?: ListCyclesParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every cycle, following pages automatically. */ + iterate(params?: ListCyclesParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof Cycle>( + cycleId: string, + params: { fields: readonly F[]; expand?: readonly CycleExpand[] } + ): Promise>; + retrieve( + cycleId: string, + params?: { fields?: readonly CycleField[]; expand?: readonly CycleExpand[] } + ): Promise; + retrieve( + cycleId: string, + params?: { fields?: readonly CycleField[]; expand?: readonly CycleExpand[] } + ): Promise { + return this.doRetrieve({ pk: cycleId }, params as Record); + } + + /** The one cycle with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create(data: CreateCycle): Promise { + return this.doCreate(data, {}); + } + + update(cycleId: string, data: UpdateCycle): Promise { + return this.doUpdate(data, { pk: cycleId }); + } + + delete(cycleId: string): Promise { + return this.doDelete({ pk: cycleId }); + } + + /** Reconciles on (external_source, external_id) when both are set. */ + upsert(data: CreateCycle): Promise { + return this.doUpsert(data, {}); + } + + bulkCreate(items: CreateCycle[], allOrNone = false): Promise { + return this.doBulkCreate(items, {}, allOrNone); + } + + bulkUpdate(items: BulkUpdateItem[], allOrNone = false): Promise { + return this.doBulkUpdate(items, {}, allOrNone); + } + + bulkDelete(ids: string[], allOrNone = false): Promise { + return this.doBulkDelete(ids, {}, allOrNone); + } + + /** Move `cycleId`'s incomplete work items into `data.new_cycle_id`; `cycleId`'s cycle must already be completed. */ + async transfer(cycleId: string, data: CycleTransferRequest): Promise { + return this.transport.request("POST", `${this.detailUrl({ pk: cycleId })}transfer/`, { + data, + }); + } + + /** Bulk add/remove work items from `cycleId`'s membership (each of `data.add`/`data.remove` caps at 100 ids). */ + async manageWorkItems(cycleId: string, data: CycleWorkItemManageRequest): Promise { + return this.transport.request( + "POST", + `${this.detailUrl({ pk: cycleId })}work-items/`, + { data } + ); + } +} diff --git a/src/api/v2/Estimates/Points.ts b/src/api/v2/Estimates/Points.ts new file mode 100644 index 0000000..7d89808 --- /dev/null +++ b/src/api/v2/Estimates/Points.ts @@ -0,0 +1,110 @@ +import { BulkUpdateItem, BulkWriteResponse, Page } from "../../../models/v2/common"; +import { EstimatePoint, UpdateEstimatePoint, CreateEstimatePoint } from "../../../models/v2/EstimatePoint"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +export type EstimatePointField = (typeof FIELDS)["estimate_points_list"][number]; +export type EstimatePointOrderBy = (typeof ORDER_BY)["estimate_points_list"][number]; + +export interface ListEstimatePointsParams { + fields?: readonly EstimatePointField[]; + key?: number; + value?: string; + external_id?: string; + external_source?: string; + search?: string; + order_by?: EstimatePointOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** The values on an {@link Estimate}'s scale (api_v2). Nested under a project's estimate. */ +export class EstimatePoints extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/estimates/{estimate_id}/points/"; + protected operations: Record = { + list: "estimate_points_list", + retrieve: "estimate_points_retrieve", + create: "estimate_points_create", + update: "estimate_points_partial_update", + upsert: "estimate_points_upsert", + delete: "estimate_points_destroy", + bulkCreate: "estimate_points_bulk_create", + bulkUpdate: "estimate_points_bulk_update", + bulkDelete: "estimate_points_bulk_delete", + }; + + private pk(estimateId: string, id?: string): Record { + const params: Record = { estimate_id: estimateId }; + if (id !== undefined) params.pk = id; + return params; + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof EstimatePoint>( + estimateId: string, + params: ListEstimatePointsParams & { fields: readonly F[] } + ): Promise>>; + list(estimateId: string, params?: ListEstimatePointsParams): Promise>; + list(estimateId: string, params?: ListEstimatePointsParams): Promise> { + return this.doList(this.pk(estimateId), params as Record); + } + + /** Every point on the estimate's scale, following pages automatically. */ + iterate(estimateId: string, params?: ListEstimatePointsParams): AsyncGenerator { + return this.doIterate(this.pk(estimateId), params as Record); + } + + retrieve & keyof EstimatePoint>( + estimateId: string, + pointId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + estimateId: string, + pointId: string, + params?: { fields?: readonly EstimatePointField[] } + ): Promise; + retrieve( + estimateId: string, + pointId: string, + params?: { fields?: readonly EstimatePointField[] } + ): Promise { + return this.doRetrieve(this.pk(estimateId, pointId), params as Record); + } + + create(estimateId: string, data: CreateEstimatePoint): Promise { + return this.doCreate(data, this.pk(estimateId)); + } + + update(estimateId: string, pointId: string, data: UpdateEstimatePoint): Promise { + return this.doUpdate(data, this.pk(estimateId, pointId)); + } + + delete(estimateId: string, pointId: string): Promise { + return this.doDelete(this.pk(estimateId, pointId)); + } + + /** Reconciles on (external_source, external_id) when both are set. */ + upsert(estimateId: string, data: CreateEstimatePoint): Promise { + return this.doUpsert(data, this.pk(estimateId)); + } + + bulkCreate(estimateId: string, items: CreateEstimatePoint[], allOrNone = false): Promise { + return this.doBulkCreate(items, this.pk(estimateId), allOrNone); + } + + bulkUpdate( + estimateId: string, + items: BulkUpdateItem[], + allOrNone = false + ): Promise { + return this.doBulkUpdate(items, this.pk(estimateId), allOrNone); + } + + bulkDelete(estimateId: string, ids: string[], allOrNone = false): Promise { + return this.doBulkDelete(ids, this.pk(estimateId), allOrNone); + } +} diff --git a/src/api/v2/Estimates/index.ts b/src/api/v2/Estimates/index.ts new file mode 100644 index 0000000..682ec58 --- /dev/null +++ b/src/api/v2/Estimates/index.ts @@ -0,0 +1,128 @@ +import { BulkUpdateItem, BulkWriteResponse, Page } from "../../../models/v2/common"; +import { Estimate, UpdateEstimate, EstimateType, CreateEstimate } from "../../../models/v2/Estimate"; +import { EXPAND, FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { EstimatePoints } from "./Points"; + +export type EstimateField = (typeof FIELDS)["estimates_list"][number]; +export type EstimateOrderBy = (typeof ORDER_BY)["estimates_list"][number]; +/** Only `"points"` — inlines the estimate's point scale instead of a separate `points.list()` call. */ +export type EstimateExpand = (typeof EXPAND)["estimates_list"][number]; + +export interface ListEstimatesParams { + fields?: readonly EstimateField[]; + name?: string; + type?: EstimateType; + type__in?: readonly EstimateType[]; + external_id?: string; + external_source?: string; + search?: string; + expand?: readonly EstimateExpand[]; + order_by?: EstimateOrderBy; + offset?: number; + per_page?: number; + /** `"cursor"` needs a cursor-safe `order_by` (e.g. `"created_at"`) or it 400s. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Project estimate systems, each a named scale of points reachable via `.points`. */ +export class Estimates extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/estimates/"; + protected operations: Record = { + list: "estimates_list", + retrieve: "estimates_retrieve", + create: "estimates_create", + update: "estimates_partial_update", + upsert: "estimates_upsert", + delete: "estimates_destroy", + bulkCreate: "estimates_bulk_create", + bulkUpdate: "estimates_bulk_update", + bulkDelete: "estimates_bulk_delete", + }; + + /** The point values on each estimate's scale. */ + public points: EstimatePoints; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.points = new EstimatePoints(transport, scope); + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Estimate>( + params: ListEstimatesParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListEstimatesParams): Promise>; + list(params?: ListEstimatesParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every estimate in the project, following pages automatically. */ + iterate(params?: ListEstimatesParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof Estimate>( + estimateId: string, + params: { fields: readonly F[]; expand?: readonly EstimateExpand[] } + ): Promise>; + retrieve( + estimateId: string, + params?: { fields?: readonly EstimateField[]; expand?: readonly EstimateExpand[] } + ): Promise; + retrieve( + estimateId: string, + params?: { fields?: readonly EstimateField[]; expand?: readonly EstimateExpand[] } + ): Promise { + return this.doRetrieve({ pk: estimateId }, params as Record); + } + + /** The one estimate with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create( + data: CreateEstimate, + params?: { fields?: readonly EstimateField[]; expand?: readonly EstimateExpand[] } + ): Promise { + return this.doCreate(data, {}, params as Record); + } + + update( + estimateId: string, + data: UpdateEstimate, + params?: { fields?: readonly EstimateField[]; expand?: readonly EstimateExpand[] } + ): Promise { + return this.doUpdate(data, { pk: estimateId }, params as Record); + } + + delete(estimateId: string): Promise { + return this.doDelete({ pk: estimateId }); + } + + /** Reconciles on (external_source, external_id) when both are set. */ + upsert( + data: CreateEstimate, + params?: { fields?: readonly EstimateField[]; expand?: readonly EstimateExpand[] } + ): Promise { + return this.doUpsert(data, {}, params as Record); + } + + bulkCreate(items: CreateEstimate[], allOrNone = false): Promise { + return this.doBulkCreate(items, {}, allOrNone); + } + + bulkUpdate(items: BulkUpdateItem[], allOrNone = false): Promise { + return this.doBulkUpdate(items, {}, allOrNone); + } + + bulkDelete(ids: string[], allOrNone = false): Promise { + return this.doBulkDelete(ids, {}, allOrNone); + } +} + +export { EstimatePoints } from "./Points"; +export type { EstimatePointField, EstimatePointOrderBy, ListEstimatePointsParams } from "./Points"; diff --git a/src/api/v2/Features.ts b/src/api/v2/Features.ts new file mode 100644 index 0000000..5ff975c --- /dev/null +++ b/src/api/v2/Features.ts @@ -0,0 +1,41 @@ +import { + ProjectFeature, + UpdateProjectFeature, + WorkspaceFeature, + UpdateWorkspaceFeature, +} from "../../models/v2/Feature"; +import { AnyOperationId, V2Resource } from "./kernel/resource"; + +/** A workspace's feature flags — a singleton, so GET/PATCH are hand-rolled against `collectionUrl` (no `{pk}` segment). */ +export class WorkspaceFeatures extends V2Resource { + protected path = "/workspaces/{slug}/features/"; + protected operations: Record = { + retrieve: "workspace_features_retrieve", + update: "workspace_features_update", + }; + + async retrieve(): Promise { + return this.transport.request("GET", this.collectionUrl({})); + } + + async update(data: UpdateWorkspaceFeature): Promise { + return this.transport.request("PATCH", this.collectionUrl({}), { data }); + } +} + +/** A project's feature flags — same singleton shape as {@link WorkspaceFeatures}. */ +export class ProjectFeatures extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/features/"; + protected operations: Record = { + retrieve: "project_features_retrieve", + update: "project_features_update", + }; + + async retrieve(): Promise { + return this.transport.request("GET", this.collectionUrl({})); + } + + async update(data: UpdateProjectFeature): Promise { + return this.transport.request("PATCH", this.collectionUrl({}), { data }); + } +} diff --git a/src/api/v2/GroupSync/Config.ts b/src/api/v2/GroupSync/Config.ts new file mode 100644 index 0000000..f30d973 --- /dev/null +++ b/src/api/v2/GroupSync/Config.ts @@ -0,0 +1,22 @@ +import { GroupSyncConfig, UpdateGroupSyncConfig } from "../../../models/v2/GroupSyncConfig"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; + +/** Singleton workspace IdP group-sync config. GET/PATCH only; talks to the singleton URL directly, bypassing `doRetrieve`/`doUpdate`. */ +export class GroupSyncConfigResource extends V2Resource { + protected path = "/workspaces/{slug}/group-sync/config/"; + // No entry needed: this operation takes no `fields`/`order_by`/`expand`. + protected operations: Record = { + get: "group_sync_config_retrieve", + update: "group_sync_config_update", + }; + + // `async` is required: `urlFor` throws synchronously, and a non-async method + // returning the transport promise directly would let that escape as a throw. + async get(): Promise { + return this.transport.request("GET", this.urlFor(this.path, {})); + } + + async update(data: UpdateGroupSyncConfig): Promise { + return this.transport.request("PATCH", this.urlFor(this.path, {}), { data }); + } +} diff --git a/src/api/v2/GroupSync/ProjectMappings.ts b/src/api/v2/GroupSync/ProjectMappings.ts new file mode 100644 index 0000000..9add3a6 --- /dev/null +++ b/src/api/v2/GroupSync/ProjectMappings.ts @@ -0,0 +1,65 @@ +import { Page } from "../../../models/v2/common"; +import { GroupMapping, UpdateGroupMapping, CreateGroupMapping } from "../../../models/v2/GroupMapping"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type GroupSyncProjectMappingField = (typeof FIELDS)["group_sync_project_mappings_list"][number]; +export type GroupSyncProjectMappingOrderBy = (typeof ORDER_BY)["group_sync_project_mappings_list"][number]; + +export interface ListGroupSyncProjectMappingsParams { + fields?: readonly GroupSyncProjectMappingField[]; + search?: string; + order_by?: GroupSyncProjectMappingOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** IdP group -> project(s) + role mappings for SSO/SCIM sync. No upsert or bulk write. */ +export class GroupSyncProjectMappings extends V2Resource { + protected path = "/workspaces/{slug}/group-sync/project-mappings/"; + protected operations: Record = { + list: "group_sync_project_mappings_list", + retrieve: "group_sync_project_mappings_retrieve", + create: "group_sync_project_mappings_create", + update: "group_sync_project_mappings_update", + delete: "group_sync_project_mappings_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof GroupMapping>( + params: ListGroupSyncProjectMappingsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListGroupSyncProjectMappingsParams): Promise>; + list(params?: ListGroupSyncProjectMappingsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every mapping, following pages automatically. */ + iterate(params?: ListGroupSyncProjectMappingsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof GroupMapping>( + mappingId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(mappingId: string, params?: { fields?: readonly GroupSyncProjectMappingField[] }): Promise; + retrieve(mappingId: string, params?: { fields?: readonly GroupSyncProjectMappingField[] }): Promise { + return this.doRetrieve({ pk: mappingId }, params as Record); + } + + create(data: CreateGroupMapping): Promise { + return this.doCreate(data, {}); + } + + update(mappingId: string, data: UpdateGroupMapping): Promise { + return this.doUpdate(data, { pk: mappingId }); + } + + delete(mappingId: string): Promise { + return this.doDelete({ pk: mappingId }); + } +} diff --git a/src/api/v2/GroupSync/WorkspaceMappings.ts b/src/api/v2/GroupSync/WorkspaceMappings.ts new file mode 100644 index 0000000..d4faae8 --- /dev/null +++ b/src/api/v2/GroupSync/WorkspaceMappings.ts @@ -0,0 +1,79 @@ +import { Page } from "../../../models/v2/common"; +import { + WorkspaceGroupMapping, + UpdateWorkspaceGroupMapping, + CreateWorkspaceGroupMapping, +} from "../../../models/v2/WorkspaceGroupMapping"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type GroupSyncWorkspaceMappingField = (typeof FIELDS)["group_sync_workspace_mappings_list"][number]; +export type GroupSyncWorkspaceMappingOrderBy = (typeof ORDER_BY)["group_sync_workspace_mappings_list"][number]; + +export interface ListGroupSyncWorkspaceMappingsParams { + fields?: readonly GroupSyncWorkspaceMappingField[]; + search?: string; + order_by?: GroupSyncWorkspaceMappingOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** IdP group -> workspace role mappings for SSO/SCIM sync. No upsert or bulk write. */ +export class GroupSyncWorkspaceMappings extends V2Resource< + WorkspaceGroupMapping, + CreateWorkspaceGroupMapping, + UpdateWorkspaceGroupMapping +> { + protected path = "/workspaces/{slug}/group-sync/workspace-mappings/"; + protected operations: Record = { + list: "group_sync_workspace_mappings_list", + retrieve: "group_sync_workspace_mappings_retrieve", + create: "group_sync_workspace_mappings_create", + update: "group_sync_workspace_mappings_update", + delete: "group_sync_workspace_mappings_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof WorkspaceGroupMapping>( + params: ListGroupSyncWorkspaceMappingsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListGroupSyncWorkspaceMappingsParams): Promise>; + list(params?: ListGroupSyncWorkspaceMappingsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every mapping, following pages automatically. */ + iterate(params?: ListGroupSyncWorkspaceMappingsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof WorkspaceGroupMapping>( + mappingId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve( + mappingId: string, + params?: { fields?: readonly GroupSyncWorkspaceMappingField[] } + ): Promise; + retrieve( + mappingId: string, + params?: { fields?: readonly GroupSyncWorkspaceMappingField[] } + ): Promise { + return this.doRetrieve({ pk: mappingId }, params as Record); + } + + create(data: CreateWorkspaceGroupMapping): Promise { + return this.doCreate(data, {}); + } + + update(mappingId: string, data: UpdateWorkspaceGroupMapping): Promise { + return this.doUpdate(data, { pk: mappingId }); + } + + delete(mappingId: string): Promise { + return this.doDelete({ pk: mappingId }); + } +} diff --git a/src/api/v2/GroupSync/index.ts b/src/api/v2/GroupSync/index.ts new file mode 100644 index 0000000..a83f700 --- /dev/null +++ b/src/api/v2/GroupSync/index.ts @@ -0,0 +1,31 @@ +import { V2Transport } from "../kernel/transport"; +import { GroupSyncConfigResource } from "./Config"; +import { GroupSyncProjectMappings } from "./ProjectMappings"; +import { GroupSyncWorkspaceMappings } from "./WorkspaceMappings"; + +/** IdP group-sync: the config singleton plus the project- and workspace-level mapping collections. */ +export class GroupSync { + public config: GroupSyncConfigResource; + public projectMappings: GroupSyncProjectMappings; + public workspaceMappings: GroupSyncWorkspaceMappings; + + constructor(transport: V2Transport, scope: Record = {}) { + this.config = new GroupSyncConfigResource(transport, scope); + this.projectMappings = new GroupSyncProjectMappings(transport, scope); + this.workspaceMappings = new GroupSyncWorkspaceMappings(transport, scope); + } +} + +export { GroupSyncConfigResource } from "./Config"; +export { GroupSyncProjectMappings } from "./ProjectMappings"; +export type { + GroupSyncProjectMappingField, + GroupSyncProjectMappingOrderBy, + ListGroupSyncProjectMappingsParams, +} from "./ProjectMappings"; +export { GroupSyncWorkspaceMappings } from "./WorkspaceMappings"; +export type { + GroupSyncWorkspaceMappingField, + GroupSyncWorkspaceMappingOrderBy, + ListGroupSyncWorkspaceMappingsParams, +} from "./WorkspaceMappings"; diff --git a/src/api/v2/Initiatives/Labels.ts b/src/api/v2/Initiatives/Labels.ts new file mode 100644 index 0000000..1c870a3 --- /dev/null +++ b/src/api/v2/Initiatives/Labels.ts @@ -0,0 +1,71 @@ +import { Page } from "../../../models/v2/common"; +import { InitiativeLabel, UpdateInitiativeLabel, CreateInitiativeLabel } from "../../../models/v2/InitiativeLabel"; +import { FIELDS, ORDER_BY } from "../generated/constants"; +import { OperationId, V2Resource } from "../kernel/resource"; + +export type InitiativeLabelField = (typeof FIELDS)["initiative_labels_list"][number]; +export type InitiativeLabelOrderBy = (typeof ORDER_BY)["initiative_labels_list"][number]; + +export interface ListInitiativeLabelsParams { + fields?: readonly InitiativeLabelField[]; + name?: string; + search?: string; + order_by?: InitiativeLabelOrderBy; + offset?: number; + per_page?: number; + /** `"cursor"` needs a cursor-safe `order_by` (e.g. `"created_at"`) or it 400s. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Workspace-level initiative label catalog — not the per-initiative association (`Initiatives.manageLabels`). */ +export class InitiativeLabels extends V2Resource { + protected path = "/workspaces/{slug}/initiatives/labels/"; + protected operations: Record = { + list: "initiative_labels_list", + retrieve: "initiative_labels_retrieve", + create: "initiative_labels_create", + update: "initiative_labels_partial_update", + delete: "initiative_labels_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof InitiativeLabel>( + params: ListInitiativeLabelsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListInitiativeLabelsParams): Promise>; + list(params?: ListInitiativeLabelsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every initiative label, following pages automatically. */ + iterate(params?: ListInitiativeLabelsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof InitiativeLabel>( + labelId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(labelId: string, params?: { fields?: readonly InitiativeLabelField[] }): Promise; + retrieve(labelId: string, params?: { fields?: readonly InitiativeLabelField[] }): Promise { + return this.doRetrieve({ pk: labelId }, params as Record); + } + + /** The one initiative label with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create(data: CreateInitiativeLabel): Promise { + return this.doCreate(data, {}); + } + + update(labelId: string, data: UpdateInitiativeLabel): Promise { + return this.doUpdate(data, { pk: labelId }); + } + + delete(labelId: string): Promise { + return this.doDelete({ pk: labelId }); + } +} diff --git a/src/api/v2/Initiatives/index.ts b/src/api/v2/Initiatives/index.ts new file mode 100644 index 0000000..3765bed --- /dev/null +++ b/src/api/v2/Initiatives/index.ts @@ -0,0 +1,136 @@ +import { Page } from "../../../models/v2/common"; +import { + Initiative, + InitiativeChildManageRequest, + InitiativeChildManageResponse, + UpdateInitiative, + InitiativeState, + CreateInitiative, +} from "../../../models/v2/Initiative"; +import { EXPAND, FIELDS, ORDER_BY } from "../generated/constants"; +import { AnyOperationId, V2Resource } from "../kernel/resource"; +import { V2Transport } from "../kernel/transport"; +import { InitiativeLabels } from "./Labels"; + +export type InitiativeField = (typeof FIELDS)["initiatives_list"][number]; +export type InitiativeOrderBy = (typeof ORDER_BY)["initiatives_list"][number]; +/** Only `"lead"` is expandable on this resource. */ +export type InitiativeExpand = (typeof EXPAND)["initiatives_list"][number]; + +export interface ListInitiativesParams { + fields?: readonly InitiativeField[]; + expand?: readonly InitiativeExpand[]; + name?: string; + lead_id?: string; + state?: InitiativeState; + state__in?: readonly InitiativeState[]; + search?: string; + order_by?: InitiativeOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Workspace initiatives — workspace-scoped, not project-scoped (no `project_id` path segment). */ +export class Initiatives extends V2Resource { + protected path = "/workspaces/{slug}/initiatives/"; + protected operations: Record = { + list: "initiatives_list", + retrieve: "initiatives_retrieve", + create: "initiatives_create", + update: "initiatives_partial_update", + delete: "initiatives_destroy", + manageLabels: "initiatives_labels", + manageProjects: "initiatives_projects", + manageWorkItems: "initiatives_work_items", + }; + + public labels: InitiativeLabels; + + constructor(transport: V2Transport, scope: Record = {}) { + super(transport, scope); + this.labels = new InitiativeLabels(transport, scope); + } + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Initiative>( + params: ListInitiativesParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListInitiativesParams): Promise>; + list(params?: ListInitiativesParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every initiative, following pages automatically. */ + iterate(params?: ListInitiativesParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof Initiative>( + initiativeId: string, + params: { fields: readonly F[]; expand?: readonly InitiativeExpand[] } + ): Promise>; + retrieve( + initiativeId: string, + params?: { fields?: readonly InitiativeField[]; expand?: readonly InitiativeExpand[] } + ): Promise; + retrieve( + initiativeId: string, + params?: { fields?: readonly InitiativeField[]; expand?: readonly InitiativeExpand[] } + ): Promise { + return this.doRetrieve({ pk: initiativeId }, params as Record); + } + + /** The one initiative with this name; throws if none or several match. */ + findByName(name: string): Promise { + return this.doFindOne({ name }, {}); + } + + create(data: CreateInitiative, params?: { expand?: readonly InitiativeExpand[] }): Promise { + return this.doCreate(data, {}, params as Record); + } + + update( + initiativeId: string, + data: UpdateInitiative, + params?: { expand?: readonly InitiativeExpand[] } + ): Promise { + return this.doUpdate(data, { pk: initiativeId }, params as Record); + } + + delete(initiativeId: string): Promise { + return this.doDelete({ pk: initiativeId }); + } + + private async manageChild( + initiativeId: string, + action: "projects" | "work-items" | "labels", + data: InitiativeChildManageRequest + ): Promise { + return this.transport.request( + "POST", + `${this.detailUrl({ pk: initiativeId })}${action}/`, + { data } + ); + } + + /** Bulk add/remove projects; invalid/out-of-workspace ids are silently skipped. */ + manageProjects(initiativeId: string, data: InitiativeChildManageRequest): Promise { + return this.manageChild(initiativeId, "projects", data); + } + + /** Bulk add/remove work items (any type, including epics); replaces v1 `/epics/`. */ + manageWorkItems(initiativeId: string, data: InitiativeChildManageRequest): Promise { + return this.manageChild(initiativeId, "work-items", data); + } + + /** Bulk add/remove workspace initiative labels ({@link InitiativeLabels}) on this initiative. */ + manageLabels(initiativeId: string, data: InitiativeChildManageRequest): Promise { + return this.manageChild(initiativeId, "labels", data); + } +} + +export { InitiativeLabels } from "./Labels"; +export type { InitiativeLabelField, InitiativeLabelOrderBy, ListInitiativeLabelsParams } from "./Labels"; diff --git a/src/api/v2/Intakes.ts b/src/api/v2/Intakes.ts new file mode 100644 index 0000000..2b2ec54 --- /dev/null +++ b/src/api/v2/Intakes.ts @@ -0,0 +1,77 @@ +import { Page } from "../../models/v2/common"; +import { + IntakeWorkItem, + UpdateIntakeWorkItem, + IntakeWorkItemStatus, + CreateIntakeWorkItem, +} from "../../models/v2/IntakeWorkItem"; +import { FIELDS, ORDER_BY } from "./generated/constants"; +import { OperationId, V2Resource } from "./kernel/resource"; + +export type IntakeWorkItemField = (typeof FIELDS)["intakes_list"][number]; +export type IntakeWorkItemOrderBy = (typeof ORDER_BY)["intakes_list"][number]; + +export interface ListIntakeWorkItemsParams { + fields?: readonly IntakeWorkItemField[]; + search?: string; + source?: string; + status?: IntakeWorkItemStatus; + status__in?: readonly IntakeWorkItemStatus[]; + work_item_id?: string; + external_id?: string; + external_source?: string; + order_by?: IntakeWorkItemOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** A project's intake (triage queue) items; the wire path is `intake-issues`, kept as-is. No `upsert`/bulk endpoints. */ +export class Intakes extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/intake-issues/"; + protected operations: Record = { + list: "intakes_list", + retrieve: "intakes_retrieve", + create: "intakes_create", + update: "intakes_partial_update", + delete: "intakes_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof IntakeWorkItem>( + params: ListIntakeWorkItemsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListIntakeWorkItemsParams): Promise>; + list(params?: ListIntakeWorkItemsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every intake item in the project, following pages automatically. */ + iterate(params?: ListIntakeWorkItemsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof IntakeWorkItem>( + intakeWorkItemId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(intakeWorkItemId: string, params?: { fields?: readonly IntakeWorkItemField[] }): Promise; + retrieve(intakeWorkItemId: string, params?: { fields?: readonly IntakeWorkItemField[] }): Promise { + return this.doRetrieve({ pk: intakeWorkItemId }, params as Record); + } + + create(data: CreateIntakeWorkItem): Promise { + return this.doCreate(data, {}); + } + + /** Ordinary field edits and/or a triage decision (`status`/`snoozed_till`/`duplicate_to_id`) in one call. */ + update(intakeWorkItemId: string, data: UpdateIntakeWorkItem): Promise { + return this.doUpdate(data, { pk: intakeWorkItemId }); + } + + delete(intakeWorkItemId: string): Promise { + return this.doDelete({ pk: intakeWorkItemId }); + } +} diff --git a/src/api/v2/Invitations.ts b/src/api/v2/Invitations.ts new file mode 100644 index 0000000..b08e9d6 --- /dev/null +++ b/src/api/v2/Invitations.ts @@ -0,0 +1,75 @@ +import { Page } from "../../models/v2/common"; +import { WorkspaceInvite, BulkCreateWorkspaceInvites, CreateWorkspaceInvite } from "../../models/v2/WorkspaceInvite"; +import { FIELDS, ORDER_BY } from "./generated/constants"; +import { OperationId, V2Resource } from "./kernel/resource"; + +export type WorkspaceInviteField = (typeof FIELDS)["members_list"][number]; +export type WorkspaceInviteOrderBy = (typeof ORDER_BY)["members_list"][number]; + +export interface ListInvitationsParams { + fields?: readonly WorkspaceInviteField[]; + accepted?: boolean; + email?: string; + search?: string; + order_by?: WorkspaceInviteOrderBy; + offset?: number; + per_page?: number; + /** Set to `"cursor"` to opt into the cursor envelope — see `ListStatesParams.paginate`. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Workspace invitations; no PATCH (accepted/declined by the invitee, not edited) and no `upsert`. */ +export class Invitations extends V2Resource { + protected path = "/workspaces/{slug}/invitations/"; + protected operations: Record = { + list: "members_list", + retrieve: "members_retrieve", + create: "members_create", + bulk: "members_bulk", + delete: "members_destroy", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof WorkspaceInvite>( + params: ListInvitationsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListInvitationsParams): Promise>; + list(params?: ListInvitationsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every invitation, following pages automatically. */ + iterate(params?: ListInvitationsParams): AsyncGenerator { + return this.doIterate({}, params as Record); + } + + retrieve & keyof WorkspaceInvite>( + inviteId: string, + params: { fields: readonly F[] } + ): Promise>; + retrieve(inviteId: string, params?: { fields?: readonly WorkspaceInviteField[] }): Promise; + retrieve(inviteId: string, params?: { fields?: readonly WorkspaceInviteField[] }): Promise { + return this.doRetrieve({ pk: inviteId }, params as Record); + } + + create(data: CreateWorkspaceInvite): Promise { + return this.doCreate(data, {}); + } + + /** Revoke an invitation. The API rejects revoking one already accepted (400). */ + delete(inviteId: string): Promise { + return this.doDelete({ pk: inviteId }); + } + + /** Invite up to 100 emails. Golden's schema shows a single object; the live view returns an array — modeled as such. */ + async bulk( + data: BulkCreateWorkspaceInvites, + params?: { fields?: readonly WorkspaceInviteField[] } + ): Promise { + return this.transport.request("POST", `${this.collectionUrl({})}bulk/`, { + params: this.query(params, "bulk"), + data, + }); + } +} diff --git a/src/api/v2/Labels.ts b/src/api/v2/Labels.ts new file mode 100644 index 0000000..8049baf --- /dev/null +++ b/src/api/v2/Labels.ts @@ -0,0 +1,93 @@ +import { BulkUpdateItem, BulkWriteResponse, Page } from "../../models/v2/common"; +import { Label, UpdateLabel, CreateLabel } from "../../models/v2/Label"; +import { LabelField, LabelOrderBy } from "./generated/constants"; +import { AnyOperationId, V2Resource } from "./kernel/resource"; + +export interface ListLabelsParams { + fields?: readonly LabelField[]; + name?: string; + parent_id?: string; + parent_id__isnull?: boolean; + external_id?: string; + external_source?: string; + search?: string; + order_by?: LabelOrderBy; + offset?: number; + per_page?: number; + /** `"cursor"` opts into the cursor envelope; pair with a cursor-safe `order_by` or expect a 400. */ + paginate?: "cursor"; + count?: boolean; +} + +/** Project labels, reached bound to a project (`project` accepts a project id or its key, e.g. `ENG`). */ +export class Labels extends V2Resource { + protected path = "/workspaces/{slug}/projects/{project_id}/labels/"; + protected operations: Record = { + list: "labels_list", + retrieve: "labels_retrieve", + create: "labels_create", + update: "labels_partial_update", + upsert: "labels_upsert", + delete: "labels_destroy", + bulkCreate: "labels_bulk_create", + bulkUpdate: "labels_bulk_update", + bulkDelete: "labels_bulk_delete", + }; + + /** The row shape returned when `fields` is a literal tuple. `id` is always present. */ + list & keyof Label>( + params: ListLabelsParams & { fields: readonly F[] } + ): Promise>>; + list(params?: ListLabelsParams): Promise>; + list(params?: ListLabelsParams): Promise> { + return this.doList({}, params as Record); + } + + /** Every label, following pages automatically. */ + iterate(params?: ListLabelsParams): AsyncGenerator