diff --git a/package.json b/package.json index b7854ec20..3c5214035 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "lint:fix": "npm run lint:tests -- --fix && npm run lint:examples -- --fix && npm run lint:src:agile -- --fix && npm run lint:src:clients -- --fix && npm run lint:src:services -- --fix && npm run lint:src:version2 -- --fix && npm run lint:src:version3 -- --fix && npm run lint:src:serviceDesk -- --fix && npm run lint:src:files -- --fix", "doc": "typedoc --name \"Jira.js - Jira Cloud API library\" --out docs ./src/index.ts --favicon ./assets/favicon.svg", "test": "npm run test:unit && npm run test:integration", - "test:unit": "vitest run tests/unit --maxWorkers=8 --sequence.concurrent", + "test:unit": "vitest run tests/unit --minWorkers=1 --maxWorkers=8 --sequence.concurrent", "test:integration": "vitest run tests/integration --bail=1 --no-file-parallelism --max-concurrency 1 -c vitest.config.mts --hookTimeout 100000 --testTimeout 100000", "replace:all": "npm run replace:permissions:version2 && npm run replace:permissions:version3 && npm run replace:pagination:version2 && npm run replace:pagination:version3 && npm run replace:async:version2 && npm run replace:async:version3 && npm run replace:expansion:version2 && npm run replace:expansion:version3 && npm run replace:ordering:version2 && npm run replace:ordering:version3 && npm run replace:groupMember:version2 && npm run replace:workflowPaginated:version2 && npm run replace:attachment:serviceDesk && npm run replace:priority:version3 && npm run replace:projectAvatar:version3 && npm run replace:issueType:version3", "replace:permissions:version2": "grep -rl \"(#permissions)\" ./src/version2 | xargs sed -i '' 's/(#permissions)/(https:\\/\\/developer.atlassian.com\\/cloud\\/jira\\/platform\\/rest\\/v2\\/intro\\/#permissions)/g'", diff --git a/src/version2/issueSearch.ts b/src/version2/issueSearch.ts index 664ffb6a9..54276f6b9 100644 --- a/src/version2/issueSearch.ts +++ b/src/version2/issueSearch.ts @@ -231,4 +231,144 @@ export class IssueSearch { return this.client.sendRequest(config, callback); } + + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). Recent updates might not be immediately + * visible in the returned search results. + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * If the JQL query expression is too large to be encoded as a query parameter, use the + * [POST](#searchforissuesusingjqlenhancedsearchpost) version of this resource. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearch( + parameters: Parameters.SearchForIssuesUsingJqlEnhancedSearch | undefined, + callback: Callback, + ): Promise; + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). Recent updates might not be immediately + * visible in the returned search results. + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * If the JQL query expression is too large to be encoded as a query parameter, use the + * [POST](#searchforissuesusingjqlenhancedsearchpost) version of this resource. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearch( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearch, + callback?: never, + ): Promise; + async searchForIssuesUsingJqlEnhancedSearch( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearch, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/2/search/jql', + method: 'GET', + params: { + jql: parameters?.jql, + nextPageToken: parameters?.nextPageToken, + maxResults: parameters?.maxResults, + fields: parameters?.fields, + expand: parameters?.expand, + properties: parameters?.properties, + fieldsByKeys: parameters?.fieldsByKeys, + failFast: parameters?.failFast, + reconcileIssues: parameters?.reconcileIssues, + }, + }; + + return this.client.sendRequest(config, callback); + } + + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * There is a [GET](#searchforissuesusingjqlenhancedsearch) version of this resource that can be used for smaller JQL query + * expressions. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost | undefined, + callback: Callback, + ): Promise; + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * There is a [GET](#searchforissuesusingjqlenhancedsearch) version of this resource that can be used for smaller JQL query + * expressions. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost, + callback?: never, + ): Promise; + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/2/search', + method: 'POST', + data: { + jql: parameters?.jql, + nextPageToken: parameters?.nextPageToken, + maxResults: parameters?.maxResults, + fields: parameters?.fields, + expand: parameters?.expand, + properties: parameters?.properties, + fieldsByKeys: parameters?.fieldsByKeys, + failFast: parameters?.failFast, + reconcileIssues: parameters?.reconcileIssues, + }, + }; + + return this.client.sendRequest(config, callback); + } } diff --git a/src/version2/jiraExpressions.ts b/src/version2/jiraExpressions.ts index 6301ebaa4..2c71ee4ef 100644 --- a/src/version2/jiraExpressions.ts +++ b/src/version2/jiraExpressions.ts @@ -190,4 +190,149 @@ export class JiraExpressions { return this.client.sendRequest(config, callback); } + + /** + * Evaluates a Jira expression and returns its value. The difference between this and `eval` is that this endpoint + * uses the enhanced search API when evaluating JQL queries. This API is eventually consistent, unlike the strongly + * consistent `eval` API. This allows for better performance and scalability. In addition, this API's response for + * JQL evaluation is based on a scrolling view (backed by a `nextPageToken`) instead of a paginated view + * (backed by `startAt` and `totalCount`). + * + * This resource can be used to test Jira expressions that you plan to use elsewhere, or to fetch data in a flexible + * way. Consult the [Jira expressions + * documentation](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/) for more details. + * + * #### Context variables + * + * The following context variables are available to Jira expressions evaluated by this resource. Their presence + * depends on various factors; usually you need to manually request them in the context object sent in the payload, + * but some of them are added automatically under certain conditions. + * + * - `user` ([User](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user)): The + * current user. Always available and equal to `null` if the request is anonymous. + * - `app` ([App](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#app)): The + * [Connect app](https://developer.atlassian.com/cloud/jira/platform/index/#connect-apps) that made the request. + * Available only for authenticated requests made by Connect Apps (read more here: [Authentication for Connect + * apps](https://developer.atlassian.com/cloud/jira/platform/security-for-connect-apps/)). + * - `issue` ([Issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): The + * current issue. Available only when the issue is provided in the request context object. + * - `issues` ([List](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#list) of + * [Issues](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): A + * collection of issues matching a JQL query. Available only when JQL is provided in the request context object. + * - `project` ([Project](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#project)): + * The current project. Available only when the project is provided in the request context object. + * - `sprint` ([Sprint](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#sprint)): + * The current sprint. Available only when the sprint is provided in the request context object. + * - `board` ([Board](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#board)): The + * current board. Available only when the board is provided in the request context object. + * - `serviceDesk` + * ([ServiceDesk](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#servicedesk)): + * The current service desk. Available only when the service desk is provided in the request context object. + * - `customerRequest` + * ([CustomerRequest](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#customerrequest)): + * The current customer request. Available only when the customer request is provided in the request context + * object. + * + * In addition, you can pass custom context variables along with their types. You can then access them from + * the Jira expression by key. You can use the following variables in a custom context: + * + * - `user`: A [user](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user) + * specified as an Atlassian account ID. + * - `issue`: An [issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue) + * specified by ID or key. All the fields of the issue object are available in the Jira expression. + * - `json`: A JSON object containing custom content. + * - `list`: A JSON list of `user`, `issue`, or `json` variable types. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required**: None. + * However, an expression may return different results for different users depending on their permissions. For + * example, different users may see different comments on the same issue. Permission to access Jira Software is + * required to access Jira Software context variables (`board` and `sprint`) or fields (for example, `issue.sprint`). + */ + async evaluateJiraExpressionUsingEnhancedSearch( + parameters: Parameters.EvaluateJiraExpressionUsingEnhancedSearch | undefined, + callback: Callback, + ): Promise; + /** + * Evaluates a Jira expression and returns its value. The difference between this and `eval` is that this endpoint + * uses the enhanced search API when evaluating JQL queries. This API is eventually consistent, unlike the strongly + * consistent `eval` API. This allows for better performance and scalability. In addition, this API's response for + * JQL evaluation is based on a scrolling view (backed by a `nextPageToken`) instead of a paginated view + * (backed by `startAt` and `totalCount`). + * + * This resource can be used to test Jira expressions that you plan to use elsewhere, or to fetch data in a flexible + * way. Consult the [Jira expressions + * documentation](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/) for more details. + * + * #### Context variables + * + * The following context variables are available to Jira expressions evaluated by this resource. Their presence + * depends on various factors; usually you need to manually request them in the context object sent in the payload, + * but some of them are added automatically under certain conditions. + * + * - `user` ([User](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user)): The + * current user. Always available and equal to `null` if the request is anonymous. + * - `app` ([App](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#app)): The + * [Connect app](https://developer.atlassian.com/cloud/jira/platform/index/#connect-apps) that made the request. + * Available only for authenticated requests made by Connect Apps (read more here: [Authentication for Connect + * apps](https://developer.atlassian.com/cloud/jira/platform/security-for-connect-apps/)). + * - `issue` ([Issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): The + * current issue. Available only when the issue is provided in the request context object. + * - `issues` ([List](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#list) of + * [Issues](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): A + * collection of issues matching a JQL query. Available only when JQL is provided in the request context object. + * - `project` ([Project](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#project)): + * The current project. Available only when the project is provided in the request context object. + * - `sprint` ([Sprint](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#sprint)): + * The current sprint. Available only when the sprint is provided in the request context object. + * - `board` ([Board](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#board)): The + * current board. Available only when the board is provided in the request context object. + * - `serviceDesk` + * ([ServiceDesk](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#servicedesk)): + * The current service desk. Available only when the service desk is provided in the request context object. + * - `customerRequest` + * ([CustomerRequest](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#customerrequest)): + * The current customer request. Available only when the customer request is provided in the request context + * object. + * + * In addition, you can pass custom context variables along with their types. You can then access them from + * the Jira expression by key. You can use the following variables in a custom context: + * + * - `user`: A [user](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user) + * specified as an Atlassian account ID. + * - `issue`: An [issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue) + * specified by ID or key. All the fields of the issue object are available in the Jira expression. + * - `json`: A JSON object containing custom content. + * - `list`: A JSON list of `user`, `issue`, or `json` variable types. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#permissions) required**: None. + * However, an expression may return different results for different users depending on their permissions. For + * example, different users may see different comments on the same issue. Permission to access Jira Software is + * required to access Jira Software context variables (`board` and `sprint`) or fields (for example, `issue.sprint`). + */ + async evaluateJiraExpressionUsingEnhancedSearch( + parameters?: Parameters.EvaluateJiraExpressionUsingEnhancedSearch, + callback?: never, + ): Promise; + async evaluateJiraExpressionUsingEnhancedSearch( + parameters?: Parameters.EvaluateJiraExpressionUsingEnhancedSearch, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/2/expression/evaluate', + method: 'POST', + params: { + expand: parameters?.expand, + }, + data: { + expression: parameters?.expression, + context: parameters?.context, + }, + }; + + return this.client.sendRequest(config, callback); + } } diff --git a/src/version2/models/enhancedSearchRequest.ts b/src/version2/models/enhancedSearchRequest.ts new file mode 100644 index 000000000..401bf2b7b --- /dev/null +++ b/src/version2/models/enhancedSearchRequest.ts @@ -0,0 +1,100 @@ +export interface EnhancedSearchRequest { + /** + * The [JQL](https://confluence.atlassian.com/x/egORLQ) expression. + * For performance reasons, this parameter requires a bounded query. A bounded query is a query with a search restriction. + * - Example of an unbounded query: `order by key desc`. + * - Example of a bounded query: `assignee = currentUser() order by key`. + * + * Additionally, `orderBy` clause can contain a maximum of 7 fields. + */ + jql?: string; + /** + * The token for a page to fetch that is not the first page. The first page has a `nextPageToken` of `null`. + * Use the `nextPageToken` to fetch the next page of issues. + */ + nextPageToken?: string; + /** + * The maximum number of items to return per page. To manage page size, API may return fewer items per page where a + * large number of fields are requested. The greatest number of items returned per page is achieved when requesting + * `id` or `key` only. + * + * It returns max 5000 issues. + * + * Default: `50` + * + * Format: `int32` + */ + maxResults?: number; + /** + * A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a + * comma-separated list. Expand options include: + * + * - `*all` Returns all fields. + * - `*navigable` Returns navigable fields. + * - `id` Returns only issue IDs. + * - Any issue field, prefixed with a minus to exclude. + * + * The default is `id`. + * + * Examples: + * + * - `summary,comment` Returns only the summary and comments fields. + * - `-description` Returns all navigable (default) fields except description. + * - `*all,-comment` Returns all fields except comments. + * + * Multiple `fields` parameters can be included in a request. + * + * Note: By default, this resource returns IDs only. This differs from + * [GET issue](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get) + * where the default is all fields. + */ + fields?: string[]; + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#expansion) to include additional + * information about issues in the response. Note that, unlike the majority of instances where `expand` is specified, + * `expand` is defined as a comma-delimited string of values. The expand options are: + * + * - `renderedFields` Returns field values rendered in HTML format. + * - `names` Returns the display name of each field. + * - `schema` Returns the schema describing a field type. + * - `transitions` Returns all possible transitions for the issue. + * - `operations` Returns all possible operations for the issue. + * - `editmeta` Returns information about how each field can be edited. + * - `changelog` Returns a list of recent updates to an issue, sorted by date, starting from the most recent. + * - `versionedRepresentations` Instead of `fields`, returns `versionedRepresentations` a JSON array containing each + * version of a field's value, with the highest numbered item representing the most recent version. + * + * Examples: `names,changelog` Returns the display name of each field as well as a list of recent updates to an issue. + */ + expand?: + | 'renderedFields' + | 'names' + | 'schema' + | 'transitions' + | 'operations' + | 'editmeta' + | 'changelog' + | 'versionedRepresentations' + | ( + | 'renderedFields' + | 'names' + | 'schema' + | 'transitions' + | 'operations' + | 'editmeta' + | 'changelog' + | 'versionedRepresentations' + )[] + | string + | string[]; + /** + * A list of up to 5 issue properties to include in the results. This parameter accepts a comma-separated list. + */ + properties?: string[]; + /** Reference fields by their key (rather than ID). The default is `false`. */ + fieldsByKeys?: boolean; + /** Fail this request early if we can't retrieve all field data. The default is `false`. */ + failFast?: boolean; + /** Strong consistency issue ids to be reconciled with search results. Accepts max 50 ids. All issues must exist. */ + reconcileIssues?: number[]; +} diff --git a/src/version2/models/index.ts b/src/version2/models/index.ts index 63f87a220..e4f98681c 100644 --- a/src/version2/models/index.ts +++ b/src/version2/models/index.ts @@ -114,6 +114,7 @@ export * from './defaultLevelValue'; export * from './defaultShareScope'; export * from './defaultWorkflow'; export * from './documentVersion'; +export * from './enhancedSearchRequest'; export * from './entityProperty'; export * from './entityPropertyDetails'; export * from './error'; @@ -165,6 +166,7 @@ export * from './issue'; export * from './issueArchivalSync'; export * from './issueChangelogIds'; export * from './issueCommentListRequest'; +export * from './issueContextVariable'; export * from './issueCreateMetadata'; export * from './issueEntityProperties'; export * from './issueEntityPropertiesForMultiUpdate'; @@ -219,6 +221,13 @@ export * from './issueTypeWithStatus'; export * from './issueTypeWorkflowMapping'; export * from './issueUpdateDetails'; export * from './issueUpdateMetadata'; +export * from './jexpEvaluateCtxIssues'; +export * from './jexpEvaluateCtxJqlIssues'; +export * from './jExpEvaluateIssuesJqlMetaData'; +export * from './jExpEvaluateIssuesMeta'; +export * from './jExpEvaluateJiraExpressionResult'; +export * from './jExpEvaluateMetaData'; +export * from './jiraExpressionEvaluateContext'; export * from './jexpIssues'; export * from './jexpJqlIssues'; export * from './jiraExpressionAnalysis'; @@ -226,6 +235,7 @@ export * from './jiraExpressionComplexity'; export * from './jiraExpressionEvalContext'; export * from './jiraExpressionEvalRequest'; export * from './jiraExpressionEvaluationMetaData'; +export * from './jiraExpressionEvalUsingEnhancedSearchRequest'; export * from './jiraExpressionForAnalysis'; export * from './jiraExpressionResult'; export * from './jiraExpressionsAnalysis'; @@ -250,6 +260,7 @@ export * from './jqlQueryOrderByClauseElement'; export * from './jqlQueryToSanitize'; export * from './jQLQueryWithUnknownUsers'; export * from './jQLReferenceData'; +export * from './jsonContextVariable'; export * from './jsonType'; export * from './license'; export * from './licensedApplication'; @@ -410,6 +421,7 @@ export * from './screenSchemeDetails'; export * from './screenSchemeId'; export * from './screenTypes'; export * from './screenWithTab'; +export * from './searchAndReconcileResults'; export * from './searchAutoComplete'; export * from './searchRequest'; export * from './searchResults'; @@ -476,6 +488,7 @@ export * from './updateUiModificationDetails'; export * from './updateUserToGroup'; export * from './user'; export * from './userAvatarUrls'; +export * from './userContextVariable'; export * from './userDetails'; export * from './userKey'; export * from './userList'; diff --git a/src/version2/models/issueContextVariable.ts b/src/version2/models/issueContextVariable.ts new file mode 100644 index 000000000..5307834f7 --- /dev/null +++ b/src/version2/models/issueContextVariable.ts @@ -0,0 +1,8 @@ +export interface IssueContextVariable { + /** The issue ID. */ + id?: number; + /** The issue key. */ + key?: string; + /** Type of custom context variable. */ + type: string; +} diff --git a/src/version2/models/jExpEvaluateIssuesJqlMetaData.ts b/src/version2/models/jExpEvaluateIssuesJqlMetaData.ts new file mode 100644 index 000000000..c97480a3e --- /dev/null +++ b/src/version2/models/jExpEvaluateIssuesJqlMetaData.ts @@ -0,0 +1,5 @@ +/** The description of the page of issues loaded by the provided JQL query. */ +export interface JExpEvaluateIssuesJqlMetaData { + /** Next Page token for the next page of issues. */ + nextPageToken?: string; +} diff --git a/src/version2/models/jExpEvaluateIssuesMeta.ts b/src/version2/models/jExpEvaluateIssuesMeta.ts new file mode 100644 index 000000000..18f849055 --- /dev/null +++ b/src/version2/models/jExpEvaluateIssuesMeta.ts @@ -0,0 +1,10 @@ +import { JExpEvaluateIssuesJqlMetaData } from './jExpEvaluateIssuesJqlMetaData'; + +/** Meta data describing the `issues` context variable. */ +export interface JExpEvaluateIssuesMeta { + /** + * The description of the page of issues loaded by the provided JQL query. + * This bean will be replacing IssuesJqlMetaDataBean bean as part of new `evaluate` endpoint + */ + jql?: JExpEvaluateIssuesJqlMetaData; +} diff --git a/src/version2/models/jExpEvaluateJiraExpressionResult.ts b/src/version2/models/jExpEvaluateJiraExpressionResult.ts new file mode 100644 index 000000000..2e449dcd9 --- /dev/null +++ b/src/version2/models/jExpEvaluateJiraExpressionResult.ts @@ -0,0 +1,13 @@ +import { JExpEvaluateMetaData } from './jExpEvaluateMetaData'; + +/** The result of evaluating a Jira expression. */ +export interface JExpEvaluateJiraExpressionResult { + /** + * The value of the evaluated expression. It may be a primitive JSON value or a Jira REST API object. (Some + * expressions do not produce any meaningful results—for example, an expression that returns a lambda function—if + * that's the case a simple string representation is returned. These string representations should not be relied upon + * and may change without notice.) + */ + value: any; + meta?: JExpEvaluateMetaData; +} diff --git a/src/version2/models/jExpEvaluateMetaData.ts b/src/version2/models/jExpEvaluateMetaData.ts new file mode 100644 index 000000000..ac7fec3ec --- /dev/null +++ b/src/version2/models/jExpEvaluateMetaData.ts @@ -0,0 +1,15 @@ +import { JExpEvaluateIssuesMeta } from './jExpEvaluateIssuesMeta'; +import { JiraExpressionsComplexity } from './jiraExpressionsComplexity'; + +export interface JExpEvaluateMetaData { + /** + * Contains information about the expression complexity. For example, the number of steps it took to + * evaluate the expression. + */ + complexity?: JiraExpressionsComplexity; + /** + * Contains information about the `issues` variable in the context. For example, is the issues were loaded + * with JQL, information about the page will be included here. + */ + issues?: JExpEvaluateIssuesMeta; +} diff --git a/src/version2/models/jexpEvaluateCtxIssues.ts b/src/version2/models/jexpEvaluateCtxIssues.ts new file mode 100644 index 000000000..9c5d3b449 --- /dev/null +++ b/src/version2/models/jexpEvaluateCtxIssues.ts @@ -0,0 +1,6 @@ +import { JexpEvaluateCtxJqlIssues } from './jexpEvaluateCtxJqlIssues'; + +/** The JQL specifying the issues available in the evaluated Jira expression under the `issues` context variable. */ +export interface JexpEvaluateCtxIssues { + jql?: JexpEvaluateCtxJqlIssues; +} diff --git a/src/version2/models/jexpEvaluateCtxJqlIssues.ts b/src/version2/models/jexpEvaluateCtxJqlIssues.ts new file mode 100644 index 000000000..35d7ace75 --- /dev/null +++ b/src/version2/models/jexpEvaluateCtxJqlIssues.ts @@ -0,0 +1,17 @@ +/** + * The JQL query that specifies the set of issues available in the Jira expression. + */ +export interface JexpEvaluateCtxJqlIssues { + /** + * The maximum number of issues to return from the JQL query. Inspect `meta.issues.jql.maxResults` in the response to + * ensure the maximum value has not been exceeded. + */ + maxResults?: number; + /** + * The token for a page to fetch that is not the first page. The first page has a `nextPageToken` of `null`. + * Use the `nextPageToken` to fetch the next page of issues. + */ + nextPageToken?: string; + /** The JQL query, required to be bounded. Additionally, `orderBy` clause can contain a maximum of 7 fields */ + query?: string; +} diff --git a/src/version2/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts b/src/version2/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts new file mode 100644 index 000000000..f8a07cffb --- /dev/null +++ b/src/version2/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts @@ -0,0 +1,8 @@ +import { JiraExpressionEvaluateContext } from './jiraExpressionEvaluateContext'; + +export interface JiraExpressionEvalUsingEnhancedSearchRequest { + /** The Jira expression to evaluate. */ + expression: string; + /** The context in which the Jira expression is evaluated. */ + context?: JiraExpressionEvaluateContext; +} diff --git a/src/version2/models/jiraExpressionEvaluateContext.ts b/src/version2/models/jiraExpressionEvaluateContext.ts new file mode 100644 index 000000000..68322e2bf --- /dev/null +++ b/src/version2/models/jiraExpressionEvaluateContext.ts @@ -0,0 +1,37 @@ +import { IssueContextVariable } from './issueContextVariable'; +import { JsonContextVariable } from './jsonContextVariable'; +import { UserContextVariable } from './userContextVariable'; +import { IdOrKey } from './idOrKey'; +import { JexpEvaluateCtxIssues } from './jexpEvaluateCtxIssues'; + +export interface JiraExpressionEvaluateContext { + issue?: IdOrKey; + issues?: JexpEvaluateCtxIssues; + project?: IdOrKey; + /** The ID of the sprint that is available under the `sprint` variable when evaluating the expression. */ + sprint?: number; + /** The ID of the board that is available under the `board` variable when evaluating the expression. */ + board?: number; + /** The ID of the service desk that is available under the `serviceDesk` variable when evaluating the expression. */ + serviceDesk?: number; + /** + * The ID of the customer request that is available under the `customerRequest` variable when evaluating the + * expression. This is the same as the ID of the underlying Jira issue, but the customer request context variable will + * have a different type. + */ + customerRequest?: number; + /** + * Custom context variables and their types. These variable types are available for use in a custom context: + * + * `user`: A [user](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user) + * specified as an Atlassian account ID. `issue`: An + * [issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue) specified by ID + * or key. All the fields of the issue object are available in the Jira expression. `json`: A JSON object containing + * custom content. `list`: A JSON list of `user`, `issue`, or `json` variable types. + */ + custom?: ( + | UserContextVariable + | IssueContextVariable + | JsonContextVariable + )[]; +} diff --git a/src/version2/models/jsonContextVariable.ts b/src/version2/models/jsonContextVariable.ts new file mode 100644 index 000000000..c57466c38 --- /dev/null +++ b/src/version2/models/jsonContextVariable.ts @@ -0,0 +1,6 @@ +export interface JsonContextVariable { + /** Type of custom context variable. */ + type: string; + /** A JSON object containing custom content. */ + value?: any; +} diff --git a/src/version2/models/searchAndReconcileResults.ts b/src/version2/models/searchAndReconcileResults.ts new file mode 100644 index 000000000..0a650df61 --- /dev/null +++ b/src/version2/models/searchAndReconcileResults.ts @@ -0,0 +1,17 @@ +import { Issue } from './issue'; + +/** The result of a JQL search. */ +export interface SearchAndReconcileResults { + /** The list of issues found by the search or reconsiliation. */ + issues?: Issue[]; + /** The ID and name of each field in the search results. */ + names?: {}; + /** + * Continuation token to fetch the next page. + * If this result represents the last or the only page this token will be null. + * This token will expire in 7 days. + */ + nextPageToken?: string; + /** The schema describing the field types in the search results. */ + schema?: {}; +} diff --git a/src/version2/models/userContextVariable.ts b/src/version2/models/userContextVariable.ts new file mode 100644 index 000000000..3db08c961 --- /dev/null +++ b/src/version2/models/userContextVariable.ts @@ -0,0 +1,6 @@ +export interface UserContextVariable { + /** The account ID of the user. */ + accountId: string; + /** Type of custom context variable. */ + type: string; +} diff --git a/src/version2/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts b/src/version2/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts new file mode 100644 index 000000000..299ff4d94 --- /dev/null +++ b/src/version2/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts @@ -0,0 +1,13 @@ +import { JiraExpressionEvalUsingEnhancedSearchRequest } from '../models'; + +export interface EvaluateJiraExpressionUsingEnhancedSearch extends JiraExpressionEvalUsingEnhancedSearchRequest { + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#expansion) to include additional + * information in the response. This parameter accepts `meta.complexity` that returns information about the expression + * complexity. For example, the number of expensive operations used by the expression and how close the expression is + * to reaching the [complexity + * limit](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#restrictions). Useful when designing + * and debugging your expressions. + */ + expand?: string; +} diff --git a/src/version2/parameters/index.ts b/src/version2/parameters/index.ts index a008d2208..cb9dbe024 100644 --- a/src/version2/parameters/index.ts +++ b/src/version2/parameters/index.ts @@ -141,6 +141,7 @@ export * from './deleteWorklogProperty'; export * from './doTransition'; export * from './editIssue'; export * from './evaluateJiraExpression'; +export * from './evaluateJiraExpressionUsingEnhancedSearch'; export * from './expandAttachmentForHumans'; export * from './expandAttachmentForMachines'; export * from './exportArchivedIssues'; @@ -379,6 +380,8 @@ export * from './restoreCustomField'; export * from './sanitiseJqlQueries'; export * from './search'; export * from './searchForIssuesUsingJql'; +export * from './searchForIssuesUsingJqlEnhancedSearch'; +export * from './searchForIssuesUsingJqlEnhancedSearchPost'; export * from './searchForIssuesUsingJqlPost'; export * from './searchPriorities'; export * from './searchProjects'; diff --git a/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearch.ts b/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearch.ts new file mode 100644 index 000000000..b22d25cf8 --- /dev/null +++ b/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearch.ts @@ -0,0 +1,80 @@ +export interface SearchForIssuesUsingJqlEnhancedSearch { + /** + * The [JQL](https://confluence.atlassian.com/x/egORLQ) expression. + * For performance reasons, this parameter requires a bounded query. A bounded query is a query with a search restriction. + * - Example of an unbounded query: `order by key desc`. + * - Example of a bounded query: `assignee = currentUser() order by key`. + * + * Additionally, `orderBy` clause can contain a maximum of 7 fields. + */ + jql?: string; + /** + * The token for a page to fetch that is not the first page. The first page has a `nextPageToken` of `null`. + * Use the `nextPageToken` to fetch the next page of issues. + */ + nextPageToken?: string; + /** + * The maximum number of items to return per page. To manage page size, API may return fewer items per page where a + * large number of fields are requested. The greatest number of items returned per page is achieved when requesting + * `id` or `key` only. + * + * It returns max 5000 issues. + * + * Default: `50` + * + * Format: `int32` + */ + maxResults?: number; + /** + * A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a + * comma-separated list. Expand options include: + * + * - `*all` Returns all fields. + * - `*navigable` Returns navigable fields. + * - `id` Returns only issue IDs. + * - Any issue field, prefixed with a minus to exclude. + * + * The default is `id`. + * + * Examples: + * + * - `summary,comment` Returns only the summary and comments fields. + * - `-description` Returns all navigable (default) fields except description. + * - `*all,-comment` Returns all fields except comments. + * + * Multiple `fields` parameters can be included in a request. + * + * Note: By default, this resource returns IDs only. This differs from + * [GET issue](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get) + * where the default is all fields. + */ + fields?: string[]; + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#expansion) to include additional + * information about issues in the response. Note that, unlike the majority of instances where `expand` is specified, + * `expand` is defined as a comma-delimited string of values. The expand options are: + * + * - `renderedFields` Returns field values rendered in HTML format. + * - `names` Returns the display name of each field. + * - `schema` Returns the schema describing a field type. + * - `transitions` Returns all possible transitions for the issue. + * - `operations` Returns all possible operations for the issue. + * - `editmeta` Returns information about how each field can be edited. + * - `changelog` Returns a list of recent updates to an issue, sorted by date, starting from the most recent. + * - `versionedRepresentations` Instead of `fields`, returns `versionedRepresentations` a JSON array containing each + * version of a field's value, with the highest numbered item representing the most recent version. + * + * Examples: `names,changelog` Returns the display name of each field as well as a list of recent updates to an issue. + */ + expand?: string; + /** + * A list of up to 5 issue properties to include in the results. This parameter accepts a comma-separated list. + */ + properties?: string[]; + /** Reference fields by their key (rather than ID). The default is `false`. */ + fieldsByKeys?: boolean; + /** Fail this request early if we can't retrieve all field data. The default is `false`. */ + failFast?: boolean; + /** Strong consistency issue ids to be reconciled with search results. Accepts max 50 ids. All issues must exist. */ + reconcileIssues?: number[]; +} diff --git a/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts b/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts new file mode 100644 index 000000000..f00326bc8 --- /dev/null +++ b/src/version2/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts @@ -0,0 +1,3 @@ +import { EnhancedSearchRequest } from '../models'; + +export interface SearchForIssuesUsingJqlEnhancedSearchPost extends EnhancedSearchRequest {} diff --git a/src/version3/issueSearch.ts b/src/version3/issueSearch.ts index 4b7ebd263..68c647da0 100644 --- a/src/version3/issueSearch.ts +++ b/src/version3/issueSearch.ts @@ -462,4 +462,144 @@ export class IssueSearch { return this.client.sendRequest(config, callback); } + + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). Recent updates might not be immediately + * visible in the returned search results. + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * If the JQL query expression is too large to be encoded as a query parameter, use the + * [POST](#searchforissuesusingjqlenhancedsearchpost) version of this resource. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearch( + parameters: Parameters.SearchForIssuesUsingJqlEnhancedSearch | undefined, + callback: Callback, + ): Promise; + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). Recent updates might not be immediately + * visible in the returned search results. + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * If the JQL query expression is too large to be encoded as a query parameter, use the + * [POST](#searchforissuesusingjqlenhancedsearchpost) version of this resource. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearch( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearch, + callback?: never, + ): Promise; + async searchForIssuesUsingJqlEnhancedSearch( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearch, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/3/search/jql', + method: 'GET', + params: { + jql: parameters?.jql, + nextPageToken: parameters?.nextPageToken, + maxResults: parameters?.maxResults, + fields: parameters?.fields, + expand: parameters?.expand, + properties: parameters?.properties, + fieldsByKeys: parameters?.fieldsByKeys, + failFast: parameters?.failFast, + reconcileIssues: parameters?.reconcileIssues, + }, + }; + + return this.client.sendRequest(config, callback); + } + + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * There is a [GET](#searchforissuesusingjqlenhancedsearch) version of this resource that can be used for smaller JQL query + * expressions. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost | undefined, + callback: Callback, + ): Promise; + /** + * Searches for issues using [JQL](https://confluence.atlassian.com/x/egORLQ). + * + * If you need [read-after-write](https://developer.atlassian.com/cloud/jira/platform/search-and-reconcile/) consistency, + * you can utilize the `reconcileIssues` parameter to ensure stronger consistency assurances. + * + * There is a [GET](#searchforissuesusingjqlenhancedsearch) version of this resource that can be used for smaller JQL query + * expressions. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required:** Issues + * are included in the response where the user has: + * + * - _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) for the project containing the + * issue. + * - If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission + * to view the issue. + */ + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost, + callback?: never, + ): Promise; + async searchForIssuesUsingJqlEnhancedSearchPost( + parameters?: Parameters.SearchForIssuesUsingJqlEnhancedSearchPost, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/3/search', + method: 'POST', + data: { + jql: parameters?.jql, + nextPageToken: parameters?.nextPageToken, + maxResults: parameters?.maxResults, + fields: parameters?.fields, + expand: parameters?.expand, + properties: parameters?.properties, + fieldsByKeys: parameters?.fieldsByKeys, + failFast: parameters?.failFast, + reconcileIssues: parameters?.reconcileIssues, + }, + }; + + return this.client.sendRequest(config, callback); + } } diff --git a/src/version3/jiraExpressions.ts b/src/version3/jiraExpressions.ts index 1b2d56026..a6e4fc454 100644 --- a/src/version3/jiraExpressions.ts +++ b/src/version3/jiraExpressions.ts @@ -339,4 +339,149 @@ export class JiraExpressions { return this.client.sendRequest(config, callback); } + + /** + * Evaluates a Jira expression and returns its value. The difference between this and `eval` is that this endpoint + * uses the enhanced search API when evaluating JQL queries. This API is eventually consistent, unlike the strongly + * consistent `eval` API. This allows for better performance and scalability. In addition, this API's response for + * JQL evaluation is based on a scrolling view (backed by a `nextPageToken`) instead of a paginated view + * (backed by `startAt` and `totalCount`). + * + * This resource can be used to test Jira expressions that you plan to use elsewhere, or to fetch data in a flexible + * way. Consult the [Jira expressions + * documentation](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/) for more details. + * + * #### Context variables + * + * The following context variables are available to Jira expressions evaluated by this resource. Their presence + * depends on various factors; usually you need to manually request them in the context object sent in the payload, + * but some of them are added automatically under certain conditions. + * + * - `user` ([User](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user)): The + * current user. Always available and equal to `null` if the request is anonymous. + * - `app` ([App](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#app)): The + * [Connect app](https://developer.atlassian.com/cloud/jira/platform/index/#connect-apps) that made the request. + * Available only for authenticated requests made by Connect Apps (read more here: [Authentication for Connect + * apps](https://developer.atlassian.com/cloud/jira/platform/security-for-connect-apps/)). + * - `issue` ([Issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): The + * current issue. Available only when the issue is provided in the request context object. + * - `issues` ([List](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#list) of + * [Issues](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): A + * collection of issues matching a JQL query. Available only when JQL is provided in the request context object. + * - `project` ([Project](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#project)): + * The current project. Available only when the project is provided in the request context object. + * - `sprint` ([Sprint](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#sprint)): + * The current sprint. Available only when the sprint is provided in the request context object. + * - `board` ([Board](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#board)): The + * current board. Available only when the board is provided in the request context object. + * - `serviceDesk` + * ([ServiceDesk](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#servicedesk)): + * The current service desk. Available only when the service desk is provided in the request context object. + * - `customerRequest` + * ([CustomerRequest](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#customerrequest)): + * The current customer request. Available only when the customer request is provided in the request context + * object. + * + * In addition, you can pass custom context variables along with their types. You can then access them from + * the Jira expression by key. You can use the following variables in a custom context: + * + * - `user`: A [user](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user) + * specified as an Atlassian account ID. + * - `issue`: An [issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue) + * specified by ID or key. All the fields of the issue object are available in the Jira expression. + * - `json`: A JSON object containing custom content. + * - `list`: A JSON list of `user`, `issue`, or `json` variable types. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required**: None. + * However, an expression may return different results for different users depending on their permissions. For + * example, different users may see different comments on the same issue. Permission to access Jira Software is + * required to access Jira Software context variables (`board` and `sprint`) or fields (for example, `issue.sprint`). + */ + async evaluateJiraExpressionUsingEnhancedSearch( + parameters: Parameters.EvaluateJiraExpressionUsingEnhancedSearch | undefined, + callback: Callback, + ): Promise; + /** + * Evaluates a Jira expression and returns its value. The difference between this and `eval` is that this endpoint + * uses the enhanced search API when evaluating JQL queries. This API is eventually consistent, unlike the strongly + * consistent `eval` API. This allows for better performance and scalability. In addition, this API's response for + * JQL evaluation is based on a scrolling view (backed by a `nextPageToken`) instead of a paginated view + * (backed by `startAt` and `totalCount`). + * + * This resource can be used to test Jira expressions that you plan to use elsewhere, or to fetch data in a flexible + * way. Consult the [Jira expressions + * documentation](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/) for more details. + * + * #### Context variables + * + * The following context variables are available to Jira expressions evaluated by this resource. Their presence + * depends on various factors; usually you need to manually request them in the context object sent in the payload, + * but some of them are added automatically under certain conditions. + * + * - `user` ([User](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user)): The + * current user. Always available and equal to `null` if the request is anonymous. + * - `app` ([App](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#app)): The + * [Connect app](https://developer.atlassian.com/cloud/jira/platform/index/#connect-apps) that made the request. + * Available only for authenticated requests made by Connect Apps (read more here: [Authentication for Connect + * apps](https://developer.atlassian.com/cloud/jira/platform/security-for-connect-apps/)). + * - `issue` ([Issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): The + * current issue. Available only when the issue is provided in the request context object. + * - `issues` ([List](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#list) of + * [Issues](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue)): A + * collection of issues matching a JQL query. Available only when JQL is provided in the request context object. + * - `project` ([Project](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#project)): + * The current project. Available only when the project is provided in the request context object. + * - `sprint` ([Sprint](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#sprint)): + * The current sprint. Available only when the sprint is provided in the request context object. + * - `board` ([Board](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#board)): The + * current board. Available only when the board is provided in the request context object. + * - `serviceDesk` + * ([ServiceDesk](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#servicedesk)): + * The current service desk. Available only when the service desk is provided in the request context object. + * - `customerRequest` + * ([CustomerRequest](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#customerrequest)): + * The current customer request. Available only when the customer request is provided in the request context + * object. + * + * In addition, you can pass custom context variables along with their types. You can then access them from + * the Jira expression by key. You can use the following variables in a custom context: + * + * - `user`: A [user](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#user) + * specified as an Atlassian account ID. + * - `issue`: An [issue](https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference#issue) + * specified by ID or key. All the fields of the issue object are available in the Jira expression. + * - `json`: A JSON object containing custom content. + * - `list`: A JSON list of `user`, `issue`, or `json` variable types. + * + * This operation can be accessed anonymously. + * + * **[Permissions](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#permissions) required**: None. + * However, an expression may return different results for different users depending on their permissions. For + * example, different users may see different comments on the same issue. Permission to access Jira Software is + * required to access Jira Software context variables (`board` and `sprint`) or fields (for example, `issue.sprint`). + */ + async evaluateJiraExpressionUsingEnhancedSearch( + parameters?: Parameters.EvaluateJiraExpressionUsingEnhancedSearch, + callback?: never, + ): Promise; + async evaluateJiraExpressionUsingEnhancedSearch( + parameters?: Parameters.EvaluateJiraExpressionUsingEnhancedSearch, + callback?: Callback, + ): Promise { + const config: RequestConfig = { + url: '/rest/api/3/expression/evaluate', + method: 'POST', + params: { + expand: parameters?.expand, + }, + data: { + expression: parameters?.expression, + context: parameters?.context, + }, + }; + + return this.client.sendRequest(config, callback); + } } diff --git a/src/version3/models/enhancedSearchRequest.ts b/src/version3/models/enhancedSearchRequest.ts new file mode 100644 index 000000000..206d2a3c6 --- /dev/null +++ b/src/version3/models/enhancedSearchRequest.ts @@ -0,0 +1,100 @@ +export interface EnhancedSearchRequest { + /** + * The [JQL](https://confluence.atlassian.com/x/egORLQ) expression. + * For performance reasons, this parameter requires a bounded query. A bounded query is a query with a search restriction. + * - Example of an unbounded query: `order by key desc`. + * - Example of a bounded query: `assignee = currentUser() order by key`. + * + * Additionally, `orderBy` clause can contain a maximum of 7 fields. + */ + jql?: string; + /** + * The token for a page to fetch that is not the first page. The first page has a `nextPageToken` of `null`. + * Use the `nextPageToken` to fetch the next page of issues. + */ + nextPageToken?: string; + /** + * The maximum number of items to return per page. To manage page size, API may return fewer items per page where a + * large number of fields are requested. The greatest number of items returned per page is achieved when requesting + * `id` or `key` only. + * + * It returns max 5000 issues. + * + * Default: `50` + * + * Format: `int32` + */ + maxResults?: number; + /** + * A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a + * comma-separated list. Expand options include: + * + * - `*all` Returns all fields. + * - `*navigable` Returns navigable fields. + * - `id` Returns only issue IDs. + * - Any issue field, prefixed with a minus to exclude. + * + * The default is `id`. + * + * Examples: + * + * - `summary,comment` Returns only the summary and comments fields. + * - `-description` Returns all navigable (default) fields except description. + * - `*all,-comment` Returns all fields except comments. + * + * Multiple `fields` parameters can be included in a request. + * + * Note: By default, this resource returns IDs only. This differs from + * [GET issue](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get) + * where the default is all fields. + */ + fields?: string[]; + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#expansion) to include additional + * information about issues in the response. Note that, unlike the majority of instances where `expand` is specified, + * `expand` is defined as a comma-delimited string of values. The expand options are: + * + * - `renderedFields` Returns field values rendered in HTML format. + * - `names` Returns the display name of each field. + * - `schema` Returns the schema describing a field type. + * - `transitions` Returns all possible transitions for the issue. + * - `operations` Returns all possible operations for the issue. + * - `editmeta` Returns information about how each field can be edited. + * - `changelog` Returns a list of recent updates to an issue, sorted by date, starting from the most recent. + * - `versionedRepresentations` Instead of `fields`, returns `versionedRepresentations` a JSON array containing each + * version of a field's value, with the highest numbered item representing the most recent version. + * + * Examples: `names,changelog` Returns the display name of each field as well as a list of recent updates to an issue. + */ + expand?: + | 'renderedFields' + | 'names' + | 'schema' + | 'transitions' + | 'operations' + | 'editmeta' + | 'changelog' + | 'versionedRepresentations' + | ( + | 'renderedFields' + | 'names' + | 'schema' + | 'transitions' + | 'operations' + | 'editmeta' + | 'changelog' + | 'versionedRepresentations' + )[] + | string + | string[]; + /** + * A list of up to 5 issue properties to include in the results. This parameter accepts a comma-separated list. + */ + properties?: string[]; + /** Reference fields by their key (rather than ID). The default is `false`. */ + fieldsByKeys?: boolean; + /** Fail this request early if we can't retrieve all field data. The default is `false`. */ + failFast?: boolean; + /** Strong consistency issue ids to be reconciled with search results. Accepts max 50 ids. All issues must exist. */ + reconcileIssues?: number[]; +} diff --git a/src/version3/models/index.ts b/src/version3/models/index.ts index 27a4d7276..2205a5db4 100644 --- a/src/version3/models/index.ts +++ b/src/version3/models/index.ts @@ -178,6 +178,7 @@ export * from './defaultShareScope'; export * from './defaultWorkflow'; export * from './deleteAndReplaceVersion'; export * from './document'; +export * from './enhancedSearchRequest'; export * from './entityProperty'; export * from './entityPropertyDetails'; export * from './error'; @@ -229,6 +230,7 @@ export * from './issueArchivalSync'; export * from './issueArchivalSyncRequest'; export * from './issueChangelogIds'; export * from './issueCommentListRequest'; +export * from './issueContextVariable'; export * from './issueCreateMetadata'; export * from './issueEntityProperties'; export * from './issueEntityPropertiesForMultiUpdate'; @@ -283,6 +285,13 @@ export * from './issueTypeWithStatus'; export * from './issueTypeWorkflowMapping'; export * from './issueUpdateDetails'; export * from './issueUpdateMetadata'; +export * from './jexpEvaluateCtxIssues'; +export * from './jexpEvaluateCtxJqlIssues'; +export * from './jExpEvaluateIssuesJqlMetaData'; +export * from './jExpEvaluateIssuesMeta'; +export * from './jExpEvaluateJiraExpressionResult'; +export * from './jExpEvaluateMetaData'; +export * from './jiraExpressionEvaluateContext'; export * from './jexpIssues'; export * from './jexpJqlIssues'; export * from './jiraExpressionAnalysis'; @@ -290,6 +299,7 @@ export * from './jiraExpressionComplexity'; export * from './jiraExpressionEvalContext'; export * from './jiraExpressionEvalRequest'; export * from './jiraExpressionEvaluationMetaData'; +export * from './jiraExpressionEvalUsingEnhancedSearchRequest'; export * from './jiraExpressionForAnalysis'; export * from './jiraExpressionResult'; export * from './jiraExpressionsAnalysis'; @@ -312,6 +322,7 @@ export * from './jqlQueryOrderByClauseElement'; export * from './jqlQueryToSanitize'; export * from './jQLQueryWithUnknownUsers'; export * from './jQLReferenceData'; +export * from './jsonContextVariable'; export * from './jsonType'; export * from './license'; export * from './licensedApplication'; @@ -474,6 +485,7 @@ export * from './screenSchemeDetails'; export * from './screenSchemeId'; export * from './screenTypes'; export * from './screenWithTab'; +export * from './searchAndReconcileResults'; export * from './searchAutoCompleteFilter'; export * from './searchRequest'; export * from './searchResults'; @@ -535,6 +547,7 @@ export * from './updateUiModificationDetails'; export * from './updateUserToGroup'; export * from './user'; export * from './userAvatarUrls'; +export * from './userContextVariable'; export * from './userDetails'; export * from './userKey'; export * from './userList'; diff --git a/src/version3/models/issueContextVariable.ts b/src/version3/models/issueContextVariable.ts new file mode 100644 index 000000000..5307834f7 --- /dev/null +++ b/src/version3/models/issueContextVariable.ts @@ -0,0 +1,8 @@ +export interface IssueContextVariable { + /** The issue ID. */ + id?: number; + /** The issue key. */ + key?: string; + /** Type of custom context variable. */ + type: string; +} diff --git a/src/version3/models/jExpEvaluateJiraExpressionResult.ts b/src/version3/models/jExpEvaluateJiraExpressionResult.ts new file mode 100644 index 000000000..2e449dcd9 --- /dev/null +++ b/src/version3/models/jExpEvaluateJiraExpressionResult.ts @@ -0,0 +1,13 @@ +import { JExpEvaluateMetaData } from './jExpEvaluateMetaData'; + +/** The result of evaluating a Jira expression. */ +export interface JExpEvaluateJiraExpressionResult { + /** + * The value of the evaluated expression. It may be a primitive JSON value or a Jira REST API object. (Some + * expressions do not produce any meaningful results—for example, an expression that returns a lambda function—if + * that's the case a simple string representation is returned. These string representations should not be relied upon + * and may change without notice.) + */ + value: any; + meta?: JExpEvaluateMetaData; +} diff --git a/src/version3/models/jExpEvaluateMetaData.ts b/src/version3/models/jExpEvaluateMetaData.ts new file mode 100644 index 000000000..ac7fec3ec --- /dev/null +++ b/src/version3/models/jExpEvaluateMetaData.ts @@ -0,0 +1,15 @@ +import { JExpEvaluateIssuesMeta } from './jExpEvaluateIssuesMeta'; +import { JiraExpressionsComplexity } from './jiraExpressionsComplexity'; + +export interface JExpEvaluateMetaData { + /** + * Contains information about the expression complexity. For example, the number of steps it took to + * evaluate the expression. + */ + complexity?: JiraExpressionsComplexity; + /** + * Contains information about the `issues` variable in the context. For example, is the issues were loaded + * with JQL, information about the page will be included here. + */ + issues?: JExpEvaluateIssuesMeta; +} diff --git a/src/version3/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts b/src/version3/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts new file mode 100644 index 000000000..f8a07cffb --- /dev/null +++ b/src/version3/models/jiraExpressionEvalUsingEnhancedSearchRequest.ts @@ -0,0 +1,8 @@ +import { JiraExpressionEvaluateContext } from './jiraExpressionEvaluateContext'; + +export interface JiraExpressionEvalUsingEnhancedSearchRequest { + /** The Jira expression to evaluate. */ + expression: string; + /** The context in which the Jira expression is evaluated. */ + context?: JiraExpressionEvaluateContext; +} diff --git a/src/version3/models/jsonContextVariable.ts b/src/version3/models/jsonContextVariable.ts new file mode 100644 index 000000000..c57466c38 --- /dev/null +++ b/src/version3/models/jsonContextVariable.ts @@ -0,0 +1,6 @@ +export interface JsonContextVariable { + /** Type of custom context variable. */ + type: string; + /** A JSON object containing custom content. */ + value?: any; +} diff --git a/src/version3/models/userContextVariable.ts b/src/version3/models/userContextVariable.ts new file mode 100644 index 000000000..3db08c961 --- /dev/null +++ b/src/version3/models/userContextVariable.ts @@ -0,0 +1,6 @@ +export interface UserContextVariable { + /** The account ID of the user. */ + accountId: string; + /** Type of custom context variable. */ + type: string; +} diff --git a/src/version3/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts b/src/version3/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts new file mode 100644 index 000000000..bad34f2b0 --- /dev/null +++ b/src/version3/parameters/evaluateJiraExpressionUsingEnhancedSearch.ts @@ -0,0 +1,13 @@ +import { JiraExpressionEvalUsingEnhancedSearchRequest } from '../models'; + +export interface EvaluateJiraExpressionUsingEnhancedSearch extends JiraExpressionEvalUsingEnhancedSearchRequest { + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#expansion) to include additional + * information in the response. This parameter accepts `meta.complexity` that returns information about the expression + * complexity. For example, the number of expensive operations used by the expression and how close the expression is + * to reaching the [complexity + * limit](https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#restrictions). Useful when designing + * and debugging your expressions. + */ + expand?: string; +} diff --git a/src/version3/parameters/index.ts b/src/version3/parameters/index.ts index c3216d6ab..09cd96cf9 100644 --- a/src/version3/parameters/index.ts +++ b/src/version3/parameters/index.ts @@ -210,6 +210,7 @@ export * from './deleteWorklogProperty'; export * from './doTransition'; export * from './editIssue'; export * from './evaluateJiraExpression'; +export * from './evaluateJiraExpressionUsingEnhancedSearch'; export * from './expandAttachmentForHumans'; export * from './expandAttachmentForMachines'; export * from './exportArchivedIssues'; @@ -446,7 +447,9 @@ export * from './restoreCustomField'; export * from './sanitiseJqlQueries'; export * from './search'; export * from './searchForIssuesUsingJql'; +export * from './searchForIssuesUsingJqlEnhancedSearch'; export * from './searchForIssuesUsingJqlPost'; +export * from './searchForIssuesUsingJqlEnhancedSearchPost'; export * from './searchPriorities'; export * from './searchProjects'; export * from './searchProjectsUsingSecuritySchemes'; diff --git a/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearch.ts b/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearch.ts new file mode 100644 index 000000000..bf2c37274 --- /dev/null +++ b/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearch.ts @@ -0,0 +1,80 @@ +export interface SearchForIssuesUsingJqlEnhancedSearch { + /** + * The [JQL](https://confluence.atlassian.com/x/egORLQ) expression. + * For performance reasons, this parameter requires a bounded query. A bounded query is a query with a search restriction. + * - Example of an unbounded query: `order by key desc`. + * - Example of a bounded query: `assignee = currentUser() order by key`. + * + * Additionally, `orderBy` clause can contain a maximum of 7 fields. + */ + jql?: string; + /** + * The token for a page to fetch that is not the first page. The first page has a `nextPageToken` of `null`. + * Use the `nextPageToken` to fetch the next page of issues. + */ + nextPageToken?: string; + /** + * The maximum number of items to return per page. To manage page size, API may return fewer items per page where a + * large number of fields are requested. The greatest number of items returned per page is achieved when requesting + * `id` or `key` only. + * + * It returns max 5000 issues. + * + * Default: `50` + * + * Format: `int32` + */ + maxResults?: number; + /** + * A list of fields to return for each issue, use it to retrieve a subset of fields. This parameter accepts a + * comma-separated list. Expand options include: + * + * - `*all` Returns all fields. + * - `*navigable` Returns navigable fields. + * - `id` Returns only issue IDs. + * - Any issue field, prefixed with a minus to exclude. + * + * The default is `id`. + * + * Examples: + * + * - `summary,comment` Returns only the summary and comments fields. + * - `-description` Returns all navigable (default) fields except description. + * - `*all,-comment` Returns all fields except comments. + * + * Multiple `fields` parameters can be included in a request. + * + * Note: By default, this resource returns IDs only. This differs from + * [GET issue](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get) + * where the default is all fields. + */ + fields?: string[]; + /** + * Use [expand](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#expansion) to include additional + * information about issues in the response. Note that, unlike the majority of instances where `expand` is specified, + * `expand` is defined as a comma-delimited string of values. The expand options are: + * + * - `renderedFields` Returns field values rendered in HTML format. + * - `names` Returns the display name of each field. + * - `schema` Returns the schema describing a field type. + * - `transitions` Returns all possible transitions for the issue. + * - `operations` Returns all possible operations for the issue. + * - `editmeta` Returns information about how each field can be edited. + * - `changelog` Returns a list of recent updates to an issue, sorted by date, starting from the most recent. + * - `versionedRepresentations` Instead of `fields`, returns `versionedRepresentations` a JSON array containing each + * version of a field's value, with the highest numbered item representing the most recent version. + * + * Examples: `names,changelog` Returns the display name of each field as well as a list of recent updates to an issue. + */ + expand?: string; + /** + * A list of up to 5 issue properties to include in the results. This parameter accepts a comma-separated list. + */ + properties?: string[]; + /** Reference fields by their key (rather than ID). The default is `false`. */ + fieldsByKeys?: boolean; + /** Fail this request early if we can't retrieve all field data. The default is `false`. */ + failFast?: boolean; + /** Strong consistency issue ids to be reconciled with search results. Accepts max 50 ids. All issues must exist. */ + reconcileIssues?: number[]; +} diff --git a/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts b/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts new file mode 100644 index 000000000..f00326bc8 --- /dev/null +++ b/src/version3/parameters/searchForIssuesUsingJqlEnhancedSearchPost.ts @@ -0,0 +1,3 @@ +import { EnhancedSearchRequest } from '../models'; + +export interface SearchForIssuesUsingJqlEnhancedSearchPost extends EnhancedSearchRequest {} diff --git a/tests/unit/version2/issueSearch.test.ts b/tests/unit/version2/issueSearch.test.ts index 06079ad87..840cadbfb 100644 --- a/tests/unit/version2/issueSearch.test.ts +++ b/tests/unit/version2/issueSearch.test.ts @@ -67,3 +67,65 @@ test('searchForIssuesUsingJqlPost should accept follow parameters', ({ expect }) validateQuery: undefined, }); }); + +test('searchForIssuesUsingJqlEnhancedSearch should calls without parameters', ({ expect }) => { + const client = new Version2Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearch(); + + expect(sendRequestStub.calledOnce).toBeTruthy(); +}); + +test('searchForIssuesUsingJqlEnhancedSearch should accept follow parameters', ({ expect }) => { + const client = new Version2Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearch({ + jql: 'id IN (TICKET_ID) ORDER BY key ASC', + maxResults: 10, + fields: ['key', 'summary'], + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.params).toStrictEqual({ + jql: 'id IN (TICKET_ID) ORDER BY key ASC', + nextPageToken: undefined, + maxResults: 10, + fields: ['key', 'summary'], + expand: undefined, + properties: undefined, + fieldsByKeys: undefined, + failFast: undefined, + reconcileIssues: undefined, + }); +}); + +test('searchForIssuesUsingJqlEnhancedSearchPost should accept follow parameters', ({ expect }) => { + const client = new Version2Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearchPost({ + jql: 'test JQL', + expand: ['changelog'], + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.data).toStrictEqual({ + jql: 'test JQL', + nextPageToken: undefined, + maxResults: undefined, + fields: undefined, + expand: ['changelog'], + properties: undefined, + fieldsByKeys: undefined, + failFast: undefined, + reconcileIssues: undefined, + }); +}); diff --git a/tests/unit/version2/jiraExpressions.test.ts b/tests/unit/version2/jiraExpressions.test.ts new file mode 100644 index 000000000..a4e0f3ae5 --- /dev/null +++ b/tests/unit/version2/jiraExpressions.test.ts @@ -0,0 +1,40 @@ +import * as sinon from 'sinon'; +import { test } from 'vitest'; +import { JiraExpressions, Version2Client } from '@jirajs/version2'; + +const config = { host: 'http://localhost' }; + +test('should be defined', ({ expect }) => { + expect(!!JiraExpressions).toBeTruthy(); +}); + +test('evaluateJiraExpressionUsingEnhancedSearch should calls without parameters', ({ expect }) => { + const client = new Version2Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.jiraExpressions.evaluateJiraExpressionUsingEnhancedSearch(); + + expect(sendRequestStub.calledOnce).toBeTruthy(); +}); + +test('evaluateJiraExpressionUsingEnhancedSearch should accept follow parameters', ({ expect }) => { + const client = new Version2Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.jiraExpressions.evaluateJiraExpressionUsingEnhancedSearch({ + expression: '{ key: issue.key, type: issue.issueType.name }', + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.params).toStrictEqual({ + expand: undefined, + }); + + expect(callArgument.data).toStrictEqual({ + expression: '{ key: issue.key, type: issue.issueType.name }', + context: undefined, + }); +}); diff --git a/tests/unit/version3/issueSearch.test.ts b/tests/unit/version3/issueSearch.test.ts index 8cce57a8e..ef30e1d84 100644 --- a/tests/unit/version3/issueSearch.test.ts +++ b/tests/unit/version3/issueSearch.test.ts @@ -70,3 +70,65 @@ test('searchForIssuesUsingJqlPost should accept follow parameters', ({ expect }) validateQuery: undefined, }); }); + +test('searchForIssuesUsingJqlEnhancedSearch should calls without parameters', ({ expect }) => { + const client = new Version3Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearch(); + + expect(sendRequestStub.calledOnce).toBeTruthy(); +}); + +test('searchForIssuesUsingJqlEnhancedSearch should accept follow parameters', ({ expect }) => { + const client = new Version3Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearch({ + jql: 'id IN (TICKET_ID) ORDER BY key ASC', + maxResults: 10, + fields: ['key', 'summary'], + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.params).toStrictEqual({ + jql: 'id IN (TICKET_ID) ORDER BY key ASC', + nextPageToken: undefined, + maxResults: 10, + fields: ['key', 'summary'], + expand: undefined, + properties: undefined, + fieldsByKeys: undefined, + failFast: undefined, + reconcileIssues: undefined, + }); +}); + +test('searchForIssuesUsingJqlEnhancedSearchPost should accept follow parameters', ({ expect }) => { + const client = new Version3Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.issueSearch.searchForIssuesUsingJqlEnhancedSearchPost({ + jql: 'test JQL', + expand: ['changelog'], + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.data).toStrictEqual({ + jql: 'test JQL', + nextPageToken: undefined, + maxResults: undefined, + fields: undefined, + expand: ['changelog'], + properties: undefined, + fieldsByKeys: undefined, + failFast: undefined, + reconcileIssues: undefined, + }); +}); diff --git a/tests/unit/version3/jiraExpressions.test.ts b/tests/unit/version3/jiraExpressions.test.ts new file mode 100644 index 000000000..6ba83c41c --- /dev/null +++ b/tests/unit/version3/jiraExpressions.test.ts @@ -0,0 +1,40 @@ +import * as sinon from 'sinon'; +import { test } from 'vitest'; +import { JiraExpressions, Version3Client } from '@jirajs/version3'; + +const config = { host: 'http://localhost' }; + +test('should be defined', ({ expect }) => { + expect(!!JiraExpressions).toBeTruthy(); +}); + +test('evaluateJiraExpressionUsingEnhancedSearch should calls without parameters', ({ expect }) => { + const client = new Version3Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.jiraExpressions.evaluateJiraExpressionUsingEnhancedSearch(); + + expect(sendRequestStub.calledOnce).toBeTruthy(); +}); + +test('evaluateJiraExpressionUsingEnhancedSearch should accept follow parameters', ({ expect }) => { + const client = new Version3Client(config); + const sendRequestStub = sinon.stub(client, 'sendRequest'); + + client.jiraExpressions.evaluateJiraExpressionUsingEnhancedSearch({ + expression: '{ key: issue.key, type: issue.issueType.name }', + }); + + expect(sendRequestStub.calledOnce).toBeTruthy(); + + const callArgument = sendRequestStub.getCall(0).args[0]; + + expect(callArgument.params).toStrictEqual({ + expand: undefined, + }); + + expect(callArgument.data).toStrictEqual({ + expression: '{ key: issue.key, type: issue.issueType.name }', + context: undefined, + }); +});