├── .eslintignore ├── src ├── types.d.ts ├── index.ts ├── __tests__ │ ├── index-test.ts │ └── ShortcutApi-unmock-test.ts ├── ShortcutClient.ts └── generated │ ├── http-client.ts │ └── Api.ts ├── .prettierignore ├── typedoc.json ├── .npmignore ├── examples ├── tsconfig.json ├── logo.png ├── .eslintrc ├── listCustomFields.ts ├── getCurrentMemberInfo.ts ├── README.md └── uploadFileToStory.ts ├── .gitignore ├── tsconfig.json ├── .prettierrc ├── tsdown.config.ts ├── .github └── workflows │ ├── gh-pages.yml │ ├── publish.yml │ └── ci.yml ├── scripts └── add-typedoc-comments.ts ├── .eslintrc ├── LICENSE ├── templates ├── api.ejs └── http-client.ejs ├── package.json └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | /src/generated 2 | /lib 3 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'stream-to-blob'; 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /src/generated 2 | /schema 3 | /lib 4 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "headings": { 3 | "readme": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | /src 4 | **/__tests__/** 5 | /docs 6 | /schema 7 | -------------------------------------------------------------------------------- /examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "ts-node": { 3 | "files": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/useshortcut/shortcut-client-js/HEAD/examples/logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | lib/ 4 | node_modules/ 5 | npm-debug.log 6 | package-lock.json 7 | /docs 8 | *.log 9 | -------------------------------------------------------------------------------- /examples/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": 0, 4 | "import/no-extraneous-dependencies": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@total-typescript/tsconfig/bundler/no-dom/library", 3 | "include": ["src"], 4 | "exclude": ["**/__tests__/**"] 5 | } 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { ShortcutClient as default } from './ShortcutClient'; 2 | export * from './ShortcutClient'; 3 | export * from './generated/data-contracts'; 4 | -------------------------------------------------------------------------------- /src/__tests__/index-test.ts: -------------------------------------------------------------------------------- 1 | import { ShortcutClient } from '../index'; 2 | 3 | describe('index', () => { 4 | it('exposes ShortcutClient', () => { 5 | expect(ShortcutClient).toBeDefined(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": true, 4 | "trailingComma": "all", 5 | "arrowParens": "always", 6 | "overrides": [ 7 | { 8 | "files": "*.ts", 9 | "options": { 10 | "parser": "typescript" 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/listCustomFields.ts: -------------------------------------------------------------------------------- 1 | import { ShortcutClient } from '../src'; 2 | 3 | const shortcut = new ShortcutClient(process.env.SHORTCUT_API_TOKEN); // See https://github.com/useshortcut/shortcut-client-js#how-to-get-an-api-token 4 | 5 | shortcut.listCustomFields().then((response) => console.log(response?.data)); 6 | -------------------------------------------------------------------------------- /examples/getCurrentMemberInfo.ts: -------------------------------------------------------------------------------- 1 | import { ShortcutClient } from '../src'; 2 | 3 | const shortcut = new ShortcutClient(process.env.SHORTCUT_API_TOKEN); // See https://github.com/useshortcut/shortcut-client-js#how-to-get-an-api-token 4 | 5 | shortcut.getCurrentMemberInfo().then((response) => console.log(response?.data)); 6 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This folder contains ready-to-use examples. 4 | 5 | ## Usage 6 | 7 | You will need to set an environment variable with your API Token. See [How to Get an API Token](../README.md#how-to-get-an-api-token). 8 | 9 | Then, you can run the file you want with: 10 | 11 | ```bash 12 | SHORTCUT_API_TOKEN=YOUR_API_TOKEN npx ts-node FILE_EXAMPLE 13 | ``` -------------------------------------------------------------------------------- /src/ShortcutClient.ts: -------------------------------------------------------------------------------- 1 | import { Api } from './generated/Api'; 2 | import type { ApiConfig } from './generated/http-client'; 3 | 4 | export class ShortcutClient< 5 | SecurityDataType = unknown, 6 | > extends Api { 7 | constructor(apiToken: string, config: ApiConfig = {}) { 8 | if (apiToken == null || typeof apiToken !== 'string') { 9 | // eslint-disable-next-line no-console 10 | console.error('You need to supply an API Token.'); 11 | } 12 | 13 | super({ 14 | headers: { 'Shortcut-Token': apiToken, ...config.headers }, 15 | ...config, 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsdown'; 2 | 3 | export default defineConfig({ 4 | // Find all TypeScript files (excluding tests and type definitions) 5 | entry: 'src/index.ts', 6 | outDir: 'lib', 7 | format: ['esm', 'cjs'], 8 | dts: true, 9 | clean: true, 10 | unbundle: true, 11 | exports: { 12 | // I'm not sure why, but the package.json file is being included in the exports. 13 | // We don't want that, so we remove it. 14 | customExports(pkg) { 15 | // eslint-disable-next-line no-param-reassign 16 | delete pkg['./package.json']; 17 | return pkg; 18 | }, 19 | }, 20 | outputOptions: { 21 | exports: 'named', 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /src/__tests__/ShortcutApi-unmock-test.ts: -------------------------------------------------------------------------------- 1 | import { ShortcutClient } from '../ShortcutClient'; 2 | 3 | jest.unmock('axios'); 4 | 5 | describe('ShortcutClient', () => { 6 | const token = 'SOME-TOKEN'; 7 | 8 | it('uses the expected baseURL', () => { 9 | const shortcut = new ShortcutClient(token); 10 | 11 | expect(shortcut.instance.defaults.baseURL).toBe( 12 | 'https://api.app.shortcut.com', 13 | ); 14 | }); 15 | 16 | it('adds Shortcut-Token to default headers', async () => { 17 | const shortcut = new ShortcutClient(token); 18 | 19 | expect(shortcut.instance.defaults.headers).toHaveProperty( 20 | 'Shortcut-Token', 21 | token, 22 | ); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: "GitHub Pages" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: blacksmith-4vcpu-ubuntu-2404 11 | permissions: 12 | contents: write # Required for deploying pages 13 | pages: write # Required for deploying pages 14 | steps: 15 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 16 | 17 | - name: Setup Node 18 | uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 19 | with: 20 | node-version: 'lts/*' 21 | cache: 'yarn' 22 | 23 | - run: yarn install 24 | - run: yarn build:client 25 | - run: yarn build:docs 26 | 27 | - name: Deploy 28 | uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 29 | with: 30 | github_token: ${{ secrets.GITHUB_TOKEN }} 31 | publish_dir: ./docs 32 | -------------------------------------------------------------------------------- /scripts/add-typedoc-comments.ts: -------------------------------------------------------------------------------- 1 | import { API, FileInfo } from 'jscodeshift'; 2 | 3 | export default function transformer(file: FileInfo, api: API) { 4 | const j = api.jscodeshift; 5 | const root = j(file.source); 6 | 7 | return root 8 | .find(j.ClassDeclaration) 9 | .filter( 10 | (path) => 11 | path.value.id?.type === 'Identifier' && 12 | ['Api', 'HttpClient'].includes(path.value.id.name), 13 | ) 14 | .forEach((path) => { 15 | const target = 16 | path.parent.value.type === 'ExportNamedDeclaration' 17 | ? path.parent 18 | : path; 19 | 20 | const desc = 21 | path.value.id?.name === 'Api' 22 | ? "\n * Please don't use this class directly, instead use the `ShortcutClient` class we provided which is extending this class to add headers for authorization." 23 | : '\n'; 24 | 25 | target.insertBefore(`/** ${desc} * @internal\n * @private\n */`); 26 | }) 27 | .toSource(); 28 | } 29 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "airbnb-base", 5 | "plugin:@typescript-eslint/recommended", 6 | "prettier", 7 | "plugin:prettier/recommended" 8 | ], 9 | "parserOptions": { 10 | "sourceType": "module" 11 | }, 12 | "settings": { 13 | "import/extensions": [ 14 | ".js", 15 | ".ts" 16 | ], 17 | "import/parsers": { 18 | "@typescript-eslint/parser": [ 19 | ".ts" 20 | ] 21 | }, 22 | "import/resolver": { 23 | "node": { 24 | "extensions": [ 25 | ".js", 26 | ".ts" 27 | ] 28 | } 29 | } 30 | }, 31 | "plugins": [ 32 | "import", 33 | "jest", 34 | "prettier" 35 | ], 36 | "env": { 37 | "jest": true, 38 | "es6": true 39 | }, 40 | "rules": { 41 | "no-undef": 0, 42 | "import/extensions": 0, 43 | "import/prefer-default-export": 0, 44 | "@typescript-eslint/camelcase": 0, 45 | "@typescript-eslint/no-explicit-any": 0, 46 | "no-restricted-exports": 0 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npmjs 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | id-token: write # Required for OIDC 13 | steps: 14 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 15 | - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 16 | with: 17 | node-version: 24 18 | cache: 'yarn' 19 | registry-url: 'https://registry.npmjs.org' 20 | # Ensure npm 11.5.1 or later is installed 21 | - name: Update npm 22 | run: npm install -g npm@latest 23 | - name: Install dependencies 24 | run: yarn --frozen-lockfile 25 | - run: npm publish --access public 26 | - name: Rename package to @useshortcut/client 27 | run: | 28 | sed -i 's/"name": ".*"/"name": "@useshortcut\/client"/' package.json 29 | - name: Publish under @useshortcut scope 30 | run: npm publish --access public 31 | -------------------------------------------------------------------------------- /examples/uploadFileToStory.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as streamToBlob from 'stream-to-blob'; 3 | 4 | import { ShortcutClient } from '../src'; 5 | 6 | (async () => { 7 | const shortcut = new ShortcutClient(process.env.SHORTCUT_API_TOKEN); // See https://github.com/useshortcut/shortcut-client-js#how-to-get-an-api-token 8 | 9 | const FILE_PATH = `${__dirname}/logo.png`; 10 | 11 | const { data: workflows } = await shortcut.listWorkflows(); 12 | 13 | const { data: story } = await shortcut.createStory({ 14 | name: 'Upload a file to a story', 15 | workflow_state_id: workflows[0].states[0].id, 16 | }); 17 | 18 | console.log('Story created with ID:', story.id); 19 | 20 | // This is proper to Node, replace this based on your environment 21 | const fileStream = fs.createReadStream(FILE_PATH); 22 | 23 | const { data: file } = await shortcut.uploadFiles({ 24 | story_id: story.id, 25 | file0: (await streamToBlob(fileStream)) as any, // On Web, this is expecting a File object, but on Node, it's a ReadableStream 26 | }); 27 | 28 | console.log(file); 29 | })(); 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Shortcut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/api.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | const { utils, route, config, modelTypes } = it; 3 | const { _, pascalCase, require } = utils; 4 | const apiClassName = pascalCase(route.moduleName); 5 | const routes = route.routes; 6 | const dataContracts = _.map(modelTypes, "name"); 7 | %> 8 | 9 | <% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import type { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %> 10 | 11 | import { HttpClient, type RequestParams, ContentType, HttpResponse } from "./<%~ config.fileNames.httpClient %>"; 12 | <% if (dataContracts.length) { %> 13 | import type { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>" 14 | <% } %> 15 | 16 | export class <%= apiClassName %><% if (!config.singleHttpClient) { %> extends HttpClient <% } %> { 17 | <% if(config.singleHttpClient) { %> 18 | http: HttpClient; 19 | 20 | constructor (http: HttpClient) { 21 | this.http = http; 22 | } 23 | <% } %> 24 | 25 | <% for (const route of routes) { %> 26 | <%~ includeFile('./procedure-call.ejs', { ...it, route }) %> 27 | <% } %> 28 | } 29 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | ci: 11 | runs-on: blacksmith-4vcpu-ubuntu-2404 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | include: 16 | - name: lint 17 | command: yarn lint 18 | - name: validate-schema 19 | command: yarn validate:schema 20 | - name: test 21 | command: yarn test 22 | - name: format-check 23 | command: yarn format:check 24 | - name: validate-examples 25 | command: yarn validate:examples 26 | - name: build 27 | command: yarn build && yarn check-exports 28 | name: ${{ matrix.name }} 29 | steps: 30 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 31 | - name: Use Node.js 32 | uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 33 | with: 34 | node-version: 24 35 | cache: 'yarn' 36 | - name: Install dependencies 37 | run: yarn install --frozen-lockfile 38 | - name: ${{ matrix.name }} 39 | run: ${{ matrix.command }} 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@shortcut/client", 3 | "version": "3.0.0", 4 | "description": "A library for interacting with the Shortcut REST API", 5 | "homepage": "https://github.com/useshortcut/shortcut-client-js", 6 | "bugs": { 7 | "url": "https://github.com/useshortcut/shortcut-client-js/issues" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/useshortcut/shortcut-client-js.git" 12 | }, 13 | "license": "MIT", 14 | "sideEffects": false, 15 | "type": "commonjs", 16 | "exports": { 17 | ".": { 18 | "import": "./lib/index.mjs", 19 | "require": "./lib/index.js" 20 | } 21 | }, 22 | "main": "./lib/index.js", 23 | "module": "./lib/index.mjs", 24 | "types": "./lib/index.d.ts", 25 | "files": [ 26 | "lib" 27 | ], 28 | "scripts": { 29 | "build": "yarn build:client && yarn build:add-typedoc-comments && NODE_OPTIONS=\"--no-experimental-strip-types\" tsdown", 30 | "build:add-typedoc-comments": "npx jscodeshift -t scripts/add-typedoc-comments.ts --extensions=ts --parser=ts src/generated/**", 31 | "build:client": "swagger-typescript-api generate --path ./schema/shortcut.swagger.json --output ./src/generated --clean-output --axios --modular --templates ./templates", 32 | "build:docs": "typedoc ./src --exclude 'src/__tests__/**'", 33 | "check-exports": "attw --pack .", 34 | "format": "prettier --write -l *.{json,md,prettierrc} '{src,scripts}/**/*.ts'", 35 | "format:check": "prettier --check *.{json,md,prettierrc} '{src,scripts}/**/*.ts'", 36 | "lint": "eslint 'src/**/*.{js,ts}'", 37 | "prepublishOnly": "yarn build", 38 | "sync:schema": "curl --silent https://developer.shortcut.com/api/rest/v3/shortcut.swagger.json --output ./schema/shortcut.swagger.json && yarn validate:schema", 39 | "test": "jest", 40 | "validate:examples": "npx tsc examples/*.ts --noEmit", 41 | "validate:schema": "swagger-cli validate ./schema/shortcut.swagger.json" 42 | }, 43 | "jest": { 44 | "preset": "ts-jest", 45 | "testEnvironment": "node", 46 | "testPathIgnorePatterns": [ 47 | "/lib/", 48 | "/node_modules/" 49 | ] 50 | }, 51 | "dependencies": { 52 | "axios": "^1.9.0" 53 | }, 54 | "devDependencies": { 55 | "@arethetypeswrong/cli": "^0.18.1", 56 | "@total-typescript/tsconfig": "^1.0.4", 57 | "@types/glob": "^8.1.0", 58 | "@types/jest": "^29.5.14", 59 | "@types/jscodeshift": "17.3.0", 60 | "@types/node": "^22.15.30", 61 | "@typescript-eslint/eslint-plugin": "^8.33.1", 62 | "@typescript-eslint/parser": "^8.33.1", 63 | "eslint": "^8.57.1", 64 | "eslint-config-airbnb-base": "^15.0.0", 65 | "eslint-config-prettier": "^10.1.5", 66 | "eslint-plugin-import": "^2.31.0", 67 | "eslint-plugin-jest": "^28.12.0", 68 | "eslint-plugin-prettier": "^5.4.1", 69 | "glob": "^11.0.2", 70 | "jest": "^29.7.0", 71 | "jscodeshift": "^17.3.0", 72 | "prettier": "^3.5.3", 73 | "stream-to-blob": "^2.0.1", 74 | "swagger-cli": "^4.0.4", 75 | "swagger-typescript-api": "^13.2.0", 76 | "ts-jest": "^29.3.4", 77 | "tsdown": "^0.12.7", 78 | "typedoc": "0.28.5", 79 | "typedoc-plugin-merge-modules": "7.0.0", 80 | "typescript": "^5.8.3" 81 | }, 82 | "readme": "https://github.com/useshortcut/shortcut-client-js#readme" 83 | } 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @shortcut/client 2 | 3 | Shortcut's logo 4 | 5 | [![Version](https://badge.fury.io/js/@shortcut%2Fclient.svg)](https://badge.fury.io/js/@shortcut%2Fclient) 6 | [![Monthly Downloads](https://img.shields.io/npm/dm/@shortcut%2Fclient)](https://www.npmjs.org/package/@shortcut%2Fclient) 7 | [![GitHub License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/useshortcut/shortcut-client-js/blob/main/LICENSE) 8 | [![PRs welcome!](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)]() 9 | [![X](https://img.shields.io/twitter/follow/shortcut.svg?label=Follow%20@shortcut)](https://twitter.com/intent/follow?screen_name=shortcut) 10 | 11 | A library for interacting with the Shortcut REST API. 12 | 13 |
14 | 15 | ## Getting Started 16 | 17 | ### Installation 18 | 19 | ```shell 20 | npm install @shortcut/client 21 | ``` 22 | 23 | > [!IMPORTANT] 24 | > Our legacy npm organization namespace is `@useshortcut`. 25 | > 26 | > While it will still contain copies of all future released package versions, we **strongly** recommend switching to our primary `@shortcut` organization namespace. 27 | 28 | ### How to Get an API Token 29 | 30 | The Shortcut API uses token-based authentication, you will need one to use this library. 31 | 32 | To generate an API token, go to https://app.shortcut.com/settings/account/api-tokens. 33 | 34 | To make it easier to explore our API, we recommend saving this token as an environment variable in your local dev environment: 35 | 36 | ```bash 37 | export SHORTCUT_API_TOKEN="YOUR API TOKEN HERE" 38 | ``` 39 | 40 | This will allow you to copy and paste many examples in the documentation to try them out. 41 | 42 | > [!NOTE] 43 | > Requests made with a missing or invalid token will get a `401 Unauthorized` response. 44 | 45 | > [!NOTE] 46 | > All requests must be made over HTTPS. 47 | 48 | > [!CAUTION] 49 | > Tokens provide complete access to your Shortcut account, **so keep them secure**. 50 | > 51 | > Don’t paste them into your source code, use an environment variable instead. 52 | > 53 | > For security reasons, we will immediately invalidate any tokens we find have been made public. 54 | 55 | ## Usage 56 | 57 | To see all available exports, take a look at the [API documentation](https://useshortcut.github.io/shortcut-client-js/) or check out the `.d.ts` files in this repository. 58 | 59 | ```javascript 60 | import { ShortcutClient } from '@shortcut/client'; 61 | // const { ShortcutClient } = require('@shortcut/client'); 62 | 63 | const shortcut = new ShortcutClient('YOUR_API_TOKEN'); // See https://github.com/useshortcut/shortcut-client-js#how-to-get-an-api-token 64 | 65 | shortcut.getCurrentMemberInfo().then((response) => console.log(response?.data)); 66 | 67 | shortcut.listProjects().then((response) => console.log(response?.data)); 68 | ``` 69 | 70 | ## Play with It 71 | 72 | You can play with it in your web browser with this live playground: 73 | 74 | - [CodeSandbox](https://codesandbox.io/s/useshortcut-client-playground-48kq1) 75 | 76 | ## Documentation 77 | 78 | [Documentation for this client](https://useshortcut.github.io/shortcut-client-js/). 79 | 80 | [Documentation for the REST API](https://developer.shortcut.com/api/rest/v3). 81 | 82 | ## Publishing & Deployment 83 | 84 | This library uses GitHub Actions for CI/CD. The deployment process is fully automated. 85 | 86 | ### Release Process 87 | 88 | To publish a new version: 89 | 90 | 1. Update the version in `package.json` 91 | 2. Commit and push to `main` 92 | 3. Create a GitHub Release with a version tag (e.g., `v2.4.0`) 93 | 4. The publish workflow will automatically build and publish to npm 94 | 95 | ### Publishing to npm 96 | 97 | Publishing is triggered automatically when a **GitHub Release is created**: 98 | 99 | 1. **Create a GitHub Release**: Go to the repository's Releases page and create a new release with a version tag (e.g., `v2.4.0`) 100 | 2. The `publish.yml` workflow will: 101 | - Build the package (`yarn build` via `prepublishOnly`) 102 | - Publish to npm under `@shortcut/client` 103 | - Also publish under the legacy `@useshortcut/client` namespace for backwards compatibility 104 | 105 | ### Documentation Deployment 106 | 107 | API documentation is automatically deployed to GitHub Pages on every push to `main`: 108 | 109 | 1. The `gh-pages.yml` workflow builds the documentation using TypeDoc 110 | 2. Documentation is published to https://useshortcut.github.io/shortcut-client-js/ 111 | -------------------------------------------------------------------------------- /templates/http-client.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | const { apiConfig, generateResponses, config } = it; 3 | %> 4 | 5 | import type { AxiosInstance, AxiosRequestConfig, HeadersDefaults, ResponseType, AxiosResponse } from "axios"; 6 | import axios from "axios"; 7 | 8 | export type QueryParamsType = Record; 9 | 10 | export interface FullRequestParams extends Omit { 11 | /** set parameter to `true` for call `securityWorker` for this request */ 12 | secure?: boolean; 13 | /** request path */ 14 | path: string; 15 | /** content type of request body */ 16 | type?: ContentType; 17 | /** query params */ 18 | query?: QueryParamsType; 19 | /** format of response (i.e. response.json() -> format: "json") */ 20 | format?: ResponseType; 21 | /** request body */ 22 | body?: unknown; 23 | } 24 | 25 | export type RequestParams = Omit; 26 | 27 | export interface ApiConfig extends Omit { 28 | securityWorker?: (securityData: SecurityDataType | null) => Promise | AxiosRequestConfig | void; 29 | secure?: boolean; 30 | format?: ResponseType; 31 | } 32 | 33 | export enum ContentType { 34 | Json = "application/json", 35 | FormData = "multipart/form-data", 36 | UrlEncoded = "application/x-www-form-urlencoded", 37 | Text = "text/plain", 38 | } 39 | 40 | export class HttpClient { 41 | public instance: AxiosInstance; 42 | private securityData: SecurityDataType | null = null; 43 | private securityWorker?: ApiConfig["securityWorker"]; 44 | private secure?: boolean; 45 | private format?: ResponseType; 46 | 47 | constructor({ securityWorker, secure, format, ...axiosConfig }: ApiConfig = {}) { 48 | this.instance = axios.create({ ...axiosConfig, baseURL: axiosConfig.baseURL || "<%~ apiConfig.baseUrl %>" }) 49 | this.secure = secure; 50 | this.format = format; 51 | this.securityWorker = securityWorker; 52 | } 53 | 54 | public setSecurityData = (data: SecurityDataType | null) => { 55 | this.securityData = data 56 | } 57 | 58 | protected mergeRequestParams(params1: AxiosRequestConfig, params2?: AxiosRequestConfig): AxiosRequestConfig { 59 | const method = params1.method || (params2 && params2.method) 60 | 61 | return { 62 | ...this.instance.defaults, 63 | ...params1, 64 | ...(params2 || {}), 65 | headers: { 66 | ...((method && this.instance.defaults.headers[method.toLowerCase() as keyof HeadersDefaults]) || {}), 67 | ...(params1.headers || {}), 68 | ...((params2 && params2.headers) || {}), 69 | }, 70 | }; 71 | } 72 | 73 | protected stringifyFormItem(formItem: unknown) { 74 | if (typeof formItem === "object" && formItem !== null) { 75 | return JSON.stringify(formItem); 76 | } else { 77 | return `${formItem}`; 78 | } 79 | } 80 | 81 | protected createFormData(input: Record): FormData { 82 | return Object.keys(input || {}).reduce((formData, key) => { 83 | const property = input[key]; 84 | const propertyContent: any[] = (property instanceof Array) ? property : [property] 85 | 86 | for (const formItem of propertyContent) { 87 | const isFileType = formItem instanceof Blob; 88 | formData.append( 89 | key, 90 | isFileType ? formItem : this.stringifyFormItem(formItem) 91 | ); 92 | } 93 | 94 | return formData; 95 | }, new FormData()); 96 | } 97 | 98 | public request = async ({ 99 | secure, 100 | path, 101 | type, 102 | query, 103 | format, 104 | body, 105 | ...params 106 | <% if (config.unwrapResponseData) { %> 107 | }: FullRequestParams): Promise => { 108 | <% } else { %> 109 | }: FullRequestParams): Promise> => { 110 | <% } %> 111 | const secureParams = ((typeof secure === 'boolean' ? secure : this.secure) && this.securityWorker && (await this.securityWorker(this.securityData))) || {}; 112 | const requestParams = this.mergeRequestParams(params, secureParams); 113 | const responseFormat = (format || this.format) || undefined; 114 | 115 | if (type === ContentType.FormData && body && body !== null && typeof body === "object") { 116 | body = this.createFormData(body as Record); 117 | } 118 | 119 | if (type === ContentType.Text && body && body !== null && typeof body !== "string") { 120 | body = JSON.stringify(body); 121 | } 122 | 123 | return this.instance.request({ 124 | ...requestParams, 125 | headers: { 126 | ...(requestParams.headers || {}), 127 | ...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}), 128 | }, 129 | params: query, 130 | responseType: responseFormat, 131 | data: body, 132 | url: path, 133 | <% if (config.unwrapResponseData) { %> 134 | }).then(response => response.data); 135 | <% } else { %> 136 | }); 137 | <% } %> 138 | }; 139 | } 140 | -------------------------------------------------------------------------------- /src/generated/http-client.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* tslint:disable */ 3 | // @ts-nocheck 4 | /* 5 | * --------------------------------------------------------------- 6 | * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ## 7 | * ## ## 8 | * ## AUTHOR: acacode ## 9 | * ## SOURCE: https://github.com/acacode/swagger-typescript-api ## 10 | * --------------------------------------------------------------- 11 | */ 12 | 13 | import type { 14 | AxiosInstance, 15 | AxiosRequestConfig, 16 | AxiosResponse, 17 | HeadersDefaults, 18 | ResponseType, 19 | } from "axios"; 20 | import axios from "axios"; 21 | 22 | export type QueryParamsType = Record; 23 | 24 | export interface FullRequestParams 25 | extends Omit { 26 | /** set parameter to `true` for call `securityWorker` for this request */ 27 | secure?: boolean; 28 | /** request path */ 29 | path: string; 30 | /** content type of request body */ 31 | type?: ContentType; 32 | /** query params */ 33 | query?: QueryParamsType; 34 | /** format of response (i.e. response.json() -> format: "json") */ 35 | format?: ResponseType; 36 | /** request body */ 37 | body?: unknown; 38 | } 39 | 40 | export type RequestParams = Omit< 41 | FullRequestParams, 42 | "body" | "method" | "query" | "path" 43 | >; 44 | 45 | export interface ApiConfig 46 | extends Omit { 47 | securityWorker?: ( 48 | securityData: SecurityDataType | null, 49 | ) => Promise | AxiosRequestConfig | void; 50 | secure?: boolean; 51 | format?: ResponseType; 52 | } 53 | 54 | export enum ContentType { 55 | Json = "application/json", 56 | FormData = "multipart/form-data", 57 | UrlEncoded = "application/x-www-form-urlencoded", 58 | Text = "text/plain", 59 | } 60 | 61 | /** 62 | * @internal 63 | * @private 64 | */ 65 | 66 | export class HttpClient { 67 | public instance: AxiosInstance; 68 | private securityData: SecurityDataType | null = null; 69 | private securityWorker?: ApiConfig["securityWorker"]; 70 | private secure?: boolean; 71 | private format?: ResponseType; 72 | 73 | constructor({ 74 | securityWorker, 75 | secure, 76 | format, 77 | ...axiosConfig 78 | }: ApiConfig = {}) { 79 | this.instance = axios.create({ 80 | ...axiosConfig, 81 | baseURL: axiosConfig.baseURL || "https://api.app.shortcut.com", 82 | }); 83 | this.secure = secure; 84 | this.format = format; 85 | this.securityWorker = securityWorker; 86 | } 87 | 88 | public setSecurityData = (data: SecurityDataType | null) => { 89 | this.securityData = data; 90 | }; 91 | 92 | protected mergeRequestParams( 93 | params1: AxiosRequestConfig, 94 | params2?: AxiosRequestConfig, 95 | ): AxiosRequestConfig { 96 | const method = params1.method || (params2 && params2.method); 97 | 98 | return { 99 | ...this.instance.defaults, 100 | ...params1, 101 | ...(params2 || {}), 102 | headers: { 103 | ...((method && 104 | this.instance.defaults.headers[ 105 | method.toLowerCase() as keyof HeadersDefaults 106 | ]) || 107 | {}), 108 | ...(params1.headers || {}), 109 | ...((params2 && params2.headers) || {}), 110 | }, 111 | }; 112 | } 113 | 114 | protected stringifyFormItem(formItem: unknown) { 115 | if (typeof formItem === "object" && formItem !== null) { 116 | return JSON.stringify(formItem); 117 | } else { 118 | return `${formItem}`; 119 | } 120 | } 121 | 122 | protected createFormData(input: Record): FormData { 123 | return Object.keys(input || {}).reduce((formData, key) => { 124 | const property = input[key]; 125 | const propertyContent: any[] = 126 | property instanceof Array ? property : [property]; 127 | 128 | for (const formItem of propertyContent) { 129 | const isFileType = formItem instanceof Blob; 130 | formData.append( 131 | key, 132 | isFileType ? formItem : this.stringifyFormItem(formItem), 133 | ); 134 | } 135 | 136 | return formData; 137 | }, new FormData()); 138 | } 139 | 140 | public request = async ({ 141 | secure, 142 | path, 143 | type, 144 | query, 145 | format, 146 | body, 147 | ...params 148 | }: FullRequestParams): Promise> => { 149 | const secureParams = 150 | ((typeof secure === "boolean" ? secure : this.secure) && 151 | this.securityWorker && 152 | (await this.securityWorker(this.securityData))) || 153 | {}; 154 | const requestParams = this.mergeRequestParams(params, secureParams); 155 | const responseFormat = format || this.format || undefined; 156 | 157 | if ( 158 | type === ContentType.FormData && 159 | body && 160 | body !== null && 161 | typeof body === "object" 162 | ) { 163 | body = this.createFormData(body as Record); 164 | } 165 | 166 | if ( 167 | type === ContentType.Text && 168 | body && 169 | body !== null && 170 | typeof body !== "string" 171 | ) { 172 | body = JSON.stringify(body); 173 | } 174 | 175 | return this.instance.request({ 176 | ...requestParams, 177 | headers: { 178 | ...(requestParams.headers || {}), 179 | ...(type && type !== ContentType.FormData 180 | ? { "Content-Type": type } 181 | : {}), 182 | }, 183 | params: query, 184 | responseType: responseFormat, 185 | data: body, 186 | url: path, 187 | }); 188 | }; 189 | } 190 | -------------------------------------------------------------------------------- /src/generated/Api.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* tslint:disable */ 3 | // @ts-nocheck 4 | /* 5 | * --------------------------------------------------------------- 6 | * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ## 7 | * ## ## 8 | * ## AUTHOR: acacode ## 9 | * ## SOURCE: https://github.com/acacode/swagger-typescript-api ## 10 | * --------------------------------------------------------------- 11 | */ 12 | 13 | import type { 14 | Category, 15 | CreateCategory, 16 | CreateCommentComment, 17 | CreateDoc, 18 | CreateEntityTemplate, 19 | CreateEpic, 20 | CreateEpicComment, 21 | CreateEpicHealth, 22 | CreateGenericIntegration, 23 | CreateGroup, 24 | CreateIteration, 25 | CreateLabelParams, 26 | CreateLinkedFile, 27 | CreateMilestone, 28 | CreateObjective, 29 | CreateOrDeleteStoryReaction, 30 | CreateProject, 31 | CreateStories, 32 | CreateStoryComment, 33 | CreateStoryFromTemplateParams, 34 | CreateStoryLink, 35 | CreateStoryParams, 36 | CreateTask, 37 | CustomField, 38 | DataConflictError, 39 | DeleteStories, 40 | DisabledFeatureError, 41 | DocSlim, 42 | EntityTemplate, 43 | Epic, 44 | EpicPaginatedResults, 45 | EpicSearchResults, 46 | EpicSlim, 47 | EpicWorkflow, 48 | Group, 49 | Health, 50 | History, 51 | Iteration, 52 | IterationSearchResults, 53 | IterationSlim, 54 | KeyResult, 55 | Label, 56 | LinkedFile, 57 | MaxSearchResultsExceededError, 58 | Member, 59 | MemberInfo, 60 | Milestone, 61 | Objective, 62 | ObjectiveSearchResults, 63 | Project, 64 | Repository, 65 | SearchResults, 66 | SearchStories, 67 | Story, 68 | StoryComment, 69 | StoryLink, 70 | StoryReaction, 71 | StorySearchResults, 72 | StorySlim, 73 | Task, 74 | ThreadedComment, 75 | UnusableEntitlementError, 76 | UpdateCategory, 77 | UpdateComment, 78 | UpdateCustomField, 79 | UpdateEntityTemplate, 80 | UpdateEpic, 81 | UpdateFile, 82 | UpdateGroup, 83 | UpdateHealth, 84 | UpdateIteration, 85 | UpdateKeyResult, 86 | UpdateLabel, 87 | UpdateLinkedFile, 88 | UpdateMilestone, 89 | UpdateObjective, 90 | UpdateProject, 91 | UpdateStories, 92 | UpdateStory, 93 | UpdateStoryComment, 94 | UpdateStoryLink, 95 | UpdateTask, 96 | UploadedFile, 97 | Workflow, 98 | } from "./data-contracts"; 99 | import { ContentType, HttpClient, type RequestParams } from "./http-client"; 100 | 101 | /** 102 | * Please don't use this class directly, instead use the `ShortcutClient` class we provided which is extending this class to add headers for authorization. * @internal 103 | * @private 104 | */ 105 | 106 | export class Api< 107 | SecurityDataType = unknown, 108 | > extends HttpClient { 109 | /** 110 | * @description List Categories returns a list of all Categories and their attributes. 111 | * 112 | * @name ListCategories 113 | * @summary List Categories 114 | * @request GET:/api/v3/categories 115 | * @secure 116 | */ 117 | listCategories = (params: RequestParams = {}) => 118 | this.request({ 119 | path: `/api/v3/categories`, 120 | method: "GET", 121 | secure: true, 122 | format: "json", 123 | ...params, 124 | }); 125 | /** 126 | * @description Create Category allows you to create a new Category in Shortcut. 127 | * 128 | * @name CreateCategory 129 | * @summary Create Category 130 | * @request POST:/api/v3/categories 131 | * @secure 132 | */ 133 | createCategory = ( 134 | CreateCategory: CreateCategory, 135 | params: RequestParams = {}, 136 | ) => 137 | this.request({ 138 | path: `/api/v3/categories`, 139 | method: "POST", 140 | body: CreateCategory, 141 | secure: true, 142 | type: ContentType.Json, 143 | format: "json", 144 | ...params, 145 | }); 146 | /** 147 | * @description Get Category returns information about the selected Category. 148 | * 149 | * @name GetCategory 150 | * @summary Get Category 151 | * @request GET:/api/v3/categories/{category-public-id} 152 | * @secure 153 | */ 154 | getCategory = (categoryPublicId: number, params: RequestParams = {}) => 155 | this.request({ 156 | path: `/api/v3/categories/${categoryPublicId}`, 157 | method: "GET", 158 | secure: true, 159 | format: "json", 160 | ...params, 161 | }); 162 | /** 163 | * @description Update Category allows you to replace a Category name with another name. If you try to name a Category something that already exists, you will receive a 422 response. 164 | * 165 | * @name UpdateCategory 166 | * @summary Update Category 167 | * @request PUT:/api/v3/categories/{category-public-id} 168 | * @secure 169 | */ 170 | updateCategory = ( 171 | categoryPublicId: number, 172 | UpdateCategory: UpdateCategory, 173 | params: RequestParams = {}, 174 | ) => 175 | this.request({ 176 | path: `/api/v3/categories/${categoryPublicId}`, 177 | method: "PUT", 178 | body: UpdateCategory, 179 | secure: true, 180 | type: ContentType.Json, 181 | format: "json", 182 | ...params, 183 | }); 184 | /** 185 | * @description Delete Category can be used to delete any Category. 186 | * 187 | * @name DeleteCategory 188 | * @summary Delete Category 189 | * @request DELETE:/api/v3/categories/{category-public-id} 190 | * @secure 191 | */ 192 | deleteCategory = (categoryPublicId: number, params: RequestParams = {}) => 193 | this.request({ 194 | path: `/api/v3/categories/${categoryPublicId}`, 195 | method: "DELETE", 196 | secure: true, 197 | ...params, 198 | }); 199 | /** 200 | * @description List Category Milestones returns a list of all Milestones with the Category. 201 | * 202 | * @name ListCategoryMilestones 203 | * @summary List Category Milestones 204 | * @request GET:/api/v3/categories/{category-public-id}/milestones 205 | * @secure 206 | */ 207 | listCategoryMilestones = ( 208 | categoryPublicId: number, 209 | params: RequestParams = {}, 210 | ) => 211 | this.request({ 212 | path: `/api/v3/categories/${categoryPublicId}/milestones`, 213 | method: "GET", 214 | secure: true, 215 | format: "json", 216 | ...params, 217 | }); 218 | /** 219 | * @description Returns a list of all Objectives with the Category. 220 | * 221 | * @name ListCategoryObjectives 222 | * @summary List Category Objectives 223 | * @request GET:/api/v3/categories/{category-public-id}/objectives 224 | * @secure 225 | */ 226 | listCategoryObjectives = ( 227 | categoryPublicId: number, 228 | params: RequestParams = {}, 229 | ) => 230 | this.request({ 231 | path: `/api/v3/categories/${categoryPublicId}/objectives`, 232 | method: "GET", 233 | secure: true, 234 | format: "json", 235 | ...params, 236 | }); 237 | /** 238 | * No description 239 | * 240 | * @name ListCustomFields 241 | * @summary List Custom Fields 242 | * @request GET:/api/v3/custom-fields 243 | * @secure 244 | */ 245 | listCustomFields = (params: RequestParams = {}) => 246 | this.request({ 247 | path: `/api/v3/custom-fields`, 248 | method: "GET", 249 | secure: true, 250 | format: "json", 251 | ...params, 252 | }); 253 | /** 254 | * No description 255 | * 256 | * @name GetCustomField 257 | * @summary Get Custom Field 258 | * @request GET:/api/v3/custom-fields/{custom-field-public-id} 259 | * @secure 260 | */ 261 | getCustomField = (customFieldPublicId: string, params: RequestParams = {}) => 262 | this.request({ 263 | path: `/api/v3/custom-fields/${customFieldPublicId}`, 264 | method: "GET", 265 | secure: true, 266 | format: "json", 267 | ...params, 268 | }); 269 | /** 270 | * @description Update Custom Field can be used to update the definition of a Custom Field. The order of items in the 'values' collection is interpreted to be their ascending sort order.To delete an existing enum value, simply omit it from the 'values' collection. New enum values may be created inline by including an object in the 'values' collection having a 'value' entry with no 'id' (eg. {'value': 'myNewValue', 'color_key': 'green'}). 271 | * 272 | * @name UpdateCustomField 273 | * @summary Update Custom Field 274 | * @request PUT:/api/v3/custom-fields/{custom-field-public-id} 275 | * @secure 276 | */ 277 | updateCustomField = ( 278 | customFieldPublicId: string, 279 | UpdateCustomField: UpdateCustomField, 280 | params: RequestParams = {}, 281 | ) => 282 | this.request({ 283 | path: `/api/v3/custom-fields/${customFieldPublicId}`, 284 | method: "PUT", 285 | body: UpdateCustomField, 286 | secure: true, 287 | type: ContentType.Json, 288 | format: "json", 289 | ...params, 290 | }); 291 | /** 292 | * No description 293 | * 294 | * @name DeleteCustomField 295 | * @summary Delete Custom Field 296 | * @request DELETE:/api/v3/custom-fields/{custom-field-public-id} 297 | * @secure 298 | */ 299 | deleteCustomField = ( 300 | customFieldPublicId: string, 301 | params: RequestParams = {}, 302 | ) => 303 | this.request({ 304 | path: `/api/v3/custom-fields/${customFieldPublicId}`, 305 | method: "DELETE", 306 | secure: true, 307 | ...params, 308 | }); 309 | /** 310 | * @description List Docs returns a list of Doc that the current user can read. 311 | * 312 | * @name ListDocs 313 | * @summary List Docs 314 | * @request GET:/api/v3/documents 315 | * @secure 316 | */ 317 | listDocs = (params: RequestParams = {}) => 318 | this.request({ 319 | path: `/api/v3/documents`, 320 | method: "GET", 321 | secure: true, 322 | format: "json", 323 | ...params, 324 | }); 325 | /** 326 | * @description Creates a new Doc. Supports markdown or HTML input via content_format parameter. 327 | * 328 | * @name CreateDoc 329 | * @summary Create Doc 330 | * @request POST:/api/v3/documents 331 | * @secure 332 | */ 333 | createDoc = (CreateDoc: CreateDoc, params: RequestParams = {}) => 334 | this.request({ 335 | path: `/api/v3/documents`, 336 | method: "POST", 337 | body: CreateDoc, 338 | secure: true, 339 | type: ContentType.Json, 340 | format: "json", 341 | ...params, 342 | }); 343 | /** 344 | * @description List all the entity templates for the Workspace. 345 | * 346 | * @name ListEntityTemplates 347 | * @summary List Entity Templates 348 | * @request GET:/api/v3/entity-templates 349 | * @secure 350 | */ 351 | listEntityTemplates = (params: RequestParams = {}) => 352 | this.request({ 353 | path: `/api/v3/entity-templates`, 354 | method: "GET", 355 | secure: true, 356 | format: "json", 357 | ...params, 358 | }); 359 | /** 360 | * @description Create a new entity template for the Workspace. 361 | * 362 | * @name CreateEntityTemplate 363 | * @summary Create Entity Template 364 | * @request POST:/api/v3/entity-templates 365 | * @secure 366 | */ 367 | createEntityTemplate = ( 368 | CreateEntityTemplate: CreateEntityTemplate, 369 | params: RequestParams = {}, 370 | ) => 371 | this.request({ 372 | path: `/api/v3/entity-templates`, 373 | method: "POST", 374 | body: CreateEntityTemplate, 375 | secure: true, 376 | type: ContentType.Json, 377 | format: "json", 378 | ...params, 379 | }); 380 | /** 381 | * @description Disables the Story Template feature for the Workspace. 382 | * 383 | * @name DisableStoryTemplates 384 | * @summary Disable Story Templates 385 | * @request PUT:/api/v3/entity-templates/disable 386 | * @secure 387 | */ 388 | disableStoryTemplates = (params: RequestParams = {}) => 389 | this.request({ 390 | path: `/api/v3/entity-templates/disable`, 391 | method: "PUT", 392 | secure: true, 393 | ...params, 394 | }); 395 | /** 396 | * @description Enables the Story Template feature for the Workspace. 397 | * 398 | * @name EnableStoryTemplates 399 | * @summary Enable Story Templates 400 | * @request PUT:/api/v3/entity-templates/enable 401 | * @secure 402 | */ 403 | enableStoryTemplates = (params: RequestParams = {}) => 404 | this.request({ 405 | path: `/api/v3/entity-templates/enable`, 406 | method: "PUT", 407 | secure: true, 408 | ...params, 409 | }); 410 | /** 411 | * @description Get Entity Template returns information about a given entity template. 412 | * 413 | * @name GetEntityTemplate 414 | * @summary Get Entity Template 415 | * @request GET:/api/v3/entity-templates/{entity-template-public-id} 416 | * @secure 417 | */ 418 | getEntityTemplate = ( 419 | entityTemplatePublicId: string, 420 | params: RequestParams = {}, 421 | ) => 422 | this.request({ 423 | path: `/api/v3/entity-templates/${entityTemplatePublicId}`, 424 | method: "GET", 425 | secure: true, 426 | format: "json", 427 | ...params, 428 | }); 429 | /** 430 | * @description Update an entity template's name or its contents. 431 | * 432 | * @name UpdateEntityTemplate 433 | * @summary Update Entity Template 434 | * @request PUT:/api/v3/entity-templates/{entity-template-public-id} 435 | * @secure 436 | */ 437 | updateEntityTemplate = ( 438 | entityTemplatePublicId: string, 439 | UpdateEntityTemplate: UpdateEntityTemplate, 440 | params: RequestParams = {}, 441 | ) => 442 | this.request({ 443 | path: `/api/v3/entity-templates/${entityTemplatePublicId}`, 444 | method: "PUT", 445 | body: UpdateEntityTemplate, 446 | secure: true, 447 | type: ContentType.Json, 448 | format: "json", 449 | ...params, 450 | }); 451 | /** 452 | * No description 453 | * 454 | * @name DeleteEntityTemplate 455 | * @summary Delete Entity Template 456 | * @request DELETE:/api/v3/entity-templates/{entity-template-public-id} 457 | * @secure 458 | */ 459 | deleteEntityTemplate = ( 460 | entityTemplatePublicId: string, 461 | params: RequestParams = {}, 462 | ) => 463 | this.request({ 464 | path: `/api/v3/entity-templates/${entityTemplatePublicId}`, 465 | method: "DELETE", 466 | secure: true, 467 | ...params, 468 | }); 469 | /** 470 | * @description Returns the Epic Workflow for the Workspace. 471 | * 472 | * @name GetEpicWorkflow 473 | * @summary Get Epic Workflow 474 | * @request GET:/api/v3/epic-workflow 475 | * @secure 476 | */ 477 | getEpicWorkflow = (params: RequestParams = {}) => 478 | this.request({ 479 | path: `/api/v3/epic-workflow`, 480 | method: "GET", 481 | secure: true, 482 | format: "json", 483 | ...params, 484 | }); 485 | /** 486 | * @description List Epics returns a list of all Epics and their attributes. 487 | * 488 | * @name ListEpics 489 | * @summary List Epics 490 | * @request GET:/api/v3/epics 491 | * @secure 492 | */ 493 | listEpics = ( 494 | query?: { 495 | /** A true/false boolean indicating whether to return Epics with their descriptions. */ 496 | includes_description?: boolean; 497 | }, 498 | params: RequestParams = {}, 499 | ) => 500 | this.request({ 501 | path: `/api/v3/epics`, 502 | method: "GET", 503 | query: query, 504 | secure: true, 505 | format: "json", 506 | ...params, 507 | }); 508 | /** 509 | * @description Create Epic allows you to create a new Epic in Shortcut. 510 | * 511 | * @name CreateEpic 512 | * @summary Create Epic 513 | * @request POST:/api/v3/epics 514 | * @secure 515 | */ 516 | createEpic = (CreateEpic: CreateEpic, params: RequestParams = {}) => 517 | this.request({ 518 | path: `/api/v3/epics`, 519 | method: "POST", 520 | body: CreateEpic, 521 | secure: true, 522 | type: ContentType.Json, 523 | format: "json", 524 | ...params, 525 | }); 526 | /** 527 | * @description List Epics with pagination returns a paginated list of Epics and their attributes. 528 | * 529 | * @name ListEpicsPaginated 530 | * @summary List Epics Paginated 531 | * @request GET:/api/v3/epics/paginated 532 | * @secure 533 | */ 534 | listEpicsPaginated = ( 535 | query?: { 536 | /** A true/false boolean indicating whether to return Epics with their descriptions. */ 537 | includes_description?: boolean; 538 | /** 539 | * The page number to return, starting with 1. Defaults to 1. 540 | * @format int64 541 | */ 542 | page?: number; 543 | /** 544 | * The number of Epics to return per page. Minimum 1, maximum 250, default 10. 545 | * @format int64 546 | */ 547 | page_size?: number; 548 | }, 549 | params: RequestParams = {}, 550 | ) => 551 | this.request({ 552 | path: `/api/v3/epics/paginated`, 553 | method: "GET", 554 | query: query, 555 | secure: true, 556 | format: "json", 557 | ...params, 558 | }); 559 | /** 560 | * @description Get Epic returns information about the selected Epic. 561 | * 562 | * @name GetEpic 563 | * @summary Get Epic 564 | * @request GET:/api/v3/epics/{epic-public-id} 565 | * @secure 566 | */ 567 | getEpic = (epicPublicId: number, params: RequestParams = {}) => 568 | this.request({ 569 | path: `/api/v3/epics/${epicPublicId}`, 570 | method: "GET", 571 | secure: true, 572 | format: "json", 573 | ...params, 574 | }); 575 | /** 576 | * @description Update Epic can be used to update numerous fields in the Epic. The only required parameter is Epic ID, which can be found in the Shortcut UI. 577 | * 578 | * @name UpdateEpic 579 | * @summary Update Epic 580 | * @request PUT:/api/v3/epics/{epic-public-id} 581 | * @secure 582 | */ 583 | updateEpic = ( 584 | epicPublicId: number, 585 | UpdateEpic: UpdateEpic, 586 | params: RequestParams = {}, 587 | ) => 588 | this.request({ 589 | path: `/api/v3/epics/${epicPublicId}`, 590 | method: "PUT", 591 | body: UpdateEpic, 592 | secure: true, 593 | type: ContentType.Json, 594 | format: "json", 595 | ...params, 596 | }); 597 | /** 598 | * @description Delete Epic can be used to delete the Epic. The only required parameter is Epic ID. 599 | * 600 | * @name DeleteEpic 601 | * @summary Delete Epic 602 | * @request DELETE:/api/v3/epics/{epic-public-id} 603 | * @secure 604 | */ 605 | deleteEpic = (epicPublicId: number, params: RequestParams = {}) => 606 | this.request({ 607 | path: `/api/v3/epics/${epicPublicId}`, 608 | method: "DELETE", 609 | secure: true, 610 | ...params, 611 | }); 612 | /** 613 | * @description Get a list of all Comments on an Epic. 614 | * 615 | * @name ListEpicComments 616 | * @summary List Epic Comments 617 | * @request GET:/api/v3/epics/{epic-public-id}/comments 618 | * @secure 619 | */ 620 | listEpicComments = (epicPublicId: number, params: RequestParams = {}) => 621 | this.request({ 622 | path: `/api/v3/epics/${epicPublicId}/comments`, 623 | method: "GET", 624 | secure: true, 625 | format: "json", 626 | ...params, 627 | }); 628 | /** 629 | * @description This endpoint allows you to create a threaded Comment on an Epic. 630 | * 631 | * @name CreateEpicComment 632 | * @summary Create Epic Comment 633 | * @request POST:/api/v3/epics/{epic-public-id}/comments 634 | * @secure 635 | */ 636 | createEpicComment = ( 637 | epicPublicId: number, 638 | CreateEpicComment: CreateEpicComment, 639 | params: RequestParams = {}, 640 | ) => 641 | this.request({ 642 | path: `/api/v3/epics/${epicPublicId}/comments`, 643 | method: "POST", 644 | body: CreateEpicComment, 645 | secure: true, 646 | type: ContentType.Json, 647 | format: "json", 648 | ...params, 649 | }); 650 | /** 651 | * @description This endpoint allows you to create a nested Comment reply to an existing Epic Comment. 652 | * 653 | * @name CreateEpicCommentComment 654 | * @summary Create Epic Comment Comment 655 | * @request POST:/api/v3/epics/{epic-public-id}/comments/{comment-public-id} 656 | * @secure 657 | */ 658 | createEpicCommentComment = ( 659 | epicPublicId: number, 660 | commentPublicId: number, 661 | CreateCommentComment: CreateCommentComment, 662 | params: RequestParams = {}, 663 | ) => 664 | this.request({ 665 | path: `/api/v3/epics/${epicPublicId}/comments/${commentPublicId}`, 666 | method: "POST", 667 | body: CreateCommentComment, 668 | secure: true, 669 | type: ContentType.Json, 670 | format: "json", 671 | ...params, 672 | }); 673 | /** 674 | * @description This endpoint returns information about the selected Epic Comment. 675 | * 676 | * @name GetEpicComment 677 | * @summary Get Epic Comment 678 | * @request GET:/api/v3/epics/{epic-public-id}/comments/{comment-public-id} 679 | * @secure 680 | */ 681 | getEpicComment = ( 682 | epicPublicId: number, 683 | commentPublicId: number, 684 | params: RequestParams = {}, 685 | ) => 686 | this.request({ 687 | path: `/api/v3/epics/${epicPublicId}/comments/${commentPublicId}`, 688 | method: "GET", 689 | secure: true, 690 | format: "json", 691 | ...params, 692 | }); 693 | /** 694 | * @description This endpoint allows you to update a threaded Comment on an Epic. 695 | * 696 | * @name UpdateEpicComment 697 | * @summary Update Epic Comment 698 | * @request PUT:/api/v3/epics/{epic-public-id}/comments/{comment-public-id} 699 | * @secure 700 | */ 701 | updateEpicComment = ( 702 | epicPublicId: number, 703 | commentPublicId: number, 704 | UpdateComment: UpdateComment, 705 | params: RequestParams = {}, 706 | ) => 707 | this.request({ 708 | path: `/api/v3/epics/${epicPublicId}/comments/${commentPublicId}`, 709 | method: "PUT", 710 | body: UpdateComment, 711 | secure: true, 712 | type: ContentType.Json, 713 | format: "json", 714 | ...params, 715 | }); 716 | /** 717 | * @description This endpoint allows you to delete a Comment from an Epic. 718 | * 719 | * @name DeleteEpicComment 720 | * @summary Delete Epic Comment 721 | * @request DELETE:/api/v3/epics/{epic-public-id}/comments/{comment-public-id} 722 | * @secure 723 | */ 724 | deleteEpicComment = ( 725 | epicPublicId: number, 726 | commentPublicId: number, 727 | params: RequestParams = {}, 728 | ) => 729 | this.request({ 730 | path: `/api/v3/epics/${epicPublicId}/comments/${commentPublicId}`, 731 | method: "DELETE", 732 | secure: true, 733 | ...params, 734 | }); 735 | /** 736 | * @description Get the current health for the specified Epic. 737 | * 738 | * @name GetEpicHealth 739 | * @summary Get Epic Health 740 | * @request GET:/api/v3/epics/{epic-public-id}/health 741 | * @secure 742 | */ 743 | getEpicHealth = (epicPublicId: number, params: RequestParams = {}) => 744 | this.request({ 745 | path: `/api/v3/epics/${epicPublicId}/health`, 746 | method: "GET", 747 | secure: true, 748 | format: "json", 749 | ...params, 750 | }); 751 | /** 752 | * @description Create a new health status for the specified Epic. 753 | * 754 | * @name CreateEpicHealth 755 | * @summary Create Epic Health 756 | * @request POST:/api/v3/epics/{epic-public-id}/health 757 | * @secure 758 | */ 759 | createEpicHealth = ( 760 | epicPublicId: number, 761 | CreateEpicHealth: CreateEpicHealth, 762 | params: RequestParams = {}, 763 | ) => 764 | this.request({ 765 | path: `/api/v3/epics/${epicPublicId}/health`, 766 | method: "POST", 767 | body: CreateEpicHealth, 768 | secure: true, 769 | type: ContentType.Json, 770 | format: "json", 771 | ...params, 772 | }); 773 | /** 774 | * @description List the history of health statuses for the specified Epic, most recent first. 775 | * 776 | * @name ListEpicHealths 777 | * @summary List Epic Healths 778 | * @request GET:/api/v3/epics/{epic-public-id}/health-history 779 | * @secure 780 | */ 781 | listEpicHealths = (epicPublicId: number, params: RequestParams = {}) => 782 | this.request({ 783 | path: `/api/v3/epics/${epicPublicId}/health-history`, 784 | method: "GET", 785 | secure: true, 786 | format: "json", 787 | ...params, 788 | }); 789 | /** 790 | * @description Get a list of all Stories in an Epic. 791 | * 792 | * @name ListEpicStories 793 | * @summary List Epic Stories 794 | * @request GET:/api/v3/epics/{epic-public-id}/stories 795 | * @secure 796 | */ 797 | listEpicStories = ( 798 | epicPublicId: number, 799 | query?: { 800 | /** A true/false boolean indicating whether to return Stories with their descriptions. */ 801 | includes_description?: boolean; 802 | }, 803 | params: RequestParams = {}, 804 | ) => 805 | this.request({ 806 | path: `/api/v3/epics/${epicPublicId}/stories`, 807 | method: "GET", 808 | query: query, 809 | secure: true, 810 | format: "json", 811 | ...params, 812 | }); 813 | /** 814 | * @description This endpoint allows you to unlink a productboard epic. 815 | * 816 | * @name UnlinkProductboardFromEpic 817 | * @summary Unlink Productboard from Epic 818 | * @request POST:/api/v3/epics/{epic-public-id}/unlink-productboard 819 | * @secure 820 | */ 821 | unlinkProductboardFromEpic = ( 822 | epicPublicId: number, 823 | params: RequestParams = {}, 824 | ) => 825 | this.request({ 826 | path: `/api/v3/epics/${epicPublicId}/unlink-productboard`, 827 | method: "POST", 828 | secure: true, 829 | ...params, 830 | }); 831 | /** 832 | * @description Get Stories which have a given External Link associated with them. 833 | * 834 | * @name GetExternalLinkStories 835 | * @summary Get External Link Stories 836 | * @request GET:/api/v3/external-link/stories 837 | * @secure 838 | */ 839 | getExternalLinkStories = ( 840 | query: { 841 | /** 842 | * The external link associated with one or more stories. 843 | * @maxLength 2048 844 | * @pattern ^https?://.+$ 845 | */ 846 | external_link: string; 847 | }, 848 | params: RequestParams = {}, 849 | ) => 850 | this.request({ 851 | path: `/api/v3/external-link/stories`, 852 | method: "GET", 853 | query: query, 854 | secure: true, 855 | format: "json", 856 | ...params, 857 | }); 858 | /** 859 | * @description List Files returns a list of all UploadedFiles in the workspace. 860 | * 861 | * @name ListFiles 862 | * @summary List Files 863 | * @request GET:/api/v3/files 864 | * @secure 865 | */ 866 | listFiles = (params: RequestParams = {}) => 867 | this.request({ 868 | path: `/api/v3/files`, 869 | method: "GET", 870 | secure: true, 871 | format: "json", 872 | ...params, 873 | }); 874 | /** 875 | * @description Upload Files uploads one or many files and optionally associates them with a story. Use the multipart/form-data content-type to upload. Each `file` key should contain a separate file. Each UploadedFile's name comes from the Content-Disposition header "filename" directive for that field. 876 | * 877 | * @name UploadFiles 878 | * @summary Upload Files 879 | * @request POST:/api/v3/files 880 | * @secure 881 | */ 882 | uploadFiles = ( 883 | data: { 884 | /** 885 | * The story ID that these files will be associated with. 886 | * @format int64 887 | */ 888 | story_id?: number; 889 | /** 890 | * A file upload. At least one is required. 891 | * @format binary 892 | */ 893 | file0: File; 894 | /** 895 | * Optional additional files. 896 | * @format binary 897 | */ 898 | file1?: File; 899 | /** 900 | * Optional additional files. 901 | * @format binary 902 | */ 903 | file2?: File; 904 | /** 905 | * Optional additional files. 906 | * @format binary 907 | */ 908 | file3?: File; 909 | }, 910 | params: RequestParams = {}, 911 | ) => 912 | this.request({ 913 | path: `/api/v3/files`, 914 | method: "POST", 915 | body: data, 916 | secure: true, 917 | type: ContentType.FormData, 918 | format: "json", 919 | ...params, 920 | }); 921 | /** 922 | * @description Get File returns information about the selected UploadedFile. 923 | * 924 | * @name GetFile 925 | * @summary Get File 926 | * @request GET:/api/v3/files/{file-public-id} 927 | * @secure 928 | */ 929 | getFile = (filePublicId: number, params: RequestParams = {}) => 930 | this.request({ 931 | path: `/api/v3/files/${filePublicId}`, 932 | method: "GET", 933 | secure: true, 934 | format: "json", 935 | ...params, 936 | }); 937 | /** 938 | * @description Update File updates the properties of an UploadedFile (but not its content). 939 | * 940 | * @name UpdateFile 941 | * @summary Update File 942 | * @request PUT:/api/v3/files/{file-public-id} 943 | * @secure 944 | */ 945 | updateFile = ( 946 | filePublicId: number, 947 | UpdateFile: UpdateFile, 948 | params: RequestParams = {}, 949 | ) => 950 | this.request({ 951 | path: `/api/v3/files/${filePublicId}`, 952 | method: "PUT", 953 | body: UpdateFile, 954 | secure: true, 955 | type: ContentType.Json, 956 | format: "json", 957 | ...params, 958 | }); 959 | /** 960 | * @description Delete File deletes a previously uploaded file. 961 | * 962 | * @name DeleteFile 963 | * @summary Delete File 964 | * @request DELETE:/api/v3/files/{file-public-id} 965 | * @secure 966 | */ 967 | deleteFile = (filePublicId: number, params: RequestParams = {}) => 968 | this.request({ 969 | path: `/api/v3/files/${filePublicId}`, 970 | method: "DELETE", 971 | secure: true, 972 | ...params, 973 | }); 974 | /** 975 | * @description A group in our API maps to a "Team" within the Shortcut Product. A Team is a collection of Users that can be associated to Stories, Epics, and Iterations within Shortcut. 976 | * 977 | * @name ListGroups 978 | * @summary List Groups 979 | * @request GET:/api/v3/groups 980 | * @secure 981 | */ 982 | listGroups = ( 983 | query?: { 984 | /** Filter groups by their archived state. If true, returns only archived groups. If false, returns only unarchived groups. If not provided, returns all groups */ 985 | archived?: boolean; 986 | }, 987 | params: RequestParams = {}, 988 | ) => 989 | this.request({ 990 | path: `/api/v3/groups`, 991 | method: "GET", 992 | query: query, 993 | secure: true, 994 | format: "json", 995 | ...params, 996 | }); 997 | /** 998 | * No description 999 | * 1000 | * @name CreateGroup 1001 | * @summary Create Group 1002 | * @request POST:/api/v3/groups 1003 | * @secure 1004 | */ 1005 | createGroup = (CreateGroup: CreateGroup, params: RequestParams = {}) => 1006 | this.request({ 1007 | path: `/api/v3/groups`, 1008 | method: "POST", 1009 | body: CreateGroup, 1010 | secure: true, 1011 | type: ContentType.Json, 1012 | format: "json", 1013 | ...params, 1014 | }); 1015 | /** 1016 | * No description 1017 | * 1018 | * @name GetGroup 1019 | * @summary Get Group 1020 | * @request GET:/api/v3/groups/{group-public-id} 1021 | * @secure 1022 | */ 1023 | getGroup = (groupPublicId: string, params: RequestParams = {}) => 1024 | this.request({ 1025 | path: `/api/v3/groups/${groupPublicId}`, 1026 | method: "GET", 1027 | secure: true, 1028 | format: "json", 1029 | ...params, 1030 | }); 1031 | /** 1032 | * No description 1033 | * 1034 | * @name UpdateGroup 1035 | * @summary Update Group 1036 | * @request PUT:/api/v3/groups/{group-public-id} 1037 | * @secure 1038 | */ 1039 | updateGroup = ( 1040 | groupPublicId: string, 1041 | UpdateGroup: UpdateGroup, 1042 | params: RequestParams = {}, 1043 | ) => 1044 | this.request({ 1045 | path: `/api/v3/groups/${groupPublicId}`, 1046 | method: "PUT", 1047 | body: UpdateGroup, 1048 | secure: true, 1049 | type: ContentType.Json, 1050 | format: "json", 1051 | ...params, 1052 | }); 1053 | /** 1054 | * @description List the Stories assigned to the Group. (By default, limited to 1,000). 1055 | * 1056 | * @name ListGroupStories 1057 | * @summary List Group Stories 1058 | * @request GET:/api/v3/groups/{group-public-id}/stories 1059 | * @secure 1060 | */ 1061 | listGroupStories = ( 1062 | groupPublicId: string, 1063 | query?: { 1064 | /** 1065 | * The maximum number of results to return. (Defaults to 1000, max 1000) 1066 | * @format int64 1067 | */ 1068 | limit?: number; 1069 | /** 1070 | * The offset at which to begin returning results. (Defaults to 0) 1071 | * @format int64 1072 | */ 1073 | offset?: number; 1074 | }, 1075 | params: RequestParams = {}, 1076 | ) => 1077 | this.request({ 1078 | path: `/api/v3/groups/${groupPublicId}/stories`, 1079 | method: "GET", 1080 | query: query, 1081 | secure: true, 1082 | format: "json", 1083 | ...params, 1084 | }); 1085 | /** 1086 | * @description Update an existing health status by its ID. 1087 | * 1088 | * @name UpdateHealth 1089 | * @summary Update Health 1090 | * @request PUT:/api/v3/health/{health-public-id} 1091 | * @secure 1092 | */ 1093 | updateHealth = ( 1094 | healthPublicId: string, 1095 | UpdateHealth: UpdateHealth, 1096 | params: RequestParams = {}, 1097 | ) => 1098 | this.request({ 1099 | path: `/api/v3/health/${healthPublicId}`, 1100 | method: "PUT", 1101 | body: UpdateHealth, 1102 | secure: true, 1103 | type: ContentType.Json, 1104 | format: "json", 1105 | ...params, 1106 | }); 1107 | /** 1108 | * No description 1109 | * 1110 | * @name CreateGenericIntegration 1111 | * @summary Create Generic Integration 1112 | * @request POST:/api/v3/integrations/webhook 1113 | * @secure 1114 | */ 1115 | createGenericIntegration = ( 1116 | CreateGenericIntegration: CreateGenericIntegration, 1117 | params: RequestParams = {}, 1118 | ) => 1119 | this.request({ 1120 | path: `/api/v3/integrations/webhook`, 1121 | method: "POST", 1122 | body: CreateGenericIntegration, 1123 | secure: true, 1124 | type: ContentType.Json, 1125 | ...params, 1126 | }); 1127 | /** 1128 | * No description 1129 | * 1130 | * @name GetGenericIntegration 1131 | * @summary Get Generic Integration 1132 | * @request GET:/api/v3/integrations/webhook/{integration-public-id} 1133 | * @secure 1134 | */ 1135 | getGenericIntegration = ( 1136 | integrationPublicId: number, 1137 | params: RequestParams = {}, 1138 | ) => 1139 | this.request({ 1140 | path: `/api/v3/integrations/webhook/${integrationPublicId}`, 1141 | method: "GET", 1142 | secure: true, 1143 | ...params, 1144 | }); 1145 | /** 1146 | * No description 1147 | * 1148 | * @name DeleteGenericIntegration 1149 | * @summary Delete Generic Integration 1150 | * @request DELETE:/api/v3/integrations/webhook/{integration-public-id} 1151 | * @secure 1152 | */ 1153 | deleteGenericIntegration = ( 1154 | integrationPublicId: number, 1155 | params: RequestParams = {}, 1156 | ) => 1157 | this.request({ 1158 | path: `/api/v3/integrations/webhook/${integrationPublicId}`, 1159 | method: "DELETE", 1160 | secure: true, 1161 | ...params, 1162 | }); 1163 | /** 1164 | * No description 1165 | * 1166 | * @name ListIterations 1167 | * @summary List Iterations 1168 | * @request GET:/api/v3/iterations 1169 | * @secure 1170 | */ 1171 | listIterations = (params: RequestParams = {}) => 1172 | this.request({ 1173 | path: `/api/v3/iterations`, 1174 | method: "GET", 1175 | secure: true, 1176 | format: "json", 1177 | ...params, 1178 | }); 1179 | /** 1180 | * No description 1181 | * 1182 | * @name CreateIteration 1183 | * @summary Create Iteration 1184 | * @request POST:/api/v3/iterations 1185 | * @secure 1186 | */ 1187 | createIteration = ( 1188 | CreateIteration: CreateIteration, 1189 | params: RequestParams = {}, 1190 | ) => 1191 | this.request({ 1192 | path: `/api/v3/iterations`, 1193 | method: "POST", 1194 | body: CreateIteration, 1195 | secure: true, 1196 | type: ContentType.Json, 1197 | format: "json", 1198 | ...params, 1199 | }); 1200 | /** 1201 | * @description Disables Iterations for the current workspace 1202 | * 1203 | * @name DisableIterations 1204 | * @summary Disable Iterations 1205 | * @request PUT:/api/v3/iterations/disable 1206 | * @secure 1207 | */ 1208 | disableIterations = (params: RequestParams = {}) => 1209 | this.request({ 1210 | path: `/api/v3/iterations/disable`, 1211 | method: "PUT", 1212 | secure: true, 1213 | ...params, 1214 | }); 1215 | /** 1216 | * @description Enables Iterations for the current workspace 1217 | * 1218 | * @name EnableIterations 1219 | * @summary Enable Iterations 1220 | * @request PUT:/api/v3/iterations/enable 1221 | * @secure 1222 | */ 1223 | enableIterations = (params: RequestParams = {}) => 1224 | this.request({ 1225 | path: `/api/v3/iterations/enable`, 1226 | method: "PUT", 1227 | secure: true, 1228 | ...params, 1229 | }); 1230 | /** 1231 | * No description 1232 | * 1233 | * @name GetIteration 1234 | * @summary Get Iteration 1235 | * @request GET:/api/v3/iterations/{iteration-public-id} 1236 | * @secure 1237 | */ 1238 | getIteration = (iterationPublicId: number, params: RequestParams = {}) => 1239 | this.request({ 1240 | path: `/api/v3/iterations/${iterationPublicId}`, 1241 | method: "GET", 1242 | secure: true, 1243 | format: "json", 1244 | ...params, 1245 | }); 1246 | /** 1247 | * No description 1248 | * 1249 | * @name UpdateIteration 1250 | * @summary Update Iteration 1251 | * @request PUT:/api/v3/iterations/{iteration-public-id} 1252 | * @secure 1253 | */ 1254 | updateIteration = ( 1255 | iterationPublicId: number, 1256 | UpdateIteration: UpdateIteration, 1257 | params: RequestParams = {}, 1258 | ) => 1259 | this.request({ 1260 | path: `/api/v3/iterations/${iterationPublicId}`, 1261 | method: "PUT", 1262 | body: UpdateIteration, 1263 | secure: true, 1264 | type: ContentType.Json, 1265 | format: "json", 1266 | ...params, 1267 | }); 1268 | /** 1269 | * No description 1270 | * 1271 | * @name DeleteIteration 1272 | * @summary Delete Iteration 1273 | * @request DELETE:/api/v3/iterations/{iteration-public-id} 1274 | * @secure 1275 | */ 1276 | deleteIteration = (iterationPublicId: number, params: RequestParams = {}) => 1277 | this.request({ 1278 | path: `/api/v3/iterations/${iterationPublicId}`, 1279 | method: "DELETE", 1280 | secure: true, 1281 | ...params, 1282 | }); 1283 | /** 1284 | * @description Get a list of all Stories in an Iteration. 1285 | * 1286 | * @name ListIterationStories 1287 | * @summary List Iteration Stories 1288 | * @request GET:/api/v3/iterations/{iteration-public-id}/stories 1289 | * @secure 1290 | */ 1291 | listIterationStories = ( 1292 | iterationPublicId: number, 1293 | query?: { 1294 | /** A true/false boolean indicating whether to return Stories with their descriptions. */ 1295 | includes_description?: boolean; 1296 | }, 1297 | params: RequestParams = {}, 1298 | ) => 1299 | this.request({ 1300 | path: `/api/v3/iterations/${iterationPublicId}/stories`, 1301 | method: "GET", 1302 | query: query, 1303 | secure: true, 1304 | format: "json", 1305 | ...params, 1306 | }); 1307 | /** 1308 | * @description Get Key Result returns information about a chosen Key Result. 1309 | * 1310 | * @name GetKeyResult 1311 | * @summary Get Key Result 1312 | * @request GET:/api/v3/key-results/{key-result-public-id} 1313 | * @secure 1314 | */ 1315 | getKeyResult = (keyResultPublicId: string, params: RequestParams = {}) => 1316 | this.request({ 1317 | path: `/api/v3/key-results/${keyResultPublicId}`, 1318 | method: "GET", 1319 | secure: true, 1320 | format: "json", 1321 | ...params, 1322 | }); 1323 | /** 1324 | * @description Update Key Result allows updating a Key Result's name or initial, observed, or target values. 1325 | * 1326 | * @name UpdateKeyResult 1327 | * @summary Update Key Result 1328 | * @request PUT:/api/v3/key-results/{key-result-public-id} 1329 | * @secure 1330 | */ 1331 | updateKeyResult = ( 1332 | keyResultPublicId: string, 1333 | UpdateKeyResult: UpdateKeyResult, 1334 | params: RequestParams = {}, 1335 | ) => 1336 | this.request({ 1337 | path: `/api/v3/key-results/${keyResultPublicId}`, 1338 | method: "PUT", 1339 | body: UpdateKeyResult, 1340 | secure: true, 1341 | type: ContentType.Json, 1342 | format: "json", 1343 | ...params, 1344 | }); 1345 | /** 1346 | * @description List Labels returns a list of all Labels and their attributes. 1347 | * 1348 | * @name ListLabels 1349 | * @summary List Labels 1350 | * @request GET:/api/v3/labels 1351 | * @secure 1352 | */ 1353 | listLabels = ( 1354 | query?: { 1355 | /** A true/false boolean indicating if the slim versions of the Label should be returned. */ 1356 | slim?: boolean; 1357 | }, 1358 | params: RequestParams = {}, 1359 | ) => 1360 | this.request({ 1361 | path: `/api/v3/labels`, 1362 | method: "GET", 1363 | query: query, 1364 | secure: true, 1365 | format: "json", 1366 | ...params, 1367 | }); 1368 | /** 1369 | * @description Create Label allows you to create a new Label in Shortcut. 1370 | * 1371 | * @name CreateLabel 1372 | * @summary Create Label 1373 | * @request POST:/api/v3/labels 1374 | * @secure 1375 | */ 1376 | createLabel = ( 1377 | CreateLabelParams: CreateLabelParams, 1378 | params: RequestParams = {}, 1379 | ) => 1380 | this.request({ 1381 | path: `/api/v3/labels`, 1382 | method: "POST", 1383 | body: CreateLabelParams, 1384 | secure: true, 1385 | type: ContentType.Json, 1386 | format: "json", 1387 | ...params, 1388 | }); 1389 | /** 1390 | * @description Get Label returns information about the selected Label. 1391 | * 1392 | * @name GetLabel 1393 | * @summary Get Label 1394 | * @request GET:/api/v3/labels/{label-public-id} 1395 | * @secure 1396 | */ 1397 | getLabel = (labelPublicId: number, params: RequestParams = {}) => 1398 | this.request({ 1399 | path: `/api/v3/labels/${labelPublicId}`, 1400 | method: "GET", 1401 | secure: true, 1402 | format: "json", 1403 | ...params, 1404 | }); 1405 | /** 1406 | * @description Update Label allows you to replace a Label name with another name. If you try to name a Label something that already exists, you will receive a 422 response. 1407 | * 1408 | * @name UpdateLabel 1409 | * @summary Update Label 1410 | * @request PUT:/api/v3/labels/{label-public-id} 1411 | * @secure 1412 | */ 1413 | updateLabel = ( 1414 | labelPublicId: number, 1415 | UpdateLabel: UpdateLabel, 1416 | params: RequestParams = {}, 1417 | ) => 1418 | this.request({ 1419 | path: `/api/v3/labels/${labelPublicId}`, 1420 | method: "PUT", 1421 | body: UpdateLabel, 1422 | secure: true, 1423 | type: ContentType.Json, 1424 | format: "json", 1425 | ...params, 1426 | }); 1427 | /** 1428 | * @description Delete Label can be used to delete any Label. 1429 | * 1430 | * @name DeleteLabel 1431 | * @summary Delete Label 1432 | * @request DELETE:/api/v3/labels/{label-public-id} 1433 | * @secure 1434 | */ 1435 | deleteLabel = (labelPublicId: number, params: RequestParams = {}) => 1436 | this.request({ 1437 | path: `/api/v3/labels/${labelPublicId}`, 1438 | method: "DELETE", 1439 | secure: true, 1440 | ...params, 1441 | }); 1442 | /** 1443 | * @description List all of the Epics with the Label. 1444 | * 1445 | * @name ListLabelEpics 1446 | * @summary List Label Epics 1447 | * @request GET:/api/v3/labels/{label-public-id}/epics 1448 | * @secure 1449 | */ 1450 | listLabelEpics = (labelPublicId: number, params: RequestParams = {}) => 1451 | this.request({ 1452 | path: `/api/v3/labels/${labelPublicId}/epics`, 1453 | method: "GET", 1454 | secure: true, 1455 | format: "json", 1456 | ...params, 1457 | }); 1458 | /** 1459 | * @description List all of the Stories with the Label. 1460 | * 1461 | * @name ListLabelStories 1462 | * @summary List Label Stories 1463 | * @request GET:/api/v3/labels/{label-public-id}/stories 1464 | * @secure 1465 | */ 1466 | listLabelStories = ( 1467 | labelPublicId: number, 1468 | query?: { 1469 | /** A true/false boolean indicating whether to return Stories with their descriptions. */ 1470 | includes_description?: boolean; 1471 | }, 1472 | params: RequestParams = {}, 1473 | ) => 1474 | this.request({ 1475 | path: `/api/v3/labels/${labelPublicId}/stories`, 1476 | method: "GET", 1477 | query: query, 1478 | secure: true, 1479 | format: "json", 1480 | ...params, 1481 | }); 1482 | /** 1483 | * @description List Linked Files returns a list of all Linked-Files and their attributes. 1484 | * 1485 | * @name ListLinkedFiles 1486 | * @summary List Linked Files 1487 | * @request GET:/api/v3/linked-files 1488 | * @secure 1489 | */ 1490 | listLinkedFiles = (params: RequestParams = {}) => 1491 | this.request({ 1492 | path: `/api/v3/linked-files`, 1493 | method: "GET", 1494 | secure: true, 1495 | format: "json", 1496 | ...params, 1497 | }); 1498 | /** 1499 | * @description Create Linked File allows you to create a new Linked File in Shortcut. 1500 | * 1501 | * @name CreateLinkedFile 1502 | * @summary Create Linked File 1503 | * @request POST:/api/v3/linked-files 1504 | * @secure 1505 | */ 1506 | createLinkedFile = ( 1507 | CreateLinkedFile: CreateLinkedFile, 1508 | params: RequestParams = {}, 1509 | ) => 1510 | this.request({ 1511 | path: `/api/v3/linked-files`, 1512 | method: "POST", 1513 | body: CreateLinkedFile, 1514 | secure: true, 1515 | type: ContentType.Json, 1516 | format: "json", 1517 | ...params, 1518 | }); 1519 | /** 1520 | * @description Get File returns information about the selected Linked File. 1521 | * 1522 | * @name GetLinkedFile 1523 | * @summary Get Linked File 1524 | * @request GET:/api/v3/linked-files/{linked-file-public-id} 1525 | * @secure 1526 | */ 1527 | getLinkedFile = (linkedFilePublicId: number, params: RequestParams = {}) => 1528 | this.request({ 1529 | path: `/api/v3/linked-files/${linkedFilePublicId}`, 1530 | method: "GET", 1531 | secure: true, 1532 | format: "json", 1533 | ...params, 1534 | }); 1535 | /** 1536 | * @description Updated Linked File allows you to update properties of a previously attached Linked-File. 1537 | * 1538 | * @name UpdateLinkedFile 1539 | * @summary Update Linked File 1540 | * @request PUT:/api/v3/linked-files/{linked-file-public-id} 1541 | * @secure 1542 | */ 1543 | updateLinkedFile = ( 1544 | linkedFilePublicId: number, 1545 | UpdateLinkedFile: UpdateLinkedFile, 1546 | params: RequestParams = {}, 1547 | ) => 1548 | this.request({ 1549 | path: `/api/v3/linked-files/${linkedFilePublicId}`, 1550 | method: "PUT", 1551 | body: UpdateLinkedFile, 1552 | secure: true, 1553 | type: ContentType.Json, 1554 | format: "json", 1555 | ...params, 1556 | }); 1557 | /** 1558 | * @description Delete Linked File can be used to delete any previously attached Linked-File. 1559 | * 1560 | * @name DeleteLinkedFile 1561 | * @summary Delete Linked File 1562 | * @request DELETE:/api/v3/linked-files/{linked-file-public-id} 1563 | * @secure 1564 | */ 1565 | deleteLinkedFile = (linkedFilePublicId: number, params: RequestParams = {}) => 1566 | this.request({ 1567 | path: `/api/v3/linked-files/${linkedFilePublicId}`, 1568 | method: "DELETE", 1569 | secure: true, 1570 | ...params, 1571 | }); 1572 | /** 1573 | * @description Returns information about the authenticated member. 1574 | * 1575 | * @name GetCurrentMemberInfo 1576 | * @summary Get Current Member Info 1577 | * @request GET:/api/v3/member 1578 | * @secure 1579 | */ 1580 | getCurrentMemberInfo = (params: RequestParams = {}) => 1581 | this.request({ 1582 | path: `/api/v3/member`, 1583 | method: "GET", 1584 | secure: true, 1585 | format: "json", 1586 | ...params, 1587 | }); 1588 | /** 1589 | * @description Returns information about members of the Workspace. 1590 | * 1591 | * @name ListMembers 1592 | * @summary List Members 1593 | * @request GET:/api/v3/members 1594 | * @secure 1595 | */ 1596 | listMembers = ( 1597 | query?: { 1598 | /** 1599 | * The unique ID of the Organization to limit the list to. 1600 | * @format uuid 1601 | */ 1602 | "org-public-id"?: string; 1603 | /** Filter members by their disabled state. If true, return only disabled members. If false, return only enabled members. */ 1604 | disabled?: boolean; 1605 | }, 1606 | params: RequestParams = {}, 1607 | ) => 1608 | this.request({ 1609 | path: `/api/v3/members`, 1610 | method: "GET", 1611 | query: query, 1612 | secure: true, 1613 | format: "json", 1614 | ...params, 1615 | }); 1616 | /** 1617 | * @description Returns information about a Member. 1618 | * 1619 | * @name GetMember 1620 | * @summary Get Member 1621 | * @request GET:/api/v3/members/{member-public-id} 1622 | * @secure 1623 | */ 1624 | getMember = ( 1625 | memberPublicId: string, 1626 | query?: { 1627 | /** 1628 | * The unique ID of the Organization to limit the lookup to. 1629 | * @format uuid 1630 | */ 1631 | "org-public-id"?: string; 1632 | }, 1633 | params: RequestParams = {}, 1634 | ) => 1635 | this.request({ 1636 | path: `/api/v3/members/${memberPublicId}`, 1637 | method: "GET", 1638 | query: query, 1639 | secure: true, 1640 | format: "json", 1641 | ...params, 1642 | }); 1643 | /** 1644 | * @description (Deprecated: Use 'List Objectives') List Milestones returns a list of all Milestones and their attributes. 1645 | * 1646 | * @name ListMilestones 1647 | * @summary List Milestones 1648 | * @request GET:/api/v3/milestones 1649 | * @secure 1650 | */ 1651 | listMilestones = (params: RequestParams = {}) => 1652 | this.request({ 1653 | path: `/api/v3/milestones`, 1654 | method: "GET", 1655 | secure: true, 1656 | format: "json", 1657 | ...params, 1658 | }); 1659 | /** 1660 | * @description (Deprecated: Use 'Create Objective') Create Milestone allows you to create a new Milestone in Shortcut. 1661 | * 1662 | * @name CreateMilestone 1663 | * @summary Create Milestone 1664 | * @request POST:/api/v3/milestones 1665 | * @secure 1666 | */ 1667 | createMilestone = ( 1668 | CreateMilestone: CreateMilestone, 1669 | params: RequestParams = {}, 1670 | ) => 1671 | this.request({ 1672 | path: `/api/v3/milestones`, 1673 | method: "POST", 1674 | body: CreateMilestone, 1675 | secure: true, 1676 | type: ContentType.Json, 1677 | format: "json", 1678 | ...params, 1679 | }); 1680 | /** 1681 | * @description (Deprecated: Use 'Get Objective') Get Milestone returns information about a chosen Milestone. 1682 | * 1683 | * @name GetMilestone 1684 | * @summary Get Milestone 1685 | * @request GET:/api/v3/milestones/{milestone-public-id} 1686 | * @secure 1687 | */ 1688 | getMilestone = (milestonePublicId: number, params: RequestParams = {}) => 1689 | this.request({ 1690 | path: `/api/v3/milestones/${milestonePublicId}`, 1691 | method: "GET", 1692 | secure: true, 1693 | format: "json", 1694 | ...params, 1695 | }); 1696 | /** 1697 | * @description (Deprecated: Use 'Update Objective') Update Milestone can be used to update Milestone properties. 1698 | * 1699 | * @name UpdateMilestone 1700 | * @summary Update Milestone 1701 | * @request PUT:/api/v3/milestones/{milestone-public-id} 1702 | * @secure 1703 | */ 1704 | updateMilestone = ( 1705 | milestonePublicId: number, 1706 | UpdateMilestone: UpdateMilestone, 1707 | params: RequestParams = {}, 1708 | ) => 1709 | this.request({ 1710 | path: `/api/v3/milestones/${milestonePublicId}`, 1711 | method: "PUT", 1712 | body: UpdateMilestone, 1713 | secure: true, 1714 | type: ContentType.Json, 1715 | format: "json", 1716 | ...params, 1717 | }); 1718 | /** 1719 | * @description (Deprecated: Use 'Delete Objective') Delete Milestone can be used to delete any Milestone. 1720 | * 1721 | * @name DeleteMilestone 1722 | * @summary Delete Milestone 1723 | * @request DELETE:/api/v3/milestones/{milestone-public-id} 1724 | * @secure 1725 | */ 1726 | deleteMilestone = (milestonePublicId: number, params: RequestParams = {}) => 1727 | this.request({ 1728 | path: `/api/v3/milestones/${milestonePublicId}`, 1729 | method: "DELETE", 1730 | secure: true, 1731 | ...params, 1732 | }); 1733 | /** 1734 | * @description (Deprecated: Use 'List Objective Epics') List all of the Epics within the Milestone. 1735 | * 1736 | * @name ListMilestoneEpics 1737 | * @summary List Milestone Epics 1738 | * @request GET:/api/v3/milestones/{milestone-public-id}/epics 1739 | * @secure 1740 | */ 1741 | listMilestoneEpics = ( 1742 | milestonePublicId: number, 1743 | params: RequestParams = {}, 1744 | ) => 1745 | this.request({ 1746 | path: `/api/v3/milestones/${milestonePublicId}/epics`, 1747 | method: "GET", 1748 | secure: true, 1749 | format: "json", 1750 | ...params, 1751 | }); 1752 | /** 1753 | * @description List Objectives returns a list of all Objectives and their attributes. 1754 | * 1755 | * @name ListObjectives 1756 | * @summary List Objectives 1757 | * @request GET:/api/v3/objectives 1758 | * @secure 1759 | */ 1760 | listObjectives = (params: RequestParams = {}) => 1761 | this.request({ 1762 | path: `/api/v3/objectives`, 1763 | method: "GET", 1764 | secure: true, 1765 | format: "json", 1766 | ...params, 1767 | }); 1768 | /** 1769 | * @description Create Objective allows you to create a new Objective in Shortcut. 1770 | * 1771 | * @name CreateObjective 1772 | * @summary Create Objective 1773 | * @request POST:/api/v3/objectives 1774 | * @secure 1775 | */ 1776 | createObjective = ( 1777 | CreateObjective: CreateObjective, 1778 | params: RequestParams = {}, 1779 | ) => 1780 | this.request({ 1781 | path: `/api/v3/objectives`, 1782 | method: "POST", 1783 | body: CreateObjective, 1784 | secure: true, 1785 | type: ContentType.Json, 1786 | format: "json", 1787 | ...params, 1788 | }); 1789 | /** 1790 | * @description Get Objective returns information about a chosen Objective. 1791 | * 1792 | * @name GetObjective 1793 | * @summary Get Objective 1794 | * @request GET:/api/v3/objectives/{objective-public-id} 1795 | * @secure 1796 | */ 1797 | getObjective = (objectivePublicId: number, params: RequestParams = {}) => 1798 | this.request({ 1799 | path: `/api/v3/objectives/${objectivePublicId}`, 1800 | method: "GET", 1801 | secure: true, 1802 | format: "json", 1803 | ...params, 1804 | }); 1805 | /** 1806 | * @description Update Objective can be used to update Objective properties. 1807 | * 1808 | * @name UpdateObjective 1809 | * @summary Update Objective 1810 | * @request PUT:/api/v3/objectives/{objective-public-id} 1811 | * @secure 1812 | */ 1813 | updateObjective = ( 1814 | objectivePublicId: number, 1815 | UpdateObjective: UpdateObjective, 1816 | params: RequestParams = {}, 1817 | ) => 1818 | this.request({ 1819 | path: `/api/v3/objectives/${objectivePublicId}`, 1820 | method: "PUT", 1821 | body: UpdateObjective, 1822 | secure: true, 1823 | type: ContentType.Json, 1824 | format: "json", 1825 | ...params, 1826 | }); 1827 | /** 1828 | * @description Delete Objective can be used to delete any Objective. 1829 | * 1830 | * @name DeleteObjective 1831 | * @summary Delete Objective 1832 | * @request DELETE:/api/v3/objectives/{objective-public-id} 1833 | * @secure 1834 | */ 1835 | deleteObjective = (objectivePublicId: number, params: RequestParams = {}) => 1836 | this.request({ 1837 | path: `/api/v3/objectives/${objectivePublicId}`, 1838 | method: "DELETE", 1839 | secure: true, 1840 | ...params, 1841 | }); 1842 | /** 1843 | * @description List all of the Epics within the Objective. 1844 | * 1845 | * @name ListObjectiveEpics 1846 | * @summary List Objective Epics 1847 | * @request GET:/api/v3/objectives/{objective-public-id}/epics 1848 | * @secure 1849 | */ 1850 | listObjectiveEpics = ( 1851 | objectivePublicId: number, 1852 | params: RequestParams = {}, 1853 | ) => 1854 | this.request({ 1855 | path: `/api/v3/objectives/${objectivePublicId}/epics`, 1856 | method: "GET", 1857 | secure: true, 1858 | format: "json", 1859 | ...params, 1860 | }); 1861 | /** 1862 | * @description List Projects returns a list of all Projects and their attributes. 1863 | * 1864 | * @name ListProjects 1865 | * @summary List Projects 1866 | * @request GET:/api/v3/projects 1867 | * @secure 1868 | */ 1869 | listProjects = (params: RequestParams = {}) => 1870 | this.request({ 1871 | path: `/api/v3/projects`, 1872 | method: "GET", 1873 | secure: true, 1874 | format: "json", 1875 | ...params, 1876 | }); 1877 | /** 1878 | * @description Create Project is used to create a new Shortcut Project. 1879 | * 1880 | * @name CreateProject 1881 | * @summary Create Project 1882 | * @request POST:/api/v3/projects 1883 | * @secure 1884 | */ 1885 | createProject = (CreateProject: CreateProject, params: RequestParams = {}) => 1886 | this.request({ 1887 | path: `/api/v3/projects`, 1888 | method: "POST", 1889 | body: CreateProject, 1890 | secure: true, 1891 | type: ContentType.Json, 1892 | format: "json", 1893 | ...params, 1894 | }); 1895 | /** 1896 | * @description Get Project returns information about the selected Project. 1897 | * 1898 | * @name GetProject 1899 | * @summary Get Project 1900 | * @request GET:/api/v3/projects/{project-public-id} 1901 | * @secure 1902 | */ 1903 | getProject = (projectPublicId: number, params: RequestParams = {}) => 1904 | this.request({ 1905 | path: `/api/v3/projects/${projectPublicId}`, 1906 | method: "GET", 1907 | secure: true, 1908 | format: "json", 1909 | ...params, 1910 | }); 1911 | /** 1912 | * @description Update Project can be used to change properties of a Project. 1913 | * 1914 | * @name UpdateProject 1915 | * @summary Update Project 1916 | * @request PUT:/api/v3/projects/{project-public-id} 1917 | * @secure 1918 | */ 1919 | updateProject = ( 1920 | projectPublicId: number, 1921 | UpdateProject: UpdateProject, 1922 | params: RequestParams = {}, 1923 | ) => 1924 | this.request({ 1925 | path: `/api/v3/projects/${projectPublicId}`, 1926 | method: "PUT", 1927 | body: UpdateProject, 1928 | secure: true, 1929 | type: ContentType.Json, 1930 | format: "json", 1931 | ...params, 1932 | }); 1933 | /** 1934 | * @description Delete Project can be used to delete a Project. Projects can only be deleted if all associated Stories are moved or deleted. In the case that the Project cannot be deleted, you will receive a 422 response. 1935 | * 1936 | * @name DeleteProject 1937 | * @summary Delete Project 1938 | * @request DELETE:/api/v3/projects/{project-public-id} 1939 | * @secure 1940 | */ 1941 | deleteProject = (projectPublicId: number, params: RequestParams = {}) => 1942 | this.request({ 1943 | path: `/api/v3/projects/${projectPublicId}`, 1944 | method: "DELETE", 1945 | secure: true, 1946 | ...params, 1947 | }); 1948 | /** 1949 | * @description List Stories returns a list of all Stories in a selected Project and their attributes. 1950 | * 1951 | * @name ListStories 1952 | * @summary List Stories 1953 | * @request GET:/api/v3/projects/{project-public-id}/stories 1954 | * @secure 1955 | */ 1956 | listStories = ( 1957 | projectPublicId: number, 1958 | query?: { 1959 | /** A true/false boolean indicating whether to return Stories with their descriptions. */ 1960 | includes_description?: boolean; 1961 | }, 1962 | params: RequestParams = {}, 1963 | ) => 1964 | this.request({ 1965 | path: `/api/v3/projects/${projectPublicId}/stories`, 1966 | method: "GET", 1967 | query: query, 1968 | secure: true, 1969 | format: "json", 1970 | ...params, 1971 | }); 1972 | /** 1973 | * @description List Repositories returns a list of all Repositories and their attributes. 1974 | * 1975 | * @name ListRepositories 1976 | * @summary List Repositories 1977 | * @request GET:/api/v3/repositories 1978 | * @secure 1979 | */ 1980 | listRepositories = (params: RequestParams = {}) => 1981 | this.request({ 1982 | path: `/api/v3/repositories`, 1983 | method: "GET", 1984 | secure: true, 1985 | format: "json", 1986 | ...params, 1987 | }); 1988 | /** 1989 | * @description Get Repository returns information about the selected Repository. 1990 | * 1991 | * @name GetRepository 1992 | * @summary Get Repository 1993 | * @request GET:/api/v3/repositories/{repo-public-id} 1994 | * @secure 1995 | */ 1996 | getRepository = (repoPublicId: number, params: RequestParams = {}) => 1997 | this.request({ 1998 | path: `/api/v3/repositories/${repoPublicId}`, 1999 | method: "GET", 2000 | secure: true, 2001 | format: "json", 2002 | ...params, 2003 | }); 2004 | /** 2005 | * @description Search lets you search Epics and Stories based on desired parameters. Since ordering of the results can change over time (due to search ranking decay, new Epics and Stories being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2006 | * 2007 | * @name Search 2008 | * @summary Search 2009 | * @request GET:/api/v3/search 2010 | * @secure 2011 | */ 2012 | search = ( 2013 | query: { 2014 | /** 2015 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2016 | * @minLength 1 2017 | */ 2018 | query: string; 2019 | /** 2020 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2021 | * @format int64 2022 | */ 2023 | page_size?: number; 2024 | /** 2025 | * The amount of detail included in each result item. 2026 | * "full" will include all descriptions and comments and more fields on 2027 | * related items such as pull requests, branches and tasks. 2028 | * "slim" omits larger fulltext fields such as descriptions and comments 2029 | * and only references related items by id. 2030 | * The default is "full". 2031 | */ 2032 | detail?: "full" | "slim"; 2033 | /** The next page token. */ 2034 | next?: string; 2035 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2036 | entity_types?: ( 2037 | | "story" 2038 | | "milestone" 2039 | | "epic" 2040 | | "iteration" 2041 | | "objective" 2042 | )[]; 2043 | }, 2044 | params: RequestParams = {}, 2045 | ) => 2046 | this.request({ 2047 | path: `/api/v3/search`, 2048 | method: "GET", 2049 | query: query, 2050 | secure: true, 2051 | format: "json", 2052 | ...params, 2053 | }); 2054 | /** 2055 | * @description Search Epics lets you search Epics based on desired parameters. Since ordering of stories can change over time (due to search ranking decay, new Epics being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2056 | * 2057 | * @name SearchEpics 2058 | * @summary Search Epics 2059 | * @request GET:/api/v3/search/epics 2060 | * @secure 2061 | */ 2062 | searchEpics = ( 2063 | query: { 2064 | /** 2065 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2066 | * @minLength 1 2067 | */ 2068 | query: string; 2069 | /** 2070 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2071 | * @format int64 2072 | */ 2073 | page_size?: number; 2074 | /** 2075 | * The amount of detail included in each result item. 2076 | * "full" will include all descriptions and comments and more fields on 2077 | * related items such as pull requests, branches and tasks. 2078 | * "slim" omits larger fulltext fields such as descriptions and comments 2079 | * and only references related items by id. 2080 | * The default is "full". 2081 | */ 2082 | detail?: "full" | "slim"; 2083 | /** The next page token. */ 2084 | next?: string; 2085 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2086 | entity_types?: ( 2087 | | "story" 2088 | | "milestone" 2089 | | "epic" 2090 | | "iteration" 2091 | | "objective" 2092 | )[]; 2093 | }, 2094 | params: RequestParams = {}, 2095 | ) => 2096 | this.request({ 2097 | path: `/api/v3/search/epics`, 2098 | method: "GET", 2099 | query: query, 2100 | secure: true, 2101 | format: "json", 2102 | ...params, 2103 | }); 2104 | /** 2105 | * @description Search Iterations lets you search Iterations based on desired parameters. Since ordering of results can change over time (due to search ranking decay, new Iterations being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2106 | * 2107 | * @name SearchIterations 2108 | * @summary Search Iterations 2109 | * @request GET:/api/v3/search/iterations 2110 | * @secure 2111 | */ 2112 | searchIterations = ( 2113 | query: { 2114 | /** 2115 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2116 | * @minLength 1 2117 | */ 2118 | query: string; 2119 | /** 2120 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2121 | * @format int64 2122 | */ 2123 | page_size?: number; 2124 | /** 2125 | * The amount of detail included in each result item. 2126 | * "full" will include all descriptions and comments and more fields on 2127 | * related items such as pull requests, branches and tasks. 2128 | * "slim" omits larger fulltext fields such as descriptions and comments 2129 | * and only references related items by id. 2130 | * The default is "full". 2131 | */ 2132 | detail?: "full" | "slim"; 2133 | /** The next page token. */ 2134 | next?: string; 2135 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2136 | entity_types?: ( 2137 | | "story" 2138 | | "milestone" 2139 | | "epic" 2140 | | "iteration" 2141 | | "objective" 2142 | )[]; 2143 | }, 2144 | params: RequestParams = {}, 2145 | ) => 2146 | this.request({ 2147 | path: `/api/v3/search/iterations`, 2148 | method: "GET", 2149 | query: query, 2150 | secure: true, 2151 | format: "json", 2152 | ...params, 2153 | }); 2154 | /** 2155 | * @description Search Milestones lets you search Milestones based on desired parameters. Since ordering of results can change over time (due to search ranking decay, new Milestones being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2156 | * 2157 | * @name SearchMilestones 2158 | * @summary Search Milestones 2159 | * @request GET:/api/v3/search/milestones 2160 | * @secure 2161 | */ 2162 | searchMilestones = ( 2163 | query: { 2164 | /** 2165 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2166 | * @minLength 1 2167 | */ 2168 | query: string; 2169 | /** 2170 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2171 | * @format int64 2172 | */ 2173 | page_size?: number; 2174 | /** 2175 | * The amount of detail included in each result item. 2176 | * "full" will include all descriptions and comments and more fields on 2177 | * related items such as pull requests, branches and tasks. 2178 | * "slim" omits larger fulltext fields such as descriptions and comments 2179 | * and only references related items by id. 2180 | * The default is "full". 2181 | */ 2182 | detail?: "full" | "slim"; 2183 | /** The next page token. */ 2184 | next?: string; 2185 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2186 | entity_types?: ( 2187 | | "story" 2188 | | "milestone" 2189 | | "epic" 2190 | | "iteration" 2191 | | "objective" 2192 | )[]; 2193 | }, 2194 | params: RequestParams = {}, 2195 | ) => 2196 | this.request({ 2197 | path: `/api/v3/search/milestones`, 2198 | method: "GET", 2199 | query: query, 2200 | secure: true, 2201 | format: "json", 2202 | ...params, 2203 | }); 2204 | /** 2205 | * @description Search Objectives lets you search Objectives based on desired parameters. Since ordering of results can change over time (due to search ranking decay, new Objectives being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2206 | * 2207 | * @name SearchObjectives 2208 | * @summary Search Objectives 2209 | * @request GET:/api/v3/search/objectives 2210 | * @secure 2211 | */ 2212 | searchObjectives = ( 2213 | query: { 2214 | /** 2215 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2216 | * @minLength 1 2217 | */ 2218 | query: string; 2219 | /** 2220 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2221 | * @format int64 2222 | */ 2223 | page_size?: number; 2224 | /** 2225 | * The amount of detail included in each result item. 2226 | * "full" will include all descriptions and comments and more fields on 2227 | * related items such as pull requests, branches and tasks. 2228 | * "slim" omits larger fulltext fields such as descriptions and comments 2229 | * and only references related items by id. 2230 | * The default is "full". 2231 | */ 2232 | detail?: "full" | "slim"; 2233 | /** The next page token. */ 2234 | next?: string; 2235 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2236 | entity_types?: ( 2237 | | "story" 2238 | | "milestone" 2239 | | "epic" 2240 | | "iteration" 2241 | | "objective" 2242 | )[]; 2243 | }, 2244 | params: RequestParams = {}, 2245 | ) => 2246 | this.request({ 2247 | path: `/api/v3/search/objectives`, 2248 | method: "GET", 2249 | query: query, 2250 | secure: true, 2251 | format: "json", 2252 | ...params, 2253 | }); 2254 | /** 2255 | * @description Search Stories lets you search Stories based on desired parameters. Since ordering of stories can change over time (due to search ranking decay, new stories being created), the `next` value from the previous response can be used as the path and query string for the next page to ensure stable ordering. 2256 | * 2257 | * @name SearchStories 2258 | * @summary Search Stories 2259 | * @request GET:/api/v3/search/stories 2260 | * @secure 2261 | */ 2262 | searchStories = ( 2263 | query: { 2264 | /** 2265 | * See our help center article on [search operators](https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators) 2266 | * @minLength 1 2267 | */ 2268 | query: string; 2269 | /** 2270 | * The number of search results to include in a page. Minimum of 1 and maximum of 250. 2271 | * @format int64 2272 | */ 2273 | page_size?: number; 2274 | /** 2275 | * The amount of detail included in each result item. 2276 | * "full" will include all descriptions and comments and more fields on 2277 | * related items such as pull requests, branches and tasks. 2278 | * "slim" omits larger fulltext fields such as descriptions and comments 2279 | * and only references related items by id. 2280 | * The default is "full". 2281 | */ 2282 | detail?: "full" | "slim"; 2283 | /** The next page token. */ 2284 | next?: string; 2285 | /** A collection of entity_types to search. Defaults to story and epic. Supports: epic, iteration, objective, story. */ 2286 | entity_types?: ( 2287 | | "story" 2288 | | "milestone" 2289 | | "epic" 2290 | | "iteration" 2291 | | "objective" 2292 | )[]; 2293 | }, 2294 | params: RequestParams = {}, 2295 | ) => 2296 | this.request({ 2297 | path: `/api/v3/search/stories`, 2298 | method: "GET", 2299 | query: query, 2300 | secure: true, 2301 | format: "json", 2302 | ...params, 2303 | }); 2304 | /** 2305 | * @description Create Story is used to add a new story to your Shortcut Workspace. This endpoint requires that either **workflow_state_id** or **project_id** be provided, but will reject the request if both or neither are specified. The workflow_state_id has been marked as required and is the recommended field to specify because we are in the process of sunsetting Projects in Shortcut. 2306 | * 2307 | * @name CreateStory 2308 | * @summary Create Story 2309 | * @request POST:/api/v3/stories 2310 | * @secure 2311 | */ 2312 | createStory = ( 2313 | CreateStoryParams: CreateStoryParams, 2314 | params: RequestParams = {}, 2315 | ) => 2316 | this.request({ 2317 | path: `/api/v3/stories`, 2318 | method: "POST", 2319 | body: CreateStoryParams, 2320 | secure: true, 2321 | type: ContentType.Json, 2322 | format: "json", 2323 | ...params, 2324 | }); 2325 | /** 2326 | * @description Create Multiple Stories allows you to create multiple stories in a single request using the same syntax as [Create Story](https://developer.shortcut.com/api/rest/v3#create-story). 2327 | * 2328 | * @name CreateMultipleStories 2329 | * @summary Create Multiple Stories 2330 | * @request POST:/api/v3/stories/bulk 2331 | * @secure 2332 | */ 2333 | createMultipleStories = ( 2334 | CreateStories: CreateStories, 2335 | params: RequestParams = {}, 2336 | ) => 2337 | this.request({ 2338 | path: `/api/v3/stories/bulk`, 2339 | method: "POST", 2340 | body: CreateStories, 2341 | secure: true, 2342 | type: ContentType.Json, 2343 | format: "json", 2344 | ...params, 2345 | }); 2346 | /** 2347 | * @description Update Multiple Stories allows you to make changes to numerous stories at once. 2348 | * 2349 | * @name UpdateMultipleStories 2350 | * @summary Update Multiple Stories 2351 | * @request PUT:/api/v3/stories/bulk 2352 | * @secure 2353 | */ 2354 | updateMultipleStories = ( 2355 | UpdateStories: UpdateStories, 2356 | params: RequestParams = {}, 2357 | ) => 2358 | this.request({ 2359 | path: `/api/v3/stories/bulk`, 2360 | method: "PUT", 2361 | body: UpdateStories, 2362 | secure: true, 2363 | type: ContentType.Json, 2364 | format: "json", 2365 | ...params, 2366 | }); 2367 | /** 2368 | * @description Delete Multiple Stories allows you to delete multiple archived stories at once. 2369 | * 2370 | * @name DeleteMultipleStories 2371 | * @summary Delete Multiple Stories 2372 | * @request DELETE:/api/v3/stories/bulk 2373 | * @secure 2374 | */ 2375 | deleteMultipleStories = ( 2376 | DeleteStories: DeleteStories, 2377 | params: RequestParams = {}, 2378 | ) => 2379 | this.request({ 2380 | path: `/api/v3/stories/bulk`, 2381 | method: "DELETE", 2382 | body: DeleteStories, 2383 | secure: true, 2384 | type: ContentType.Json, 2385 | ...params, 2386 | }); 2387 | /** 2388 | * @description Create Story From Template is used to add a new story derived from a template to your Shortcut Workspace. 2389 | * 2390 | * @name CreateStoryFromTemplate 2391 | * @summary Create Story From Template 2392 | * @request POST:/api/v3/stories/from-template 2393 | * @secure 2394 | */ 2395 | createStoryFromTemplate = ( 2396 | CreateStoryFromTemplateParams: CreateStoryFromTemplateParams, 2397 | params: RequestParams = {}, 2398 | ) => 2399 | this.request({ 2400 | path: `/api/v3/stories/from-template`, 2401 | method: "POST", 2402 | body: CreateStoryFromTemplateParams, 2403 | secure: true, 2404 | type: ContentType.Json, 2405 | format: "json", 2406 | ...params, 2407 | }); 2408 | /** 2409 | * @description Search Stories lets you search Stories based on desired parameters. 2410 | * 2411 | * @name QueryStories 2412 | * @summary Query Stories 2413 | * @request POST:/api/v3/stories/search 2414 | * @secure 2415 | */ 2416 | queryStories = (SearchStories: SearchStories, params: RequestParams = {}) => 2417 | this.request({ 2418 | path: `/api/v3/stories/search`, 2419 | method: "POST", 2420 | body: SearchStories, 2421 | secure: true, 2422 | type: ContentType.Json, 2423 | format: "json", 2424 | ...params, 2425 | }); 2426 | /** 2427 | * @description Get Story returns information about a chosen Story. 2428 | * 2429 | * @name GetStory 2430 | * @summary Get Story 2431 | * @request GET:/api/v3/stories/{story-public-id} 2432 | * @secure 2433 | */ 2434 | getStory = (storyPublicId: number, params: RequestParams = {}) => 2435 | this.request({ 2436 | path: `/api/v3/stories/${storyPublicId}`, 2437 | method: "GET", 2438 | secure: true, 2439 | format: "json", 2440 | ...params, 2441 | }); 2442 | /** 2443 | * @description Update Story can be used to update Story properties. 2444 | * 2445 | * @name UpdateStory 2446 | * @summary Update Story 2447 | * @request PUT:/api/v3/stories/{story-public-id} 2448 | * @secure 2449 | */ 2450 | updateStory = ( 2451 | storyPublicId: number, 2452 | UpdateStory: UpdateStory, 2453 | params: RequestParams = {}, 2454 | ) => 2455 | this.request({ 2456 | path: `/api/v3/stories/${storyPublicId}`, 2457 | method: "PUT", 2458 | body: UpdateStory, 2459 | secure: true, 2460 | type: ContentType.Json, 2461 | format: "json", 2462 | ...params, 2463 | }); 2464 | /** 2465 | * @description Delete Story can be used to delete any Story. 2466 | * 2467 | * @name DeleteStory 2468 | * @summary Delete Story 2469 | * @request DELETE:/api/v3/stories/{story-public-id} 2470 | * @secure 2471 | */ 2472 | deleteStory = (storyPublicId: number, params: RequestParams = {}) => 2473 | this.request({ 2474 | path: `/api/v3/stories/${storyPublicId}`, 2475 | method: "DELETE", 2476 | secure: true, 2477 | ...params, 2478 | }); 2479 | /** 2480 | * @description Lists Comments associated with a Story 2481 | * 2482 | * @name ListStoryComment 2483 | * @summary List Story Comment 2484 | * @request GET:/api/v3/stories/{story-public-id}/comments 2485 | * @secure 2486 | */ 2487 | listStoryComment = (storyPublicId: number, params: RequestParams = {}) => 2488 | this.request({ 2489 | path: `/api/v3/stories/${storyPublicId}/comments`, 2490 | method: "GET", 2491 | secure: true, 2492 | format: "json", 2493 | ...params, 2494 | }); 2495 | /** 2496 | * @description Create Comment allows you to create a Comment on any Story. 2497 | * 2498 | * @name CreateStoryComment 2499 | * @summary Create Story Comment 2500 | * @request POST:/api/v3/stories/{story-public-id}/comments 2501 | * @secure 2502 | */ 2503 | createStoryComment = ( 2504 | storyPublicId: number, 2505 | CreateStoryComment: CreateStoryComment, 2506 | params: RequestParams = {}, 2507 | ) => 2508 | this.request({ 2509 | path: `/api/v3/stories/${storyPublicId}/comments`, 2510 | method: "POST", 2511 | body: CreateStoryComment, 2512 | secure: true, 2513 | type: ContentType.Json, 2514 | format: "json", 2515 | ...params, 2516 | }); 2517 | /** 2518 | * @description Get Comment is used to get Comment information. 2519 | * 2520 | * @name GetStoryComment 2521 | * @summary Get Story Comment 2522 | * @request GET:/api/v3/stories/{story-public-id}/comments/{comment-public-id} 2523 | * @secure 2524 | */ 2525 | getStoryComment = ( 2526 | storyPublicId: number, 2527 | commentPublicId: number, 2528 | params: RequestParams = {}, 2529 | ) => 2530 | this.request({ 2531 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}`, 2532 | method: "GET", 2533 | secure: true, 2534 | format: "json", 2535 | ...params, 2536 | }); 2537 | /** 2538 | * @description Update Comment replaces the text of the existing Comment. 2539 | * 2540 | * @name UpdateStoryComment 2541 | * @summary Update Story Comment 2542 | * @request PUT:/api/v3/stories/{story-public-id}/comments/{comment-public-id} 2543 | * @secure 2544 | */ 2545 | updateStoryComment = ( 2546 | storyPublicId: number, 2547 | commentPublicId: number, 2548 | UpdateStoryComment: UpdateStoryComment, 2549 | params: RequestParams = {}, 2550 | ) => 2551 | this.request({ 2552 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}`, 2553 | method: "PUT", 2554 | body: UpdateStoryComment, 2555 | secure: true, 2556 | type: ContentType.Json, 2557 | format: "json", 2558 | ...params, 2559 | }); 2560 | /** 2561 | * @description Delete a Comment from any story. 2562 | * 2563 | * @name DeleteStoryComment 2564 | * @summary Delete Story Comment 2565 | * @request DELETE:/api/v3/stories/{story-public-id}/comments/{comment-public-id} 2566 | * @secure 2567 | */ 2568 | deleteStoryComment = ( 2569 | storyPublicId: number, 2570 | commentPublicId: number, 2571 | params: RequestParams = {}, 2572 | ) => 2573 | this.request({ 2574 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}`, 2575 | method: "DELETE", 2576 | secure: true, 2577 | ...params, 2578 | }); 2579 | /** 2580 | * @description Create a reaction to a story comment. 2581 | * 2582 | * @name CreateStoryReaction 2583 | * @summary Create Story Reaction 2584 | * @request POST:/api/v3/stories/{story-public-id}/comments/{comment-public-id}/reactions 2585 | * @secure 2586 | */ 2587 | createStoryReaction = ( 2588 | storyPublicId: number, 2589 | commentPublicId: number, 2590 | CreateOrDeleteStoryReaction: CreateOrDeleteStoryReaction, 2591 | params: RequestParams = {}, 2592 | ) => 2593 | this.request({ 2594 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}/reactions`, 2595 | method: "POST", 2596 | body: CreateOrDeleteStoryReaction, 2597 | secure: true, 2598 | type: ContentType.Json, 2599 | format: "json", 2600 | ...params, 2601 | }); 2602 | /** 2603 | * @description Delete a reaction from any story comment. 2604 | * 2605 | * @name DeleteStoryReaction 2606 | * @summary Delete Story Reaction 2607 | * @request DELETE:/api/v3/stories/{story-public-id}/comments/{comment-public-id}/reactions 2608 | * @secure 2609 | */ 2610 | deleteStoryReaction = ( 2611 | storyPublicId: number, 2612 | commentPublicId: number, 2613 | CreateOrDeleteStoryReaction: CreateOrDeleteStoryReaction, 2614 | params: RequestParams = {}, 2615 | ) => 2616 | this.request({ 2617 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}/reactions`, 2618 | method: "DELETE", 2619 | body: CreateOrDeleteStoryReaction, 2620 | secure: true, 2621 | type: ContentType.Json, 2622 | ...params, 2623 | }); 2624 | /** 2625 | * @description Unlinks a Comment from its linked Slack thread (Comment replies and Slack replies will no longer be synced) 2626 | * 2627 | * @name UnlinkCommentThreadFromSlack 2628 | * @summary Unlink Comment thread from Slack 2629 | * @request POST:/api/v3/stories/{story-public-id}/comments/{comment-public-id}/unlink-from-slack 2630 | * @secure 2631 | */ 2632 | unlinkCommentThreadFromSlack = ( 2633 | storyPublicId: number, 2634 | commentPublicId: number, 2635 | params: RequestParams = {}, 2636 | ) => 2637 | this.request({ 2638 | path: `/api/v3/stories/${storyPublicId}/comments/${commentPublicId}/unlink-from-slack`, 2639 | method: "POST", 2640 | secure: true, 2641 | format: "json", 2642 | ...params, 2643 | }); 2644 | /** 2645 | * No description 2646 | * 2647 | * @name StoryHistory 2648 | * @summary Story History 2649 | * @request GET:/api/v3/stories/{story-public-id}/history 2650 | * @secure 2651 | */ 2652 | storyHistory = (storyPublicId: number, params: RequestParams = {}) => 2653 | this.request({ 2654 | path: `/api/v3/stories/${storyPublicId}/history`, 2655 | method: "GET", 2656 | secure: true, 2657 | format: "json", 2658 | ...params, 2659 | }); 2660 | /** 2661 | * @description List Story Sub tasks returns a list of all Sub-task Stories for a given parent Story. 2662 | * 2663 | * @name ListStorySubTasks 2664 | * @summary List Story Sub tasks 2665 | * @request GET:/api/v3/stories/{story-public-id}/sub-tasks 2666 | * @secure 2667 | */ 2668 | listStorySubTasks = (storyPublicId: number, params: RequestParams = {}) => 2669 | this.request({ 2670 | path: `/api/v3/stories/${storyPublicId}/sub-tasks`, 2671 | method: "GET", 2672 | secure: true, 2673 | format: "json", 2674 | ...params, 2675 | }); 2676 | /** 2677 | * @description Create Task is used to create a new task in a Story. 2678 | * 2679 | * @name CreateTask 2680 | * @summary Create Task 2681 | * @request POST:/api/v3/stories/{story-public-id}/tasks 2682 | * @secure 2683 | */ 2684 | createTask = ( 2685 | storyPublicId: number, 2686 | CreateTask: CreateTask, 2687 | params: RequestParams = {}, 2688 | ) => 2689 | this.request({ 2690 | path: `/api/v3/stories/${storyPublicId}/tasks`, 2691 | method: "POST", 2692 | body: CreateTask, 2693 | secure: true, 2694 | type: ContentType.Json, 2695 | format: "json", 2696 | ...params, 2697 | }); 2698 | /** 2699 | * @description Returns information about a chosen Task. 2700 | * 2701 | * @name GetTask 2702 | * @summary Get Task 2703 | * @request GET:/api/v3/stories/{story-public-id}/tasks/{task-public-id} 2704 | * @secure 2705 | */ 2706 | getTask = ( 2707 | storyPublicId: number, 2708 | taskPublicId: number, 2709 | params: RequestParams = {}, 2710 | ) => 2711 | this.request({ 2712 | path: `/api/v3/stories/${storyPublicId}/tasks/${taskPublicId}`, 2713 | method: "GET", 2714 | secure: true, 2715 | format: "json", 2716 | ...params, 2717 | }); 2718 | /** 2719 | * @description Update Task can be used to update Task properties. 2720 | * 2721 | * @name UpdateTask 2722 | * @summary Update Task 2723 | * @request PUT:/api/v3/stories/{story-public-id}/tasks/{task-public-id} 2724 | * @secure 2725 | */ 2726 | updateTask = ( 2727 | storyPublicId: number, 2728 | taskPublicId: number, 2729 | UpdateTask: UpdateTask, 2730 | params: RequestParams = {}, 2731 | ) => 2732 | this.request({ 2733 | path: `/api/v3/stories/${storyPublicId}/tasks/${taskPublicId}`, 2734 | method: "PUT", 2735 | body: UpdateTask, 2736 | secure: true, 2737 | type: ContentType.Json, 2738 | format: "json", 2739 | ...params, 2740 | }); 2741 | /** 2742 | * @description Delete Task can be used to delete any previously created Task on a Story. 2743 | * 2744 | * @name DeleteTask 2745 | * @summary Delete Task 2746 | * @request DELETE:/api/v3/stories/{story-public-id}/tasks/{task-public-id} 2747 | * @secure 2748 | */ 2749 | deleteTask = ( 2750 | storyPublicId: number, 2751 | taskPublicId: number, 2752 | params: RequestParams = {}, 2753 | ) => 2754 | this.request({ 2755 | path: `/api/v3/stories/${storyPublicId}/tasks/${taskPublicId}`, 2756 | method: "DELETE", 2757 | secure: true, 2758 | ...params, 2759 | }); 2760 | /** 2761 | * @description Story Links (called Story Relationships in the UI) allow you create semantic relationships between two stories. The parameters read like an active voice grammatical sentence: subject -> verb -> object. The subject story acts on the object Story; the object story is the direct object of the sentence. The subject story "blocks", "duplicates", or "relates to" the object story. Examples: - "story 5 blocks story 6” -- story 6 is now "blocked" until story 5 is moved to a Done workflow state. - "story 2 duplicates story 1” -- Story 2 represents the same body of work as Story 1 (and should probably be archived). - "story 7 relates to story 3” 2762 | * 2763 | * @name CreateStoryLink 2764 | * @summary Create Story Link 2765 | * @request POST:/api/v3/story-links 2766 | * @secure 2767 | */ 2768 | createStoryLink = ( 2769 | CreateStoryLink: CreateStoryLink, 2770 | params: RequestParams = {}, 2771 | ) => 2772 | this.request({ 2773 | path: `/api/v3/story-links`, 2774 | method: "POST", 2775 | body: CreateStoryLink, 2776 | secure: true, 2777 | type: ContentType.Json, 2778 | format: "json", 2779 | ...params, 2780 | }); 2781 | /** 2782 | * @description Returns the stories and their relationship for the given Story Link. 2783 | * 2784 | * @name GetStoryLink 2785 | * @summary Get Story Link 2786 | * @request GET:/api/v3/story-links/{story-link-public-id} 2787 | * @secure 2788 | */ 2789 | getStoryLink = (storyLinkPublicId: number, params: RequestParams = {}) => 2790 | this.request({ 2791 | path: `/api/v3/story-links/${storyLinkPublicId}`, 2792 | method: "GET", 2793 | secure: true, 2794 | format: "json", 2795 | ...params, 2796 | }); 2797 | /** 2798 | * @description Updates the stories and/or the relationship for the given Story Link. 2799 | * 2800 | * @name UpdateStoryLink 2801 | * @summary Update Story Link 2802 | * @request PUT:/api/v3/story-links/{story-link-public-id} 2803 | * @secure 2804 | */ 2805 | updateStoryLink = ( 2806 | storyLinkPublicId: number, 2807 | UpdateStoryLink: UpdateStoryLink, 2808 | params: RequestParams = {}, 2809 | ) => 2810 | this.request({ 2811 | path: `/api/v3/story-links/${storyLinkPublicId}`, 2812 | method: "PUT", 2813 | body: UpdateStoryLink, 2814 | secure: true, 2815 | type: ContentType.Json, 2816 | format: "json", 2817 | ...params, 2818 | }); 2819 | /** 2820 | * @description Removes the relationship between the stories for the given Story Link. 2821 | * 2822 | * @name DeleteStoryLink 2823 | * @summary Delete Story Link 2824 | * @request DELETE:/api/v3/story-links/{story-link-public-id} 2825 | * @secure 2826 | */ 2827 | deleteStoryLink = (storyLinkPublicId: number, params: RequestParams = {}) => 2828 | this.request({ 2829 | path: `/api/v3/story-links/${storyLinkPublicId}`, 2830 | method: "DELETE", 2831 | secure: true, 2832 | ...params, 2833 | }); 2834 | /** 2835 | * @description Returns a list of all Workflows in the Workspace. 2836 | * 2837 | * @name ListWorkflows 2838 | * @summary List Workflows 2839 | * @request GET:/api/v3/workflows 2840 | * @secure 2841 | */ 2842 | listWorkflows = (params: RequestParams = {}) => 2843 | this.request({ 2844 | path: `/api/v3/workflows`, 2845 | method: "GET", 2846 | secure: true, 2847 | format: "json", 2848 | ...params, 2849 | }); 2850 | /** 2851 | * @description Get Workflow returns information about a chosen Workflow. 2852 | * 2853 | * @name GetWorkflow 2854 | * @summary Get Workflow 2855 | * @request GET:/api/v3/workflows/{workflow-public-id} 2856 | * @secure 2857 | */ 2858 | getWorkflow = (workflowPublicId: number, params: RequestParams = {}) => 2859 | this.request({ 2860 | path: `/api/v3/workflows/${workflowPublicId}`, 2861 | method: "GET", 2862 | secure: true, 2863 | format: "json", 2864 | ...params, 2865 | }); 2866 | } 2867 | --------------------------------------------------------------------------------