@knpkv/jira-api-client 1.0.1 → 2.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 CHANGED
@@ -1,5 +1,49 @@
1
1
  # @knpkv/jira-api-client
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#438](https://github.com/knpkv/npm/pull/438) [`acb8b25`](https://github.com/knpkv/npm/commit/acb8b25772cc188a0cc1299a1b591903240cfc7c) Thanks [@github-actions](https://github.com/apps/github-actions)! - Update the generated Schema-backed Jira API client.
8
+
9
+ Breaking: these exported types now include `null`, so code that reads them must handle it: `ApprovalConfiguration`, `BoardFeaturesPayload`, `BoardsPayload`, `ConditionGroupConfiguration`, `ConditionGroupUpdate`, `CustomFieldPayload`, `FieldCapabilityPayload`, `FieldLayoutPayload`, `FieldLayoutSchemePayload`, `FieldSchemePayload`, `IssueLayoutPayload`, `IssueTypeHierarchyPayload`, `IssueTypePayload`, `IssueTypeProjectCreatePayload`, `IssueTypeScreenSchemePayload`, `NotificationSchemePayload`, `PermissionPayloadDTO`, `PreviewConditionGroupConfiguration`, `PreviewRuleConfiguration`, `ProjectId`, `RolesCapabilityPayload`, `ScopePayload`, `ScreenPayload`, `ScreenSchemePayload`, `SecuritySchemePayload`, `TargetClassification`, `TargetMandatoryFields`, `TargetStatus`, `WorkflowCapabilityPayload`, `WorkflowLayout`, `WorkflowProjectIdScope`, `WorkflowRuleConfiguration`, `WorkflowStatusLayout`, and `WorkflowTransitionLinks`. `ProjectId` and `WorkflowLayout` also appear in responses. No exports are removed; 129 are added.
10
+
11
+ ### Minor Changes
12
+
13
+ - [#452](https://github.com/knpkv/npm/pull/452) [`755eafa`](https://github.com/knpkv/npm/commit/755eafab8c0bc3e82b00e2dd27c68d669a1de87e) Thanks [@konopkov](https://github.com/konopkov)! - Upgrade to Effect 4.0.0 stable. `effect` and every `@effect/*` dependency or peer dependency now require `4.0.0`; imports move from the removed `effect/unstable/*` paths to `effect/*`.
14
+
15
+ - [#376](https://github.com/knpkv/npm/pull/376) [`379b029`](https://github.com/knpkv/npm/commit/379b02947180d50d4a40cf4b7723851aa68fc183) Thanks [@konopkov](https://github.com/konopkov)! - Let a client re-read its credential per request. `JiraApiConfigContract` gains an optional
16
+ `resolveAuth`, and the credential union it yields is now exported as `JiraApiCredential`.
17
+
18
+ Without it, a client is pinned for life to the token that existed when its layer was built. That is
19
+ invisible in a command that exits in seconds and fatal in one that does not: an Atlassian access
20
+ token lasts about an hour, after which every request 401s and no retry inside the process can
21
+ recover, because the expired token is already baked into the header. `jcf watch` is meant to run all
22
+ day.
23
+
24
+ Omitting `resolveAuth` keeps the previous behaviour exactly — the credential in `auth` is used as
25
+ given, which is right for a basic-auth API token that cannot expire. When it is supplied, both the
26
+ `Authorization` header and the API host are derived from the same resolved value, so a resolver
27
+ cannot address one site while authenticating against another.
28
+
29
+ - [#452](https://github.com/knpkv/npm/pull/452) [`755eafa`](https://github.com/knpkv/npm/commit/755eafab8c0bc3e82b00e2dd27c68d669a1de87e) Thanks [@konopkov](https://github.com/konopkov)! - Decode Jira change items that omit `toString`. Effect 4.0.0 reads declared struct keys through the prototype, so an omitted `toString` resolved to `Object.prototype.toString` and failed decoding. The new `ownOptionalKey` schema treats that inherited member as an absent key.
30
+
31
+ ## 1.1.1
32
+
33
+ ### Patch Changes
34
+
35
+ - [#361](https://github.com/knpkv/npm/pull/361) [`676419e`](https://github.com/knpkv/npm/commit/676419e39c395dd4cfea6d9ffaee7d002a3f75e2) Thanks [@konopkov](https://github.com/konopkov)! - Upgrade the workspace to Effect 4.0.0-rc.109, pin the vendored Effect reference to that exact upstream release, guard source/package alignment, and bound Control Center test concurrency for reliable CI execution.
36
+
37
+ ## 1.1.0
38
+
39
+ ### Minor Changes
40
+
41
+ - [#370](https://github.com/knpkv/npm/pull/370) [`27d2ca1`](https://github.com/knpkv/npm/commit/27d2ca18b0c0b0f8a252d461c0aaf10eb92e9ffc) Thanks [@konopkov](https://github.com/konopkov)! - Enforce the complete anti-slop rule set with zero accepted diagnostics and update affected APIs and implementations to satisfy the required contracts.
42
+
43
+ ### Patch Changes
44
+
45
+ - [#361](https://github.com/knpkv/npm/pull/361) [`676419e`](https://github.com/knpkv/npm/commit/676419e39c395dd4cfea6d9ffaee7d002a3f75e2) Thanks [@konopkov](https://github.com/konopkov)! - Update Effect and effect-qb, migrate schema-tagged errors to the current Effect API, and adopt the dialect-scoped SQLite function and type APIs introduced by effect-qb 0.22.
46
+
3
47
  ## 1.0.1
4
48
 
5
49
  ### Patch Changes
@@ -9,22 +9,22 @@
9
9
  */
10
10
  import * as Context from "effect/Context";
11
11
  import * as Effect from "effect/Effect";
12
+ import * as HttpClient from "effect/http/HttpClient";
13
+ import type * as HttpClientError from "effect/http/HttpClientError";
12
14
  import * as Layer from "effect/Layer";
13
15
  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
16
  import * as Generated from "./generated/JiraApi.js";
17
- import { JiraApiConfig, type JiraApiConfigShape } from "./JiraApiConfig.js";
17
+ import { JiraApiConfig, type JiraApiConfigContract } from "./JiraApiConfig.js";
18
18
  export interface UploadAttachmentInput {
19
19
  readonly bytes: Uint8Array;
20
20
  readonly filename: string;
21
21
  readonly mediaType?: string | undefined;
22
22
  }
23
- export interface JiraApiClientShape extends Generated.JiraApi {
23
+ export interface JiraApiClientContract extends Generated.JiraApi {
24
24
  readonly uploadAttachment: (issueIdOrKey: string, input: UploadAttachmentInput) => Effect.Effect<Generated.AddAttachment200, HttpClientError.HttpClientError | SchemaError>;
25
25
  }
26
- export declare const make: (httpClient: HttpClient.HttpClient, config: JiraApiConfigShape) => Generated.JiraApi;
27
- declare const JiraApiClient_base: Context.ServiceClass<JiraApiClient, "@knpkv/jira-api-client/JiraApiClient", JiraApiClientShape>;
26
+ export declare const make: (httpClient: HttpClient.HttpClient, config: JiraApiConfigContract) => Generated.JiraApi;
27
+ declare const JiraApiClient_base: Context.ServiceClass<JiraApiClient, "@knpkv/jira-api-client/JiraApiClient", JiraApiClientContract>;
28
28
  export declare class JiraApiClient extends JiraApiClient_base {
29
29
  static readonly layer: Layer.Layer<JiraApiClient, never, JiraApiConfig | HttpClient.HttpClient>;
30
30
  }
@@ -1 +1 @@
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"}
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,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,KAAK,eAAe,MAAM,6BAA6B,CAAA;AAGnE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAA0B,MAAM,oBAAoB,CAAA;AAEtG,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,qBAAsB,SAAQ,SAAS,CAAC,OAAO;IAC9D,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;AAqCD,eAAO,MAAM,IAAI,eACH,UAAU,CAAC,UAAU,UACzB,qBAAqB,KAC5B,SAAS,CAAC,OAIT,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"}
@@ -9,22 +9,35 @@
9
9
  */
10
10
  import * as Context from "effect/Context";
11
11
  import * as Effect from "effect/Effect";
12
- import * as Encoding from "effect/Encoding";
12
+ import { Base64 } from "effect/encoding";
13
13
  import { flow } from "effect/Function";
14
+ import * as HttpClient from "effect/http/HttpClient";
15
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
16
+ import * as HttpClientResponse from "effect/http/HttpClientResponse";
14
17
  import * as Layer from "effect/Layer";
15
18
  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
19
  import * as Generated from "./generated/JiraApi.js";
20
20
  import { JiraApiConfig } from "./JiraApiConfig.js";
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")))));
21
+ const authorizationHeader = (auth) => auth.type === "basic"
22
+ ? `Basic ${Base64.encode(`${auth.email}:${Redacted.value(auth.apiToken)}`)}`
23
+ : `Bearer ${Redacted.value(auth.accessToken)}`;
24
+ const apiBaseUrl = (baseUrl, auth) => auth.type === "oauth2" ? `https://api.atlassian.com/ex/jira/${auth.cloudId}` : baseUrl;
25
+ /**
26
+ * Where the credential is turned into a header.
27
+ *
28
+ * Both the host and the `Authorization` header come from `auth`, so they are derived together from
29
+ * one value rather than separately from two reads that could disagree about which site is being
30
+ * addressed. When `resolveAuth` is present that pair is recomputed per request, which is the only
31
+ * way a token refreshed mid-run reaches the wire — `mapRequest` would capture the startup value.
32
+ */
33
+ const addressAndAuthorize = (config) => {
34
+ const resolve = config.resolveAuth;
35
+ if (resolve === undefined) {
36
+ return HttpClient.mapRequest(flow(HttpClientRequest.prependUrl(apiBaseUrl(config.baseUrl, config.auth)), HttpClientRequest.setHeader("Authorization", authorizationHeader(config.auth))));
37
+ }
38
+ return HttpClient.mapRequestEffect((request) => Effect.map(resolve, (auth) => request.pipe(HttpClientRequest.prependUrl(apiBaseUrl(config.baseUrl, auth)), HttpClientRequest.setHeader("Authorization", authorizationHeader(auth)))));
39
+ };
40
+ export const make = (httpClient, config) => Generated.make(httpClient.pipe(addressAndAuthorize(config), HttpClient.mapRequest(HttpClientRequest.setHeader("Accept", "application/json"))));
28
41
  const makeUploadAttachment = (api) => (issueIdOrKey, input) => {
29
42
  const buffer = new ArrayBuffer(input.bytes.byteLength);
30
43
  new Uint8Array(buffer).set(input.bytes);
@@ -1 +1 @@
1
- {"version":3,"file":"JiraApiClient.js","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"JiraApiClient.js","sourceRoot":"","sources":["../src/JiraApiClient.ts"],"names":[],"mappings":"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"}
@@ -7,29 +7,48 @@
7
7
  * Basic auth uses email + Redacted API token; OAuth2 uses Redacted access token + cloud ID.
8
8
  * - **Base URL routing**: For OAuth2, the base URL is derived from cloud ID (`api.atlassian.com/ex/jira/{cloudId}`);
9
9
  * for basic auth, `baseUrl` is used directly.
10
+ * - **`auth` is a snapshot; `resolveAuth` is a subscription.** A credential that can expire needs the
11
+ * second one — see its own note.
10
12
  *
11
13
  * @module
12
14
  */
13
15
  import * as Context from "effect/Context";
16
+ import type * as Effect from "effect/Effect";
14
17
  import type * as Redacted from "effect/Redacted";
18
+ /** How a request proves who is asking. */
19
+ export type JiraApiCredential = {
20
+ readonly type: "basic";
21
+ readonly email: string;
22
+ readonly apiToken: Redacted.Redacted<string>;
23
+ } | {
24
+ readonly type: "oauth2";
25
+ readonly accessToken: Redacted.Redacted<string>;
26
+ readonly cloudId: string;
27
+ };
15
28
  /**
16
29
  * Configuration shape for Jira API client.
17
30
  *
18
31
  * @category Config
19
32
  */
20
- export interface JiraApiConfigShape {
33
+ export interface JiraApiConfigContract {
21
34
  readonly baseUrl: string;
22
- readonly auth: {
23
- readonly type: "basic";
24
- readonly email: string;
25
- readonly apiToken: Redacted.Redacted<string>;
26
- } | {
27
- readonly type: "oauth2";
28
- readonly accessToken: Redacted.Redacted<string>;
29
- readonly cloudId: string;
30
- };
35
+ readonly auth: JiraApiCredential;
36
+ /**
37
+ * Re-read before every request, when supplied. Otherwise `auth` is used as given.
38
+ *
39
+ * A `Redacted` token is a value, so a client built from one is pinned to it for as long as the
40
+ * client lives. That is invisible in a command that exits in seconds and fatal in one that does
41
+ * not: an Atlassian access token lasts about an hour, after which every request 401s and no amount
42
+ * of retrying inside the process can recover, because the expired token is baked into the header.
43
+ * `jcf watch` is meant to run all day, so it supplies this and a refresh reaches the next request.
44
+ *
45
+ * Typed as infallible on purpose. This runs inside request preprocessing, where a new error would
46
+ * widen every operation's error channel; a resolver that cannot read its credential yields
47
+ * whatever it has, and the 401 that follows is the same one an absent login already produces.
48
+ */
49
+ readonly resolveAuth?: Effect.Effect<JiraApiCredential> | undefined;
31
50
  }
32
- declare const JiraApiConfig_base: Context.ServiceClass<JiraApiConfig, "@knpkv/jira-api-client/JiraApiConfig", JiraApiConfigShape>;
51
+ declare const JiraApiConfig_base: Context.ServiceClass<JiraApiConfig, "@knpkv/jira-api-client/JiraApiConfig", JiraApiConfigContract>;
33
52
  /**
34
53
  * Jira API configuration service.
35
54
  *
@@ -1 +1 @@
1
- {"version":3,"file":"JiraApiConfig.d.ts","sourceRoot":"","sources":["../src/JiraApiConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAEhD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EACT;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;KAAE,GAChG;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3G;;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAc,SAAQ,kBAElC;CAAG"}
1
+ {"version":3,"file":"JiraApiConfig.d.ts","sourceRoot":"","sources":["../src/JiraApiConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAEhD,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAChG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1G;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAA;CACpE;;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAc,SAAQ,kBAElC;CAAG"}
@@ -7,6 +7,8 @@
7
7
  * Basic auth uses email + Redacted API token; OAuth2 uses Redacted access token + cloud ID.
8
8
  * - **Base URL routing**: For OAuth2, the base URL is derived from cloud ID (`api.atlassian.com/ex/jira/{cloudId}`);
9
9
  * for basic auth, `baseUrl` is used directly.
10
+ * - **`auth` is a snapshot; `resolveAuth` is a subscription.** A credential that can expire needs the
11
+ * second one — see its own note.
10
12
  *
11
13
  * @module
12
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"JiraApiConfig.js","sourceRoot":"","sources":["../src/JiraApiConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAezC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,aAAc,SAAQ,OAAO,CAAC,OAAO,EAAqC,CACrF,sCAAsC,CACvC;CAAG"}
1
+ {"version":3,"file":"JiraApiConfig.js","sourceRoot":"","sources":["../src/JiraApiConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAiCzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,aAAc,SAAQ,OAAO,CAAC,OAAO,EAAwC,CACxF,sCAAsC,CACvC;CAAG"}
@@ -0,0 +1,13 @@
1
+ import * as Schema from "effect/Schema";
2
+ /** `Object.prototype` members that Jira payloads use as ordinary field names. */
3
+ export type PrototypeKey = "toString";
4
+ /**
5
+ * Optional key for a field named after an `Object.prototype` member, such as Jira's `toString`.
6
+ *
7
+ * Effect resolves declared struct keys with `in`, so a JSON object that omits `toString` presents the inherited
8
+ * `Object.prototype.toString`. Only that exact inherited function decodes as an absent key; any other value must
9
+ * satisfy `schema`. Use it in place of `Schema.optionalKey(schema)` for these keys; the encoded and decoded types
10
+ * stay those of `Schema.optionalKey(schema)`.
11
+ */
12
+ export declare const ownOptionalKey: <S extends Schema.Top>(key: PrototypeKey, schema: S) => Schema.decodeTo<Schema.optionalKey<Schema.toType<S>>, Schema.optionalKey<Schema.Union<readonly [S, Schema.declare<never, never>]>>, never, never>;
13
+ //# sourceMappingURL=OwnOptionalKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OwnOptionalKey.d.ts","sourceRoot":"","sources":["../src/OwnOptionalKey.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAA;AAErC;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,MAAM,CAAC,GAAG,OAAO,YAAY,UAAU,CAAC,sJAchF,CAAA"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Optional struct keys that shadow `Object.prototype` members.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import * as Option from "effect/Option";
7
+ import * as Predicate from "effect/Predicate";
8
+ import * as Schema from "effect/Schema";
9
+ import * as SchemaGetter from "effect/SchemaGetter";
10
+ /**
11
+ * Optional key for a field named after an `Object.prototype` member, such as Jira's `toString`.
12
+ *
13
+ * Effect resolves declared struct keys with `in`, so a JSON object that omits `toString` presents the inherited
14
+ * `Object.prototype.toString`. Only that exact inherited function decodes as an absent key; any other value must
15
+ * satisfy `schema`. Use it in place of `Schema.optionalKey(schema)` for these keys; the encoded and decoded types
16
+ * stay those of `Schema.optionalKey(schema)`.
17
+ */
18
+ export const ownOptionalKey = (key, schema) => {
19
+ const inherited = Object.prototype[key];
20
+ // Typed `never`: the inherited member is not a domain value and never survives decoding.
21
+ const isInherited = Predicate.compose(Predicate.isFunction, (member) => member === inherited);
22
+ const InheritedMember = Schema.declare(isInherited, { expected: `the inherited Object.prototype.${key}` });
23
+ return Schema.optionalKey(Schema.Union([schema, InheritedMember])).pipe(Schema.decodeTo(Schema.optionalKey(Schema.toType(schema)), {
24
+ decode: SchemaGetter.transformOptional(Option.filter(Predicate.not(isInherited))),
25
+ encode: SchemaGetter.passthrough()
26
+ }));
27
+ };
28
+ //# sourceMappingURL=OwnOptionalKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OwnOptionalKey.js","sourceRoot":"","sources":["../src/OwnOptionalKey.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAKnD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAuB,GAAiB,EAAE,MAAS,EAAE,EAAE;IACnF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IACvC,yFAAyF;IACzF,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CACnC,SAAS,CAAC,UAAU,EACpB,CAAC,MAAgB,EAAmB,EAAE,CAAC,MAAM,KAAK,SAAS,CAC5D,CAAA;IACD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,kCAAkC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC1G,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CACrE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QACzD,MAAM,EAAE,YAAY,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACjF,MAAM,EAAE,YAAY,CAAC,WAAW,EAAE;KACnC,CAAC,CACH,CAAA;AACH,CAAC,CAAA"}