@knpkv/jira-api-client 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +88 -65
- package/dist/JiraApiClient.d.ts +20 -86
- package/dist/JiraApiClient.d.ts.map +1 -1
- package/dist/JiraApiClient.js +26 -75
- package/dist/JiraApiClient.js.map +1 -1
- package/dist/generated/JiraApi.d.ts +103971 -0
- package/dist/generated/JiraApi.d.ts.map +1 -0
- package/dist/generated/JiraApi.js +7608 -0
- package/dist/generated/JiraApi.js.map +1 -0
- package/dist/index.d.ts +3 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -11
- package/dist/index.js.map +1 -1
- package/package.json +13 -16
- package/scripts/regenerate.ts +209 -201
- package/scripts/tsconfig.json +13 -0
- package/src/JiraApiClient.ts +74 -104
- package/src/generated/JiraApi.ts +19596 -0
- package/src/index.ts +3 -14
- package/test/JiraApiClient.test.ts +154 -153
- package/.specs/VERSION_V3 +0 -1
- package/.specs/jira-v3-1001.0.0-SNAPSHOT-05f20e18d9bde3de68f911b4915970482f536d4e.json +0 -56275
- package/.specs/jira-v3-1001.0.0-SNAPSHOT-d7cd03e966bb408ad32ffe870114289c528f56fd.json +0 -56129
- package/.specs/jira-v3-1001.0.0-SNAPSHOT-ea9913a8c4412d2bfb1911480b023a04544e19d8.json +0 -55618
- package/dist/OpenApiFetchClient.d.ts +0 -55
- package/dist/OpenApiFetchClient.d.ts.map +0 -1
- package/dist/OpenApiFetchClient.js +0 -68
- package/dist/OpenApiFetchClient.js.map +0 -1
- package/dist/generated/v3/index.d.ts +0 -7
- package/dist/generated/v3/index.d.ts.map +0 -1
- package/dist/generated/v3/index.js +0 -2
- package/dist/generated/v3/index.js.map +0 -1
- package/dist/generated/v3/schema.d.ts +0 -64454
- package/src/OpenApiFetchClient.ts +0 -102
- package/src/generated/v3/index.ts +0 -6
- package/src/generated/v3/schema.d.ts +0 -64454
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @knpkv/jira-api-client
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#125](https://github.com/knpkv/npm/pull/125) [`f820c19`](https://github.com/knpkv/npm/commit/f820c1906e00f2f2d17c2e7cc3921ba26522db43) Thanks [@konopkov](https://github.com/konopkov)! - Replace the legacy Atlassian `openapi-fetch` clients with generated,
|
|
8
|
+
Schema-validated Effect clients. Jira and Confluence now provide direct Effect
|
|
9
|
+
operations, injected `HttpClient` transports, deterministic local regeneration,
|
|
10
|
+
structural upstream freshness checks, and scheduled tested update pull requests.
|
|
11
|
+
|
|
12
|
+
The legacy `toEffect`, `FetchClientError`, raw `.client` operation surface, and
|
|
13
|
+
type-only generated subpaths are removed.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#125](https://github.com/knpkv/npm/pull/125) [`f820c19`](https://github.com/knpkv/npm/commit/f820c1906e00f2f2d17c2e7cc3921ba26522db43) Thanks [@konopkov](https://github.com/konopkov)! - Upgrade the workspace to Effect 4.0.0-beta.98 and current compatible dependencies. Replace ad hoc object guards with Effect Predicate helpers and migrate retry schedules to the current Schedule API.
|
|
18
|
+
|
|
3
19
|
## 0.4.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,94 +1,117 @@
|
|
|
1
1
|
# @knpkv/jira-api-client
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pnpm add @knpkv/jira-api-client
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Peer dependencies: `effect`
|
|
3
|
+
Schema-validated Effect client for Jira Cloud REST API v3. Request parameters,
|
|
4
|
+
response codecs, operation errors, and the low-level client are generated from
|
|
5
|
+
Atlassian's official OpenAPI document with `@effect/openapi-generator`.
|
|
12
6
|
|
|
13
7
|
## Usage
|
|
14
8
|
|
|
15
|
-
```
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
9
|
+
```ts
|
|
10
|
+
import { JiraApiClient, JiraApiConfig } from "@knpkv/jira-api-client"
|
|
11
|
+
import { NodeHttpClient } from "@effect/platform-node"
|
|
12
|
+
import { Effect, Layer, Redacted } from "effect"
|
|
19
13
|
|
|
20
14
|
const program = Effect.gen(function* () {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
client.v3.client.GET("/rest/api/3/issue/{issueIdOrKey}", {
|
|
26
|
-
params: { path: { issueIdOrKey: "PROJ-123" } }
|
|
27
|
-
})
|
|
28
|
-
)
|
|
29
|
-
console.log(issue.fields?.summary)
|
|
30
|
-
|
|
31
|
-
// Search with JQL
|
|
32
|
-
const results = yield* toEffect(
|
|
33
|
-
client.v3.client.POST("/rest/api/3/search/jql", {
|
|
34
|
-
body: { jql: "project = PROJ AND status != Done", maxResults: 50 }
|
|
35
|
-
})
|
|
36
|
-
)
|
|
15
|
+
const jira = yield* JiraApiClient
|
|
16
|
+
return yield* jira.getIssue("PROJ-123", {
|
|
17
|
+
params: { fields: ["summary", "status"] }
|
|
18
|
+
})
|
|
37
19
|
})
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
baseUrl: "https://mysite.atlassian.net",
|
|
21
|
+
const ConfigLive = Layer.succeed(JiraApiConfig, {
|
|
22
|
+
baseUrl: "https://example.atlassian.net",
|
|
42
23
|
auth: {
|
|
43
24
|
type: "basic",
|
|
44
|
-
email: "
|
|
45
|
-
apiToken: Redacted.make("
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
// Or OAuth2
|
|
50
|
-
const oauthConfigLayer = Layer.succeed(JiraApiConfig, {
|
|
51
|
-
baseUrl: "",
|
|
52
|
-
auth: {
|
|
53
|
-
type: "oauth2",
|
|
54
|
-
accessToken: Redacted.make("oauth-access-token"),
|
|
55
|
-
cloudId: "your-cloud-id"
|
|
25
|
+
email: "developer@example.com",
|
|
26
|
+
apiToken: Redacted.make("api-token")
|
|
56
27
|
}
|
|
57
28
|
})
|
|
58
29
|
|
|
59
|
-
Effect.runPromise(
|
|
30
|
+
Effect.runPromise(
|
|
31
|
+
program.pipe(
|
|
32
|
+
Effect.provide(JiraApiClient.layer),
|
|
33
|
+
Effect.provide(ConfigLive),
|
|
34
|
+
Effect.provide(NodeHttpClient.layerUndici)
|
|
35
|
+
)
|
|
36
|
+
)
|
|
60
37
|
```
|
|
61
38
|
|
|
62
|
-
|
|
39
|
+
OAuth2 configuration uses an access token and cloud ID. Requests are routed
|
|
40
|
+
through `https://api.atlassian.com/ex/jira/{cloudId}` automatically.
|
|
41
|
+
|
|
42
|
+
The complete generated module is exported as `JiraApi`, and `make` constructs
|
|
43
|
+
the generated client from an existing Effect `HttpClient`. Application code
|
|
44
|
+
normally uses `JiraApiClient`, which also provides `uploadAttachment` for Jira's
|
|
45
|
+
multipart endpoint. The upstream schema describes that endpoint as Java server
|
|
46
|
+
objects rather than a native `FormData`, so multipart construction deliberately
|
|
47
|
+
lives in this single handwritten boundary.
|
|
48
|
+
|
|
49
|
+
All successful JSON bodies are decoded with generated Effect Schemas. Documented
|
|
50
|
+
4xx and 5xx statuses fail with generated tagged errors such as `GetIssue404`;
|
|
51
|
+
transport and malformed-body failures remain in the typed error channel.
|
|
52
|
+
|
|
53
|
+
## Regenerating the client
|
|
54
|
+
|
|
55
|
+
Requirements:
|
|
56
|
+
|
|
57
|
+
- dependencies installed with `pnpm install`;
|
|
58
|
+
- network access to Atlassian for a live regeneration;
|
|
59
|
+
- a clean enough worktree to review generated changes independently.
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
Run a live regeneration from the repository root:
|
|
65
62
|
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
// → Effect<ResponseData, FetchClientError>
|
|
63
|
+
```sh
|
|
64
|
+
pnpm --filter @knpkv/jira-api-client regenerate
|
|
69
65
|
```
|
|
70
66
|
|
|
71
|
-
|
|
67
|
+
The command performs this deterministic pipeline:
|
|
72
68
|
|
|
73
|
-
|
|
69
|
+
1. Fetch `https://dac-static.atlassian.com/cloud/jira/platform/swagger-v3.v3.json`.
|
|
70
|
+
2. Canonically encode the unmodified response as `.specs/jira-v3.json`.
|
|
71
|
+
3. Apply `.specs/jira-v3.patch.json` as RFC 6902 JSON Patch in memory.
|
|
72
|
+
4. Normalize contradictory defaults and mixed open-object schemas in memory.
|
|
73
|
+
5. Remove misleading JSON content from `204 No Content` responses so they
|
|
74
|
+
generate as `void` instead of attempting to decode an empty body.
|
|
75
|
+
6. Add permissive JSON schemas to documented bodyless error responses so they
|
|
76
|
+
cannot be mistaken for successful `void` responses.
|
|
77
|
+
7. Generate `src/generated/JiraApi.ts` with `@effect/openapi-generator`.
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
Never edit the generated TypeScript or committed upstream specification by
|
|
80
|
+
hand. Put intentional upstream corrections in the JSON Patch, or change the
|
|
81
|
+
documented normalization in `scripts/regenerate.ts`.
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
import { FetchClientError } from "@knpkv/jira-api-client"
|
|
83
|
+
For an offline, reproducible regeneration from the committed specification:
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
```sh
|
|
86
|
+
pnpm --filter @knpkv/jira-api-client regenerate --local
|
|
81
87
|
```
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
Review and validate a regeneration with:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
git diff -- packages/jira-api-client/.specs
|
|
93
|
+
git diff -- packages/jira-api-client/src/generated/JiraApi.ts
|
|
94
|
+
pnpm --filter @knpkv/jira-api-client check
|
|
95
|
+
pnpm --filter @knpkv/jira-api-client build
|
|
96
|
+
pnpm --filter @knpkv/jira-api-client test
|
|
97
|
+
pnpm --filter @knpkv/jira-cli test
|
|
98
|
+
pnpm --filter @knpkv/jira-clockify test
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Checking specification freshness
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
pnpm --filter @knpkv/jira-api-client regenerate:check
|
|
105
|
+
```
|
|
84
106
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| `@knpkv/jira-api-client/v3` | Generated V3 OpenAPI types |
|
|
89
|
-
| `@knpkv/jira-api-client/JiraApiClient` | Client service only |
|
|
90
|
-
| `@knpkv/jira-api-client/JiraApiConfig` | Config service only |
|
|
107
|
+
This fetches the complete current document and compares its canonical JSON
|
|
108
|
+
structure with the committed raw specification. It does not rely only on
|
|
109
|
+
Atlassian's version string.
|
|
91
110
|
|
|
92
|
-
|
|
111
|
+
`.github/workflows/jira-api-update.yml` runs the check daily. When the upstream
|
|
112
|
+
document changes, CI regenerates the client, builds and tests this package and
|
|
113
|
+
its Jira consumers, adds a changeset, and opens or updates a pull request on
|
|
114
|
+
`chore/jira-api-spec-update`.
|
|
93
115
|
|
|
94
|
-
|
|
116
|
+
Generated source is excluded from handwritten-source lint rules, but remains
|
|
117
|
+
fully typechecked, built, and exercised through transport and decoding tests.
|
package/dist/JiraApiClient.d.ts
CHANGED
|
@@ -1,99 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Schema-validated Jira Cloud REST API client.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* cloud ID) auth. The layer reads {@link JiraApiConfig} to build the Authorization header
|
|
8
|
-
* and derive the correct base URL.
|
|
9
|
-
* - **openapi-fetch wrapper**: Uses {@link OpenApiFetchClient} for Effect-based methods.
|
|
10
|
-
*
|
|
11
|
-
* **Common tasks**
|
|
12
|
-
*
|
|
13
|
-
* - Use the client: `const jira = yield* JiraApiClient; jira.v3.GET(...)`
|
|
14
|
-
* - Provide the layer: `Effect.provide(JiraApiClient.layer)`
|
|
4
|
+
* Generated code owns request construction and response decoding. This module
|
|
5
|
+
* applies Jira authentication and contains the one multipart boundary that the
|
|
6
|
+
* upstream specification cannot model as a native FormData value.
|
|
15
7
|
*
|
|
16
8
|
* @module
|
|
17
9
|
*/
|
|
18
10
|
import * as Context from "effect/Context";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
19
12
|
import * as Layer from "effect/Layer";
|
|
20
|
-
import type {
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* params: { path: { issueIdOrKey: "PROJ-123" } }
|
|
33
|
-
* }))
|
|
34
|
-
*
|
|
35
|
-
* // Search issues with JQL
|
|
36
|
-
* toEffect(client.v3.client.POST("/rest/api/3/search/jql", {
|
|
37
|
-
* body: { jql: "project = PROJ", maxResults: 50 }
|
|
38
|
-
* }))
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @category Client
|
|
42
|
-
*/
|
|
43
|
-
export interface JiraApiClientShape {
|
|
44
|
-
readonly v3: OpenApiFetchClient<V3Paths>;
|
|
13
|
+
import type { SchemaError } from "effect/Schema";
|
|
14
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
15
|
+
import type * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
16
|
+
import * as Generated from "./generated/JiraApi.js";
|
|
17
|
+
import { JiraApiConfig, type JiraApiConfigShape } from "./JiraApiConfig.js";
|
|
18
|
+
export interface UploadAttachmentInput {
|
|
19
|
+
readonly bytes: Uint8Array;
|
|
20
|
+
readonly filename: string;
|
|
21
|
+
readonly mediaType?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface JiraApiClientShape extends Generated.JiraApi {
|
|
24
|
+
readonly uploadAttachment: (issueIdOrKey: string, input: UploadAttachmentInput) => Effect.Effect<Generated.AddAttachment200, HttpClientError.HttpClientError | SchemaError>;
|
|
45
25
|
}
|
|
26
|
+
export declare const make: (httpClient: HttpClient.HttpClient, config: JiraApiConfigShape) => Generated.JiraApi;
|
|
46
27
|
declare const JiraApiClient_base: Context.ServiceClass<JiraApiClient, "@knpkv/jira-api-client/JiraApiClient", JiraApiClientShape>;
|
|
47
|
-
/**
|
|
48
|
-
* Jira API client service.
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```typescript
|
|
52
|
-
* import { JiraApiClient, JiraApiConfig } from "@knpkv/jira-api-client"
|
|
53
|
-
* import * as Redacted from "effect/Redacted"
|
|
54
|
-
* import * as Effect from "effect/Effect"
|
|
55
|
-
* import * as Layer from "effect/Layer"
|
|
56
|
-
*
|
|
57
|
-
* const program = Effect.gen(function* () {
|
|
58
|
-
* const client = yield* JiraApiClient
|
|
59
|
-
* const issue = yield* toEffect(client.v3.client.GET("/rest/api/3/issue/{issueIdOrKey}", {
|
|
60
|
-
* params: { path: { issueIdOrKey: "PROJ-123" } }
|
|
61
|
-
* }))
|
|
62
|
-
* console.log(issue.fields?.summary)
|
|
63
|
-
* })
|
|
64
|
-
*
|
|
65
|
-
* const configLayer = Layer.succeed(JiraApiConfig, {
|
|
66
|
-
* baseUrl: "https://mysite.atlassian.net",
|
|
67
|
-
* auth: {
|
|
68
|
-
* type: "basic",
|
|
69
|
-
* email: "user@example.com",
|
|
70
|
-
* apiToken: Redacted.make("token")
|
|
71
|
-
* }
|
|
72
|
-
* })
|
|
73
|
-
*
|
|
74
|
-
* Effect.runPromise(
|
|
75
|
-
* program.pipe(
|
|
76
|
-
* Effect.provide(JiraApiClient.layer),
|
|
77
|
-
* Effect.provide(configLayer)
|
|
78
|
-
* )
|
|
79
|
-
* )
|
|
80
|
-
* ```
|
|
81
|
-
*
|
|
82
|
-
* @category Client
|
|
83
|
-
*/
|
|
84
28
|
export declare class JiraApiClient extends JiraApiClient_base {
|
|
85
|
-
|
|
86
|
-
* Layer that provides JiraApiClient.
|
|
87
|
-
*
|
|
88
|
-
* Requires: JiraApiConfig
|
|
89
|
-
*/
|
|
90
|
-
static readonly layer: Layer.Layer<JiraApiClient, never, JiraApiConfig>;
|
|
29
|
+
static readonly layer: Layer.Layer<JiraApiClient, never, JiraApiConfig | HttpClient.HttpClient>;
|
|
91
30
|
}
|
|
92
|
-
|
|
93
|
-
* Layer that provides JiraApiClient.
|
|
94
|
-
*
|
|
95
|
-
* @category Layers
|
|
96
|
-
*/
|
|
97
|
-
export declare const layer: Layer.Layer<JiraApiClient, never, JiraApiConfig>;
|
|
31
|
+
export declare const layer: Layer.Layer<JiraApiClient, never, HttpClient.HttpClient | JiraApiConfig>;
|
|
98
32
|
export {};
|
|
99
33
|
//# sourceMappingURL=JiraApiClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JiraApiClient.d.ts","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"JiraApiClient.d.ts","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAA;AAC7D,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAA;AAG5E,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE3E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,MAAM,WAAW,kBAAmB,SAAQ,SAAS,CAAC,OAAO;IAC3D,QAAQ,CAAC,gBAAgB,EAAE,CACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,qBAAqB,KACzB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC,eAAe,GAAG,WAAW,CAAC,CAAA;CAC9F;AAYD,eAAO,MAAM,IAAI,GACf,YAAY,UAAU,CAAC,UAAU,EACjC,QAAQ,kBAAkB,KACzB,SAAS,CAAC,OAOT,CAAA;;AAuBJ,qBAAa,aAAc,SAAQ,kBAElC;IACC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAChC,aAAa,EACb,KAAK,EACL,aAAa,GAAG,UAAU,CAAC,UAAU,CACtC,CAQA;CACF;AAED,eAAO,MAAM,KAAK,0EAAsB,CAAA"}
|
package/dist/JiraApiClient.js
CHANGED
|
@@ -1,93 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Schema-validated Jira Cloud REST API client.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* cloud ID) auth. The layer reads {@link JiraApiConfig} to build the Authorization header
|
|
8
|
-
* and derive the correct base URL.
|
|
9
|
-
* - **openapi-fetch wrapper**: Uses {@link OpenApiFetchClient} for Effect-based methods.
|
|
10
|
-
*
|
|
11
|
-
* **Common tasks**
|
|
12
|
-
*
|
|
13
|
-
* - Use the client: `const jira = yield* JiraApiClient; jira.v3.GET(...)`
|
|
14
|
-
* - Provide the layer: `Effect.provide(JiraApiClient.layer)`
|
|
4
|
+
* Generated code owns request construction and response decoding. This module
|
|
5
|
+
* applies Jira authentication and contains the one multipart boundary that the
|
|
6
|
+
* upstream specification cannot model as a native FormData value.
|
|
15
7
|
*
|
|
16
8
|
* @module
|
|
17
9
|
*/
|
|
18
10
|
import * as Context from "effect/Context";
|
|
19
11
|
import * as Effect from "effect/Effect";
|
|
20
12
|
import * as Encoding from "effect/Encoding";
|
|
13
|
+
import { flow } from "effect/Function";
|
|
21
14
|
import * as Layer from "effect/Layer";
|
|
22
15
|
import * as Redacted from "effect/Redacted";
|
|
16
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
17
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
18
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
19
|
+
import * as Generated from "./generated/JiraApi.js";
|
|
23
20
|
import { JiraApiConfig } from "./JiraApiConfig.js";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* params: { path: { issueIdOrKey: "PROJ-123" } }
|
|
39
|
-
* }))
|
|
40
|
-
* console.log(issue.fields?.summary)
|
|
41
|
-
* })
|
|
42
|
-
*
|
|
43
|
-
* const configLayer = Layer.succeed(JiraApiConfig, {
|
|
44
|
-
* baseUrl: "https://mysite.atlassian.net",
|
|
45
|
-
* auth: {
|
|
46
|
-
* type: "basic",
|
|
47
|
-
* email: "user@example.com",
|
|
48
|
-
* apiToken: Redacted.make("token")
|
|
49
|
-
* }
|
|
50
|
-
* })
|
|
51
|
-
*
|
|
52
|
-
* Effect.runPromise(
|
|
53
|
-
* program.pipe(
|
|
54
|
-
* Effect.provide(JiraApiClient.layer),
|
|
55
|
-
* Effect.provide(configLayer)
|
|
56
|
-
* )
|
|
57
|
-
* )
|
|
58
|
-
* ```
|
|
59
|
-
*
|
|
60
|
-
* @category Client
|
|
61
|
-
*/
|
|
21
|
+
const authorizationHeader = (config) => config.auth.type === "basic"
|
|
22
|
+
? `Basic ${Encoding.encodeBase64(`${config.auth.email}:${Redacted.value(config.auth.apiToken)}`)}`
|
|
23
|
+
: `Bearer ${Redacted.value(config.auth.accessToken)}`;
|
|
24
|
+
const apiBaseUrl = (config) => config.auth.type === "oauth2"
|
|
25
|
+
? `https://api.atlassian.com/ex/jira/${config.auth.cloudId}`
|
|
26
|
+
: config.baseUrl;
|
|
27
|
+
export const make = (httpClient, config) => Generated.make(httpClient.pipe(HttpClient.mapRequest(flow(HttpClientRequest.prependUrl(apiBaseUrl(config)), HttpClientRequest.setHeader("Authorization", authorizationHeader(config)), HttpClientRequest.setHeader("Accept", "application/json")))));
|
|
28
|
+
const makeUploadAttachment = (api) => (issueIdOrKey, input) => {
|
|
29
|
+
const buffer = new ArrayBuffer(input.bytes.byteLength);
|
|
30
|
+
new Uint8Array(buffer).set(input.bytes);
|
|
31
|
+
const form = new FormData();
|
|
32
|
+
form.append("file", new Blob([buffer], input.mediaType === undefined ? undefined : { type: input.mediaType }), input.filename);
|
|
33
|
+
return api.httpClient.execute(HttpClientRequest.post(`/rest/api/3/issue/${encodeURIComponent(issueIdOrKey)}/attachments`).pipe(HttpClientRequest.setHeader("X-Atlassian-Token", "no-check"), HttpClientRequest.bodyFormData(form))).pipe(Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.flatMap(HttpClientResponse.schemaBodyJson(Generated.AddAttachment200)));
|
|
34
|
+
};
|
|
62
35
|
export class JiraApiClient extends Context.Service()("@knpkv/jira-api-client/JiraApiClient") {
|
|
63
|
-
/**
|
|
64
|
-
* Layer that provides JiraApiClient.
|
|
65
|
-
*
|
|
66
|
-
* Requires: JiraApiConfig
|
|
67
|
-
*/
|
|
68
36
|
static layer = Layer.effect(JiraApiClient, Effect.gen(function* () {
|
|
69
37
|
const config = yield* JiraApiConfig;
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
: `Bearer ${Redacted.value(config.auth.accessToken)}`;
|
|
74
|
-
// Base URL differs by auth type
|
|
75
|
-
const baseUrl = config.auth.type === "oauth2"
|
|
76
|
-
? `https://api.atlassian.com/ex/jira/${config.auth.cloudId}`
|
|
77
|
-
: config.baseUrl;
|
|
78
|
-
const headers = {
|
|
79
|
-
Authorization: authHeader,
|
|
80
|
-
Accept: "application/json"
|
|
81
|
-
};
|
|
82
|
-
return {
|
|
83
|
-
v3: makeOpenApiFetchClient(baseUrl, headers)
|
|
84
|
-
};
|
|
38
|
+
const httpClient = yield* HttpClient.HttpClient;
|
|
39
|
+
const api = make(httpClient, config);
|
|
40
|
+
return JiraApiClient.of({ ...api, uploadAttachment: makeUploadAttachment(api) });
|
|
85
41
|
}));
|
|
86
42
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Layer that provides JiraApiClient.
|
|
89
|
-
*
|
|
90
|
-
* @category Layers
|
|
91
|
-
*/
|
|
92
43
|
export const layer = JiraApiClient.layer;
|
|
93
44
|
//# sourceMappingURL=JiraApiClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JiraApiClient.js","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"JiraApiClient.js","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"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"}
|