@knpkv/atlassian-common 0.2.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +107 -0
  4. package/dist/Brand.d.ts +118 -0
  5. package/dist/Brand.d.ts.map +1 -0
  6. package/dist/Brand.js +107 -0
  7. package/dist/Brand.js.map +1 -0
  8. package/dist/Hash.d.ts +53 -0
  9. package/dist/Hash.d.ts.map +1 -0
  10. package/dist/Hash.js +63 -0
  11. package/dist/Hash.js.map +1 -0
  12. package/dist/SerializeError.d.ts +48 -0
  13. package/dist/SerializeError.d.ts.map +1 -0
  14. package/dist/SerializeError.js +42 -0
  15. package/dist/SerializeError.js.map +1 -0
  16. package/dist/ast/BlockNode.d.ts +429 -0
  17. package/dist/ast/BlockNode.d.ts.map +1 -0
  18. package/dist/ast/BlockNode.js +279 -0
  19. package/dist/ast/BlockNode.js.map +1 -0
  20. package/dist/ast/Document.d.ts +255 -0
  21. package/dist/ast/Document.d.ts.map +1 -0
  22. package/dist/ast/Document.js +80 -0
  23. package/dist/ast/Document.js.map +1 -0
  24. package/dist/ast/InlineNode.d.ts +483 -0
  25. package/dist/ast/InlineNode.d.ts.map +1 -0
  26. package/dist/ast/InlineNode.js +268 -0
  27. package/dist/ast/InlineNode.js.map +1 -0
  28. package/dist/ast/MacroNode.d.ts +214 -0
  29. package/dist/ast/MacroNode.d.ts.map +1 -0
  30. package/dist/ast/MacroNode.js +110 -0
  31. package/dist/ast/MacroNode.js.map +1 -0
  32. package/dist/ast/index.d.ts +10 -0
  33. package/dist/ast/index.d.ts.map +1 -0
  34. package/dist/ast/index.js +14 -0
  35. package/dist/ast/index.js.map +1 -0
  36. package/dist/auth/OAuthEndpoints.d.ts +95 -0
  37. package/dist/auth/OAuthEndpoints.d.ts.map +1 -0
  38. package/dist/auth/OAuthEndpoints.js +112 -0
  39. package/dist/auth/OAuthEndpoints.js.map +1 -0
  40. package/dist/auth/OAuthErrors.d.ts +76 -0
  41. package/dist/auth/OAuthErrors.d.ts.map +1 -0
  42. package/dist/auth/OAuthErrors.js +85 -0
  43. package/dist/auth/OAuthErrors.js.map +1 -0
  44. package/dist/auth/OAuthOperations.d.ts +87 -0
  45. package/dist/auth/OAuthOperations.d.ts.map +1 -0
  46. package/dist/auth/OAuthOperations.js +169 -0
  47. package/dist/auth/OAuthOperations.js.map +1 -0
  48. package/dist/auth/OAuthResponseSchemas.d.ts +65 -0
  49. package/dist/auth/OAuthResponseSchemas.d.ts.map +1 -0
  50. package/dist/auth/OAuthResponseSchemas.js +47 -0
  51. package/dist/auth/OAuthResponseSchemas.js.map +1 -0
  52. package/dist/auth/index.d.ts +11 -0
  53. package/dist/auth/index.d.ts.map +1 -0
  54. package/dist/auth/index.js +16 -0
  55. package/dist/auth/index.js.map +1 -0
  56. package/dist/auth/uuid.d.ts +14 -0
  57. package/dist/auth/uuid.d.ts.map +1 -0
  58. package/dist/auth/uuid.js +14 -0
  59. package/dist/auth/uuid.js.map +1 -0
  60. package/dist/config/ConfigPaths.d.ts +95 -0
  61. package/dist/config/ConfigPaths.d.ts.map +1 -0
  62. package/dist/config/ConfigPaths.js +102 -0
  63. package/dist/config/ConfigPaths.js.map +1 -0
  64. package/dist/config/OAuthSchemas.d.ts +144 -0
  65. package/dist/config/OAuthSchemas.d.ts.map +1 -0
  66. package/dist/config/OAuthSchemas.js +107 -0
  67. package/dist/config/OAuthSchemas.js.map +1 -0
  68. package/dist/config/TokenStorage.d.ts +96 -0
  69. package/dist/config/TokenStorage.d.ts.map +1 -0
  70. package/dist/config/TokenStorage.js +128 -0
  71. package/dist/config/TokenStorage.js.map +1 -0
  72. package/dist/config/index.d.ts +9 -0
  73. package/dist/config/index.d.ts.map +1 -0
  74. package/dist/config/index.js +12 -0
  75. package/dist/config/index.js.map +1 -0
  76. package/dist/index.d.ts +13 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +20 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/parsers/index.d.ts +7 -0
  81. package/dist/parsers/index.d.ts.map +1 -0
  82. package/dist/parsers/index.js +8 -0
  83. package/dist/parsers/index.js.map +1 -0
  84. package/dist/serializers/MarkdownSerializer.d.ts +63 -0
  85. package/dist/serializers/MarkdownSerializer.d.ts.map +1 -0
  86. package/dist/serializers/MarkdownSerializer.js +367 -0
  87. package/dist/serializers/MarkdownSerializer.js.map +1 -0
  88. package/dist/serializers/index.d.ts +7 -0
  89. package/dist/serializers/index.d.ts.map +1 -0
  90. package/dist/serializers/index.js +7 -0
  91. package/dist/serializers/index.js.map +1 -0
  92. package/package.json +86 -0
  93. package/src/Brand.ts +142 -0
  94. package/src/Hash.ts +68 -0
  95. package/src/SerializeError.ts +50 -0
  96. package/src/ast/BlockNode.ts +386 -0
  97. package/src/ast/Document.ts +101 -0
  98. package/src/ast/InlineNode.ts +328 -0
  99. package/src/ast/MacroNode.ts +172 -0
  100. package/src/ast/index.ts +87 -0
  101. package/src/auth/OAuthEndpoints.ts +142 -0
  102. package/src/auth/OAuthErrors.ts +101 -0
  103. package/src/auth/OAuthOperations.ts +276 -0
  104. package/src/auth/OAuthResponseSchemas.ts +70 -0
  105. package/src/auth/index.ts +47 -0
  106. package/src/auth/uuid.ts +14 -0
  107. package/src/config/ConfigPaths.ts +179 -0
  108. package/src/config/OAuthSchemas.ts +146 -0
  109. package/src/config/TokenStorage.ts +228 -0
  110. package/src/config/index.ts +43 -0
  111. package/src/index.ts +34 -0
  112. package/src/parsers/index.ts +8 -0
  113. package/src/serializers/MarkdownSerializer.ts +498 -0
  114. package/src/serializers/index.ts +7 -0
  115. package/test/Brand.test.ts +90 -0
  116. package/test/MarkdownSerializer.test.ts +82 -0
  117. package/test/OAuthEndpoints.test.ts +109 -0
  118. package/test/OAuthOperations.test.ts +315 -0
  119. package/tsconfig.json +11 -0
  120. package/tsconfig.tsbuildinfo +1 -0
  121. package/vitest.config.ts +12 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Atlassian OAuth2 endpoint URLs, scope constants, authorization URL builder, and PKCE.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Constants + builder**: Endpoint URLs are plain strings; {@link buildAuthUrl}
7
+ * assembles the full authorization URL with audience, scopes, CSRF state, and PKCE.
8
+ * - **Scope sets**: {@link CONFLUENCE_SCOPES} and {@link JIRA_SCOPES} define the
9
+ * minimum permissions for each product's OAuth flow.
10
+ * - **PKCE**: {@link generateCodeVerifier} and {@link computeCodeChallenge} implement
11
+ * RFC 7636 S256 to protect the authorization code grant from interception.
12
+ *
13
+ * @module
14
+ */
15
+ import * as Effect from "effect/Effect";
16
+ /**
17
+ * OAuth2 authorization endpoint.
18
+ *
19
+ * @category Endpoints
20
+ */
21
+ export declare const AUTH_URL = "https://auth.atlassian.com/authorize";
22
+ /**
23
+ * OAuth2 token endpoint.
24
+ *
25
+ * @category Endpoints
26
+ */
27
+ export declare const TOKEN_URL = "https://auth.atlassian.com/oauth/token";
28
+ /**
29
+ * OAuth2 token revocation endpoint.
30
+ *
31
+ * @category Endpoints
32
+ */
33
+ export declare const REVOKE_URL = "https://auth.atlassian.com/oauth/revoke";
34
+ /**
35
+ * Accessible resources endpoint (to get cloud IDs).
36
+ *
37
+ * @category Endpoints
38
+ */
39
+ export declare const RESOURCES_URL = "https://api.atlassian.com/oauth/token/accessible-resources";
40
+ /**
41
+ * User info endpoint.
42
+ *
43
+ * @category Endpoints
44
+ */
45
+ export declare const ME_URL = "https://api.atlassian.com/me";
46
+ /**
47
+ * Confluence scopes for OAuth2.
48
+ *
49
+ * @category Scopes
50
+ */
51
+ export declare const CONFLUENCE_SCOPES: string[];
52
+ /**
53
+ * Jira scopes for OAuth2.
54
+ *
55
+ * @category Scopes
56
+ */
57
+ export declare const JIRA_SCOPES: string[];
58
+ /**
59
+ * Options for building OAuth2 authorization URL.
60
+ *
61
+ * @category Types
62
+ */
63
+ export interface BuildAuthUrlOptions {
64
+ /** OAuth2 client ID */
65
+ readonly clientId: string;
66
+ /** State parameter for CSRF protection */
67
+ readonly state: string;
68
+ /** Local callback server port */
69
+ readonly port: number;
70
+ /** OAuth2 scopes */
71
+ readonly scopes: ReadonlyArray<string>;
72
+ /** PKCE code_challenge (S256). Omit to skip PKCE. */
73
+ readonly codeChallenge?: string | undefined;
74
+ }
75
+ /**
76
+ * Build OAuth2 authorization URL.
77
+ *
78
+ * @category Utilities
79
+ */
80
+ export declare const buildAuthUrl: (options: BuildAuthUrlOptions) => string;
81
+ /**
82
+ * Generate a cryptographically random PKCE code verifier (RFC 7636).
83
+ * Uses Web Crypto API (available in Node 18+, Deno, browsers).
84
+ *
85
+ * @category PKCE
86
+ */
87
+ export declare const generateCodeVerifier: () => string;
88
+ /**
89
+ * Compute S256 code challenge from a code verifier (RFC 7636).
90
+ * Uses Web Crypto `subtle.digest` — returns Effect since digest is async.
91
+ *
92
+ * @category PKCE
93
+ */
94
+ export declare const computeCodeChallenge: (verifier: string) => Effect.Effect<string>;
95
+ //# sourceMappingURL=OAuthEndpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthEndpoints.d.ts","sourceRoot":"","sources":["../../src/auth/OAuthEndpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC;;;;GAIG;AACH,eAAO,MAAM,QAAQ,yCAAyC,CAAA;AAE9D;;;;GAIG;AACH,eAAO,MAAM,SAAS,2CAA2C,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,UAAU,4CAA4C,CAAA;AAEnE;;;;GAIG;AACH,eAAO,MAAM,aAAa,+DAA+D,CAAA;AAEzF;;;;GAIG;AACH,eAAO,MAAM,MAAM,iCAAiC,CAAA;AAEpD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,UAM7B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,UAQvB,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oBAAoB;IACpB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,qDAAqD;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5C;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,mBAAmB,KAAG,MAe3D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAIvC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAGzE,CAAA"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Atlassian OAuth2 endpoint URLs, scope constants, authorization URL builder, and PKCE.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Constants + builder**: Endpoint URLs are plain strings; {@link buildAuthUrl}
7
+ * assembles the full authorization URL with audience, scopes, CSRF state, and PKCE.
8
+ * - **Scope sets**: {@link CONFLUENCE_SCOPES} and {@link JIRA_SCOPES} define the
9
+ * minimum permissions for each product's OAuth flow.
10
+ * - **PKCE**: {@link generateCodeVerifier} and {@link computeCodeChallenge} implement
11
+ * RFC 7636 S256 to protect the authorization code grant from interception.
12
+ *
13
+ * @module
14
+ */
15
+ import * as Effect from "effect/Effect";
16
+ import * as Encoding from "effect/Encoding";
17
+ /**
18
+ * OAuth2 authorization endpoint.
19
+ *
20
+ * @category Endpoints
21
+ */
22
+ export const AUTH_URL = "https://auth.atlassian.com/authorize";
23
+ /**
24
+ * OAuth2 token endpoint.
25
+ *
26
+ * @category Endpoints
27
+ */
28
+ export const TOKEN_URL = "https://auth.atlassian.com/oauth/token";
29
+ /**
30
+ * OAuth2 token revocation endpoint.
31
+ *
32
+ * @category Endpoints
33
+ */
34
+ export const REVOKE_URL = "https://auth.atlassian.com/oauth/revoke";
35
+ /**
36
+ * Accessible resources endpoint (to get cloud IDs).
37
+ *
38
+ * @category Endpoints
39
+ */
40
+ export const RESOURCES_URL = "https://api.atlassian.com/oauth/token/accessible-resources";
41
+ /**
42
+ * User info endpoint.
43
+ *
44
+ * @category Endpoints
45
+ */
46
+ export const ME_URL = "https://api.atlassian.com/me";
47
+ /**
48
+ * Confluence scopes for OAuth2.
49
+ *
50
+ * @category Scopes
51
+ */
52
+ export const CONFLUENCE_SCOPES = [
53
+ "read:page:confluence",
54
+ "write:page:confluence",
55
+ "delete:page:confluence",
56
+ "read:me",
57
+ "offline_access"
58
+ ];
59
+ /**
60
+ * Jira scopes for OAuth2.
61
+ *
62
+ * @category Scopes
63
+ */
64
+ export const JIRA_SCOPES = [
65
+ "read:jira-work",
66
+ "write:jira-work",
67
+ "read:jira-user",
68
+ "manage:jira-project",
69
+ "manage:jira-configuration",
70
+ "read:me",
71
+ "offline_access"
72
+ ];
73
+ /**
74
+ * Build OAuth2 authorization URL.
75
+ *
76
+ * @category Utilities
77
+ */
78
+ export const buildAuthUrl = (options) => {
79
+ const params = new URLSearchParams({
80
+ audience: "api.atlassian.com",
81
+ client_id: options.clientId,
82
+ scope: options.scopes.join(" "),
83
+ redirect_uri: `http://localhost:${options.port}/callback`,
84
+ state: options.state,
85
+ response_type: "code",
86
+ prompt: "consent"
87
+ });
88
+ if (options.codeChallenge) {
89
+ params.set("code_challenge", options.codeChallenge);
90
+ params.set("code_challenge_method", "S256");
91
+ }
92
+ return `${AUTH_URL}?${params.toString()}`;
93
+ };
94
+ /**
95
+ * Generate a cryptographically random PKCE code verifier (RFC 7636).
96
+ * Uses Web Crypto API (available in Node 18+, Deno, browsers).
97
+ *
98
+ * @category PKCE
99
+ */
100
+ export const generateCodeVerifier = () => {
101
+ const bytes = new Uint8Array(32);
102
+ globalThis.crypto.getRandomValues(bytes);
103
+ return Encoding.encodeBase64Url(bytes);
104
+ };
105
+ /**
106
+ * Compute S256 code challenge from a code verifier (RFC 7636).
107
+ * Uses Web Crypto `subtle.digest` — returns Effect since digest is async.
108
+ *
109
+ * @category PKCE
110
+ */
111
+ export const computeCodeChallenge = (verifier) => Effect.promise(() => globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier))).pipe(Effect.map((hash) => Encoding.encodeBase64Url(new Uint8Array(hash))));
112
+ //# sourceMappingURL=OAuthEndpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthEndpoints.js","sourceRoot":"","sources":["../../src/auth/OAuthEndpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,sCAAsC,CAAA;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,wCAAwC,CAAA;AAEjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,yCAAyC,CAAA;AAEnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,4DAA4D,CAAA;AAEzF;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,8BAA8B,CAAA;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,sBAAsB;IACtB,uBAAuB;IACvB,wBAAwB;IACxB,SAAS;IACT,gBAAgB;CACjB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB,qBAAqB;IACrB,2BAA2B;IAC3B,SAAS;IACT,gBAAgB;CACjB,CAAA;AAoBD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAA4B,EAAU,EAAE;IACnE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,QAAQ,EAAE,mBAAmB;QAC7B,SAAS,EAAE,OAAO,CAAC,QAAQ;QAC3B,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/B,YAAY,EAAE,oBAAoB,OAAO,CAAC,IAAI,WAAW;QACzD,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,aAAa,EAAE,MAAM;QACrB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAA;IACF,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;QACnD,MAAM,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,GAAG,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;AAC3C,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAW,EAAE;IAC/C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IAChC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IACxC,OAAO,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;AACxC,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAyB,EAAE,CAC9E,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CACvG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CACrE,CAAA"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * OAuth flow step for error context.
3
+ *
4
+ * @category Types
5
+ */
6
+ export type OAuthStep = "configure" | "authorize" | "token" | "resources" | "user-info" | "refresh" | "revoke";
7
+ declare const OAuthError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
8
+ readonly _tag: "OAuthError";
9
+ } & Readonly<A>;
10
+ /**
11
+ * Error during OAuth2 flow.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { Effect } from "effect"
16
+ * import { OAuthError } from "@knpkv/atlassian-common/auth"
17
+ *
18
+ * Effect.gen(function* () {
19
+ * // ... oauth operation
20
+ * }).pipe(
21
+ * Effect.catchTag("OAuthError", (error) =>
22
+ * Effect.sync(() => console.error(`OAuth error at ${error.step}: ${error.message}`))
23
+ * )
24
+ * )
25
+ * ```
26
+ *
27
+ * @category Errors
28
+ */
29
+ export declare class OAuthError extends OAuthError_base<{
30
+ readonly step: OAuthStep;
31
+ readonly cause?: unknown;
32
+ }> {
33
+ get message(): string;
34
+ }
35
+ declare const AuthMissingError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
36
+ readonly _tag: "AuthMissingError";
37
+ } & Readonly<A>;
38
+ /**
39
+ * Error when authentication is missing.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * import { Effect } from "effect"
44
+ * import { AuthMissingError } from "@knpkv/atlassian-common/auth"
45
+ *
46
+ * Effect.gen(function* () {
47
+ * // ... requires auth
48
+ * }).pipe(
49
+ * Effect.catchTag("AuthMissingError", () =>
50
+ * Effect.sync(() => console.error("Please login first"))
51
+ * )
52
+ * )
53
+ * ```
54
+ *
55
+ * @category Errors
56
+ */
57
+ export declare class AuthMissingError extends AuthMissingError_base<{
58
+ readonly tool?: string;
59
+ }> {
60
+ get message(): string;
61
+ }
62
+ declare const OAuthNotConfiguredError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
63
+ readonly _tag: "OAuthNotConfiguredError";
64
+ } & Readonly<A>;
65
+ /**
66
+ * Error when OAuth is not configured.
67
+ *
68
+ * @category Errors
69
+ */
70
+ export declare class OAuthNotConfiguredError extends OAuthNotConfiguredError_base<{
71
+ readonly tool?: string;
72
+ }> {
73
+ get message(): string;
74
+ }
75
+ export {};
76
+ //# sourceMappingURL=OAuthErrors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthErrors.d.ts","sourceRoot":"","sources":["../../src/auth/OAuthErrors.ts"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;;;;AAE9G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAQ7B;CACF;;;;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAiB,SAAQ,sBAAqC;IACzE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAG7B;CACF;;;;AAED;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,6BAA4C;IACvF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAG7B;CACF"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Tagged error types for Atlassian OAuth2 flows.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Step-scoped errors**: {@link OAuthError} carries a `step` field (`"configure" | "authorize" |
7
+ * "token" | "refresh" | "revoke"`) so callers can handle failures per-phase.
8
+ * - **Companion errors**: {@link AuthMissingError} (not logged in) and
9
+ * {@link OAuthNotConfiguredError} (no client credentials) represent pre-flow failures.
10
+ *
11
+ * **Gotchas**
12
+ *
13
+ * - `OAuthError.message` is a computed getter derived from `step` + `cause` — it's not
14
+ * a stored field, so don't destructure it from the constructor.
15
+ *
16
+ * @module
17
+ */
18
+ import * as Data from "effect/Data";
19
+ /**
20
+ * Error during OAuth2 flow.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { Effect } from "effect"
25
+ * import { OAuthError } from "@knpkv/atlassian-common/auth"
26
+ *
27
+ * Effect.gen(function* () {
28
+ * // ... oauth operation
29
+ * }).pipe(
30
+ * Effect.catchTag("OAuthError", (error) =>
31
+ * Effect.sync(() => console.error(`OAuth error at ${error.step}: ${error.message}`))
32
+ * )
33
+ * )
34
+ * ```
35
+ *
36
+ * @category Errors
37
+ */
38
+ export class OAuthError extends Data.TaggedError("OAuthError") {
39
+ get message() {
40
+ if (this.cause instanceof Error) {
41
+ return `OAuth ${this.step} failed: ${this.cause.message}`;
42
+ }
43
+ if (typeof this.cause === "string") {
44
+ return `OAuth ${this.step} failed: ${this.cause}`;
45
+ }
46
+ return `OAuth ${this.step} failed`;
47
+ }
48
+ }
49
+ /**
50
+ * Error when authentication is missing.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * import { Effect } from "effect"
55
+ * import { AuthMissingError } from "@knpkv/atlassian-common/auth"
56
+ *
57
+ * Effect.gen(function* () {
58
+ * // ... requires auth
59
+ * }).pipe(
60
+ * Effect.catchTag("AuthMissingError", () =>
61
+ * Effect.sync(() => console.error("Please login first"))
62
+ * )
63
+ * )
64
+ * ```
65
+ *
66
+ * @category Errors
67
+ */
68
+ export class AuthMissingError extends Data.TaggedError("AuthMissingError") {
69
+ get message() {
70
+ const toolPart = this.tool ? ` for ${this.tool}` : "";
71
+ return `Not logged in${toolPart}. Please run 'auth login' first.`;
72
+ }
73
+ }
74
+ /**
75
+ * Error when OAuth is not configured.
76
+ *
77
+ * @category Errors
78
+ */
79
+ export class OAuthNotConfiguredError extends Data.TaggedError("OAuthNotConfiguredError") {
80
+ get message() {
81
+ const toolPart = this.tool ? `'${this.tool} auth configure'` : "'auth configure'";
82
+ return `OAuth not configured. Run ${toolPart} first.`;
83
+ }
84
+ }
85
+ //# sourceMappingURL=OAuthErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthErrors.js","sourceRoot":"","sources":["../../src/auth/OAuthErrors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AASnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,UAAW,SAAQ,IAAI,CAAC,WAAW,CAAC,YAAY,CAG3D;IACA,IAAa,OAAO;QAClB,IAAI,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE,CAAC;YAChC,OAAO,SAAS,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAA;QAC3D,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,SAAS,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,KAAK,EAAE,CAAA;QACnD,CAAC;QACD,OAAO,SAAS,IAAI,CAAC,IAAI,SAAS,CAAA;IACpC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,gBAAiB,SAAQ,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAEvE;IACA,IAAa,OAAO;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACrD,OAAO,gBAAgB,QAAQ,kCAAkC,CAAA;IACnE,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,uBAAwB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAErF;IACA,IAAa,OAAO;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAA;QACjF,OAAO,6BAA6B,QAAQ,SAAS,CAAA;IACvD,CAAC;CACF"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Core OAuth2 operations against Atlassian's token and resource endpoints.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Effect-native HTTP**: Every operation takes an `HttpClient` from the Effect
7
+ * context and returns `Effect<A, OAuthError, HttpClient>`. Callers provide the
8
+ * client via `Layer.succeed`.
9
+ * - **Schema-validated responses**: Token and user payloads are decoded through
10
+ * Effect Schema before returning, catching API contract drift at runtime.
11
+ *
12
+ * **Common tasks**
13
+ *
14
+ * - Exchange auth code: {@link exchangeCodeForTokens}
15
+ * - List user sites: {@link getAccessibleResources}
16
+ * - Refresh expired token: {@link refreshToken}
17
+ * - Build storable token: {@link buildOAuthToken}
18
+ *
19
+ * @module
20
+ */
21
+ import * as HttpClient from "@effect/platform/HttpClient";
22
+ import * as Effect from "effect/Effect";
23
+ import { type OAuthConfig, type OAuthToken } from "../config/OAuthSchemas.js";
24
+ import { OAuthError } from "./OAuthErrors.js";
25
+ import { type AccessibleResource, type TokenResponse, type UserInfo } from "./OAuthResponseSchemas.js";
26
+ /**
27
+ * Options for exchanging an authorization code for tokens.
28
+ *
29
+ * @category Types
30
+ */
31
+ export interface ExchangeCodeOptions {
32
+ /** Local callback server port (for redirect_uri) */
33
+ readonly port: number;
34
+ /** PKCE code verifier (if PKCE was used in auth request) */
35
+ readonly codeVerifier?: string | undefined;
36
+ }
37
+ /**
38
+ * Exchange authorization code for tokens.
39
+ *
40
+ * @category Operations
41
+ */
42
+ export declare const exchangeCodeForTokens: (code: string, config: OAuthConfig, options: ExchangeCodeOptions) => Effect.Effect<TokenResponse, OAuthError, HttpClient.HttpClient>;
43
+ /**
44
+ * Get accessible resources (sites) for the authenticated user.
45
+ *
46
+ * @param accessToken - OAuth access token
47
+ *
48
+ * @category Operations
49
+ */
50
+ export declare const getAccessibleResources: (accessToken: string) => Effect.Effect<ReadonlyArray<AccessibleResource>, OAuthError, HttpClient.HttpClient>;
51
+ /**
52
+ * Get user info from /me endpoint.
53
+ *
54
+ * @param accessToken - OAuth access token
55
+ *
56
+ * @category Operations
57
+ */
58
+ export declare const getUserInfo: (accessToken: string) => Effect.Effect<UserInfo, OAuthError, HttpClient.HttpClient>;
59
+ /**
60
+ * Refresh an expired OAuth token.
61
+ *
62
+ * @param token - Current OAuth token (with refresh_token)
63
+ * @param config - OAuth client configuration
64
+ *
65
+ * @category Operations
66
+ */
67
+ export declare const refreshToken: (token: OAuthToken, config: OAuthConfig) => Effect.Effect<OAuthToken, OAuthError, HttpClient.HttpClient>;
68
+ /**
69
+ * Revoke an OAuth token.
70
+ *
71
+ * @param token - OAuth token to revoke
72
+ * @param config - OAuth client configuration
73
+ *
74
+ * @category Operations
75
+ */
76
+ export declare const revokeToken: (token: OAuthToken, config: OAuthConfig) => Effect.Effect<void, OAuthError, HttpClient.HttpClient>;
77
+ /**
78
+ * Build OAuthToken from token response and site info.
79
+ *
80
+ * @param tokenResponse - Token response from exchange
81
+ * @param site - Selected accessible resource
82
+ * @param user - User info
83
+ *
84
+ * @category Utilities
85
+ */
86
+ export declare const buildOAuthToken: (tokenResponse: TokenResponse, site: AccessibleResource, user: UserInfo) => OAuthToken;
87
+ //# sourceMappingURL=OAuthOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthOperations.d.ts","sourceRoot":"","sources":["../../src/auth/OAuthOperations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,UAAU,MAAM,6BAA6B,CAAA;AAEzD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,aAAa,EAElB,KAAK,QAAQ,EAEd,MAAM,2BAA2B,CAAA;AAElC;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,QAAQ,WAAW,EACnB,SAAS,mBAAmB,KAC3B,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,CA+B9D,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,MAAM,KAClB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,CAuBlF,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,aAAa,MAAM,KAClB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,CAuBzD,CAAA;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,QAAQ,WAAW,KAClB,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,CAyC1D,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,UAAU,EACjB,QAAQ,WAAW,KAClB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,CAyBpD,CAAA;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,aAAa,EAC5B,MAAM,kBAAkB,EACxB,MAAM,QAAQ,KACb,UAYD,CAAA"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Core OAuth2 operations against Atlassian's token and resource endpoints.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Effect-native HTTP**: Every operation takes an `HttpClient` from the Effect
7
+ * context and returns `Effect<A, OAuthError, HttpClient>`. Callers provide the
8
+ * client via `Layer.succeed`.
9
+ * - **Schema-validated responses**: Token and user payloads are decoded through
10
+ * Effect Schema before returning, catching API contract drift at runtime.
11
+ *
12
+ * **Common tasks**
13
+ *
14
+ * - Exchange auth code: {@link exchangeCodeForTokens}
15
+ * - List user sites: {@link getAccessibleResources}
16
+ * - Refresh expired token: {@link refreshToken}
17
+ * - Build storable token: {@link buildOAuthToken}
18
+ *
19
+ * @module
20
+ */
21
+ import * as HttpClient from "@effect/platform/HttpClient";
22
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
23
+ import * as Effect from "effect/Effect";
24
+ import * as Schema from "effect/Schema";
25
+ import {} from "../config/OAuthSchemas.js";
26
+ import { ME_URL, RESOURCES_URL, REVOKE_URL, TOKEN_URL } from "./OAuthEndpoints.js";
27
+ import { OAuthError } from "./OAuthErrors.js";
28
+ import { AccessibleResourceSchema, TokenResponseSchema, UserInfoSchema } from "./OAuthResponseSchemas.js";
29
+ /**
30
+ * Exchange authorization code for tokens.
31
+ *
32
+ * @category Operations
33
+ */
34
+ export const exchangeCodeForTokens = (code, config, options) => Effect.gen(function* () {
35
+ const httpClient = yield* HttpClient.HttpClient;
36
+ const tokenBody = {
37
+ grant_type: "authorization_code",
38
+ client_id: config.clientId,
39
+ client_secret: config.clientSecret,
40
+ code,
41
+ redirect_uri: `http://localhost:${options.port}/callback`
42
+ };
43
+ if (options.codeVerifier)
44
+ tokenBody.code_verifier = options.codeVerifier;
45
+ const request = yield* HttpClientRequest.post(TOKEN_URL).pipe(HttpClientRequest.setHeader("Content-Type", "application/json"), HttpClientRequest.bodyJson(tokenBody));
46
+ const response = yield* httpClient.execute(request);
47
+ if (response.status >= 400) {
48
+ const text = yield* response.text;
49
+ yield* Effect.logDebug(`Token exchange failed (${response.status}): ${text}`);
50
+ return yield* Effect.fail(new OAuthError({ step: "token", cause: `HTTP ${response.status}` }));
51
+ }
52
+ const body = yield* response.json;
53
+ return yield* Schema.decodeUnknown(TokenResponseSchema)(body);
54
+ }).pipe(Effect.mapError((cause) => new OAuthError({ step: "token", cause })));
55
+ /**
56
+ * Get accessible resources (sites) for the authenticated user.
57
+ *
58
+ * @param accessToken - OAuth access token
59
+ *
60
+ * @category Operations
61
+ */
62
+ export const getAccessibleResources = (accessToken) => Effect.gen(function* () {
63
+ const httpClient = yield* HttpClient.HttpClient;
64
+ const request = HttpClientRequest.get(RESOURCES_URL).pipe(HttpClientRequest.setHeader("Authorization", `Bearer ${accessToken}`), HttpClientRequest.setHeader("Accept", "application/json"));
65
+ const response = yield* httpClient.execute(request);
66
+ if (response.status >= 400) {
67
+ const text = yield* response.text;
68
+ yield* Effect.logDebug(`Accessible resources failed (${response.status}): ${text}`);
69
+ return yield* Effect.fail(new OAuthError({ step: "resources", cause: `HTTP ${response.status}` }));
70
+ }
71
+ const body = yield* response.json;
72
+ return yield* Schema.decodeUnknown(Schema.Array(AccessibleResourceSchema))(body);
73
+ }).pipe(Effect.mapError((cause) => new OAuthError({ step: "resources", cause })));
74
+ /**
75
+ * Get user info from /me endpoint.
76
+ *
77
+ * @param accessToken - OAuth access token
78
+ *
79
+ * @category Operations
80
+ */
81
+ export const getUserInfo = (accessToken) => Effect.gen(function* () {
82
+ const httpClient = yield* HttpClient.HttpClient;
83
+ const request = HttpClientRequest.get(ME_URL).pipe(HttpClientRequest.setHeader("Authorization", `Bearer ${accessToken}`), HttpClientRequest.setHeader("Accept", "application/json"));
84
+ const response = yield* httpClient.execute(request);
85
+ if (response.status >= 400) {
86
+ const text = yield* response.text;
87
+ yield* Effect.logDebug(`User info failed (${response.status}): ${text}`);
88
+ return yield* Effect.fail(new OAuthError({ step: "user-info", cause: `HTTP ${response.status}` }));
89
+ }
90
+ const body = yield* response.json;
91
+ return yield* Schema.decodeUnknown(UserInfoSchema)(body);
92
+ }).pipe(Effect.mapError((cause) => new OAuthError({ step: "user-info", cause })));
93
+ /**
94
+ * Refresh an expired OAuth token.
95
+ *
96
+ * @param token - Current OAuth token (with refresh_token)
97
+ * @param config - OAuth client configuration
98
+ *
99
+ * @category Operations
100
+ */
101
+ export const refreshToken = (token, config) => Effect.gen(function* () {
102
+ const httpClient = yield* HttpClient.HttpClient;
103
+ const request = yield* HttpClientRequest.post(TOKEN_URL).pipe(HttpClientRequest.setHeader("Content-Type", "application/json"), HttpClientRequest.bodyJson({
104
+ grant_type: "refresh_token",
105
+ client_id: config.clientId,
106
+ client_secret: config.clientSecret,
107
+ refresh_token: token.refresh_token
108
+ }), Effect.mapError((cause) => new OAuthError({ step: "refresh", cause })));
109
+ const response = yield* httpClient.execute(request).pipe(Effect.mapError((cause) => new OAuthError({ step: "refresh", cause })));
110
+ if (response.status >= 400) {
111
+ const text = yield* response.text.pipe(Effect.mapError((cause) => new OAuthError({ step: "refresh", cause })));
112
+ return yield* Effect.fail(new OAuthError({ step: "refresh", cause: `HTTP ${response.status}: ${text}` }));
113
+ }
114
+ const body = yield* response.json.pipe(Effect.mapError((cause) => new OAuthError({ step: "refresh", cause })));
115
+ const tokenResponse = yield* Schema.decodeUnknown(TokenResponseSchema)(body).pipe(Effect.mapError((cause) => new OAuthError({ step: "refresh", cause })));
116
+ return {
117
+ ...token,
118
+ access_token: tokenResponse.access_token,
119
+ refresh_token: tokenResponse.refresh_token,
120
+ expires_at: Date.now() + tokenResponse.expires_in * 1000,
121
+ scope: tokenResponse.scope
122
+ };
123
+ });
124
+ /**
125
+ * Revoke an OAuth token.
126
+ *
127
+ * @param token - OAuth token to revoke
128
+ * @param config - OAuth client configuration
129
+ *
130
+ * @category Operations
131
+ */
132
+ export const revokeToken = (token, config) => Effect.gen(function* () {
133
+ const httpClient = yield* HttpClient.HttpClient;
134
+ const request = yield* HttpClientRequest.post(REVOKE_URL).pipe(HttpClientRequest.setHeader("Content-Type", "application/json"), HttpClientRequest.bodyJson({
135
+ client_id: config.clientId,
136
+ client_secret: config.clientSecret,
137
+ token: token.refresh_token
138
+ }), Effect.mapError((cause) => new OAuthError({ step: "revoke", cause })));
139
+ const response = yield* httpClient.execute(request).pipe(Effect.mapError((cause) => new OAuthError({ step: "revoke", cause })));
140
+ if (response.status >= 400) {
141
+ return yield* Effect.fail(new OAuthError({
142
+ step: "revoke",
143
+ cause: `Token revocation failed with status ${response.status}`
144
+ }));
145
+ }
146
+ });
147
+ /**
148
+ * Build OAuthToken from token response and site info.
149
+ *
150
+ * @param tokenResponse - Token response from exchange
151
+ * @param site - Selected accessible resource
152
+ * @param user - User info
153
+ *
154
+ * @category Utilities
155
+ */
156
+ export const buildOAuthToken = (tokenResponse, site, user) => ({
157
+ access_token: tokenResponse.access_token,
158
+ refresh_token: tokenResponse.refresh_token,
159
+ expires_at: Date.now() + tokenResponse.expires_in * 1000,
160
+ scope: tokenResponse.scope,
161
+ cloud_id: site.id,
162
+ site_url: site.url,
163
+ user: {
164
+ account_id: user.account_id,
165
+ name: user.name,
166
+ email: user.email
167
+ }
168
+ });
169
+ //# sourceMappingURL=OAuthOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthOperations.js","sourceRoot":"","sources":["../../src/auth/OAuthOperations.ts"],"names":[],"mappings":"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"}