@fractary/core 0.3.2 → 0.4.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 (122) hide show
  1. package/dist/__tests__/factories.test.d.ts +5 -0
  2. package/dist/__tests__/factories.test.d.ts.map +1 -0
  3. package/dist/__tests__/factories.test.js +66 -0
  4. package/dist/__tests__/factories.test.js.map +1 -0
  5. package/dist/auth/__tests__/create-token-provider.test.d.ts +5 -0
  6. package/dist/auth/__tests__/create-token-provider.test.d.ts.map +1 -0
  7. package/dist/auth/__tests__/create-token-provider.test.js +104 -0
  8. package/dist/auth/__tests__/create-token-provider.test.js.map +1 -0
  9. package/dist/auth/__tests__/github-app-auth.test.d.ts +5 -0
  10. package/dist/auth/__tests__/github-app-auth.test.d.ts.map +1 -0
  11. package/dist/auth/__tests__/github-app-auth.test.js +293 -0
  12. package/dist/auth/__tests__/github-app-auth.test.js.map +1 -0
  13. package/dist/auth/__tests__/static-token-provider.test.d.ts +5 -0
  14. package/dist/auth/__tests__/static-token-provider.test.d.ts.map +1 -0
  15. package/dist/auth/__tests__/static-token-provider.test.js +54 -0
  16. package/dist/auth/__tests__/static-token-provider.test.js.map +1 -0
  17. package/dist/auth/github-app-auth.d.ts +109 -0
  18. package/dist/auth/github-app-auth.d.ts.map +1 -0
  19. package/dist/auth/github-app-auth.js +262 -0
  20. package/dist/auth/github-app-auth.js.map +1 -0
  21. package/dist/auth/github-app-token-provider.d.ts +59 -0
  22. package/dist/auth/github-app-token-provider.d.ts.map +1 -0
  23. package/dist/auth/github-app-token-provider.js +68 -0
  24. package/dist/auth/github-app-token-provider.js.map +1 -0
  25. package/dist/auth/index.d.ts +45 -0
  26. package/dist/auth/index.d.ts.map +1 -0
  27. package/dist/auth/index.js +74 -0
  28. package/dist/auth/index.js.map +1 -0
  29. package/dist/auth/static-token-provider.d.ts +35 -0
  30. package/dist/auth/static-token-provider.d.ts.map +1 -0
  31. package/dist/auth/static-token-provider.js +45 -0
  32. package/dist/auth/static-token-provider.js.map +1 -0
  33. package/dist/auth/types.d.ts +49 -0
  34. package/dist/auth/types.d.ts.map +1 -0
  35. package/dist/auth/types.js +8 -0
  36. package/dist/auth/types.js.map +1 -0
  37. package/dist/common/yaml-config.d.ts +10 -0
  38. package/dist/common/yaml-config.d.ts.map +1 -1
  39. package/dist/common/yaml-config.js.map +1 -1
  40. package/dist/config/__tests__/loader.test.d.ts +5 -0
  41. package/dist/config/__tests__/loader.test.d.ts.map +1 -0
  42. package/dist/config/__tests__/loader.test.js +129 -0
  43. package/dist/config/__tests__/loader.test.js.map +1 -0
  44. package/dist/config/index.d.ts +8 -0
  45. package/dist/config/index.d.ts.map +1 -0
  46. package/dist/config/index.js +27 -0
  47. package/dist/config/index.js.map +1 -0
  48. package/dist/config/loader.d.ts +126 -0
  49. package/dist/config/loader.d.ts.map +1 -0
  50. package/dist/config/loader.js +277 -0
  51. package/dist/config/loader.js.map +1 -0
  52. package/dist/docs/index.d.ts +5 -0
  53. package/dist/docs/index.d.ts.map +1 -1
  54. package/dist/docs/index.js +6 -1
  55. package/dist/docs/index.js.map +1 -1
  56. package/dist/docs/manager.d.ts +27 -0
  57. package/dist/docs/manager.d.ts.map +1 -1
  58. package/dist/docs/manager.js +168 -15
  59. package/dist/docs/manager.js.map +1 -1
  60. package/dist/docs/type-registry.d.ts +123 -0
  61. package/dist/docs/type-registry.d.ts.map +1 -0
  62. package/dist/docs/type-registry.js +393 -0
  63. package/dist/docs/type-registry.js.map +1 -0
  64. package/dist/docs/types.d.ts +93 -0
  65. package/dist/docs/types.d.ts.map +1 -1
  66. package/dist/factories.d.ts +89 -0
  67. package/dist/factories.d.ts.map +1 -0
  68. package/dist/factories.js +228 -0
  69. package/dist/factories.js.map +1 -0
  70. package/dist/file/factory.d.ts +41 -0
  71. package/dist/file/factory.d.ts.map +1 -0
  72. package/dist/file/factory.js +237 -0
  73. package/dist/file/factory.js.map +1 -0
  74. package/dist/file/gcs.d.ts +66 -0
  75. package/dist/file/gcs.d.ts.map +1 -0
  76. package/dist/file/gcs.js +226 -0
  77. package/dist/file/gcs.js.map +1 -0
  78. package/dist/file/gdrive.d.ts +78 -0
  79. package/dist/file/gdrive.d.ts.map +1 -0
  80. package/dist/file/gdrive.js +302 -0
  81. package/dist/file/gdrive.js.map +1 -0
  82. package/dist/file/index.d.ts +13 -1
  83. package/dist/file/index.d.ts.map +1 -1
  84. package/dist/file/index.js +25 -1
  85. package/dist/file/index.js.map +1 -1
  86. package/dist/file/manager.d.ts +83 -2
  87. package/dist/file/manager.d.ts.map +1 -1
  88. package/dist/file/manager.js +125 -4
  89. package/dist/file/manager.js.map +1 -1
  90. package/dist/file/r2.d.ts +56 -0
  91. package/dist/file/r2.d.ts.map +1 -0
  92. package/dist/file/r2.js +96 -0
  93. package/dist/file/r2.js.map +1 -0
  94. package/dist/file/s3.d.ts +61 -0
  95. package/dist/file/s3.d.ts.map +1 -0
  96. package/dist/file/s3.js +258 -0
  97. package/dist/file/s3.js.map +1 -0
  98. package/dist/file/types.d.ts +145 -2
  99. package/dist/file/types.d.ts.map +1 -1
  100. package/dist/index.d.ts +3 -0
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +6 -0
  103. package/dist/index.js.map +1 -1
  104. package/dist/logs/index.d.ts +1 -0
  105. package/dist/logs/index.d.ts.map +1 -1
  106. package/dist/logs/index.js +3 -1
  107. package/dist/logs/index.js.map +1 -1
  108. package/dist/logs/manager.d.ts +29 -2
  109. package/dist/logs/manager.d.ts.map +1 -1
  110. package/dist/logs/manager.js +48 -7
  111. package/dist/logs/manager.js.map +1 -1
  112. package/dist/logs/type-registry.d.ts +180 -0
  113. package/dist/logs/type-registry.d.ts.map +1 -0
  114. package/dist/logs/type-registry.js +421 -0
  115. package/dist/logs/type-registry.js.map +1 -0
  116. package/dist/logs/type-registry.test.d.ts +5 -0
  117. package/dist/logs/type-registry.test.d.ts.map +1 -0
  118. package/dist/logs/type-registry.test.js +671 -0
  119. package/dist/logs/type-registry.test.js.map +1 -0
  120. package/dist/logs/types.d.ts +2 -0
  121. package/dist/logs/types.d.ts.map +1 -1
  122. package/package.json +62 -8
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @fractary/core - GitHub App Authentication
3
+ *
4
+ * Full GitHub App authentication with JWT generation, token exchange, and caching.
5
+ */
6
+ import type { GitHubAppConfig } from './types';
7
+ /**
8
+ * GitHub App authentication handler
9
+ *
10
+ * Handles the complete GitHub App authentication flow:
11
+ * 1. Generates JWT signed with the app's private key
12
+ * 2. Exchanges JWT for an installation access token via GitHub API
13
+ * 3. Caches tokens and auto-refreshes before expiration
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const auth = new GitHubAppAuth({
18
+ * id: '123456',
19
+ * installation_id: '789012',
20
+ * private_key_path: '/path/to/private-key.pem'
21
+ * });
22
+ *
23
+ * const token = await auth.getInstallationToken();
24
+ * ```
25
+ */
26
+ export declare class GitHubAppAuth {
27
+ private readonly config;
28
+ private readonly privateKey;
29
+ private cachedToken;
30
+ /** In-flight token request promise (for race condition prevention) */
31
+ private pendingTokenRequest;
32
+ /** Token refresh buffer - refresh 5 minutes before expiration */
33
+ private static readonly REFRESH_BUFFER_MS;
34
+ /** JWT expiration time - 10 minutes (GitHub's maximum) */
35
+ private static readonly JWT_EXPIRATION_SECONDS;
36
+ /**
37
+ * Create a new GitHub App authentication handler
38
+ *
39
+ * @param config GitHub App configuration
40
+ * @throws AuthenticationError if private key cannot be loaded
41
+ */
42
+ constructor(config: GitHubAppConfig);
43
+ /**
44
+ * Load private key from file or environment variable
45
+ *
46
+ * @returns The PEM-encoded private key
47
+ * @throws AuthenticationError if private key cannot be loaded
48
+ */
49
+ private loadPrivateKey;
50
+ /**
51
+ * Generate a JWT for GitHub App authentication
52
+ *
53
+ * The JWT is signed with the app's private key using RS256.
54
+ *
55
+ * @returns Signed JWT string
56
+ */
57
+ private generateJWT;
58
+ /**
59
+ * Exchange JWT for an installation access token
60
+ *
61
+ * @returns Installation access token response from GitHub
62
+ * @throws AuthenticationError if token exchange fails
63
+ */
64
+ private exchangeJWTForToken;
65
+ /**
66
+ * Check if the cached token is still valid
67
+ *
68
+ * A token is considered valid if it exists and won't expire within
69
+ * the refresh buffer window (5 minutes).
70
+ *
71
+ * @returns true if cached token is valid and not near expiration
72
+ */
73
+ private isCachedTokenValid;
74
+ /**
75
+ * Get a valid installation access token
76
+ *
77
+ * Returns a cached token if still valid, otherwise generates a new one.
78
+ * Tokens are automatically refreshed 5 minutes before expiration.
79
+ *
80
+ * Thread-safe: concurrent calls will share the same pending request
81
+ * to prevent redundant API calls and potential rate limiting.
82
+ *
83
+ * @returns Installation access token string
84
+ * @throws AuthenticationError if token cannot be obtained
85
+ */
86
+ getInstallationToken(): Promise<string>;
87
+ /**
88
+ * Internal method to fetch and cache token
89
+ * Separated from getInstallationToken to enable promise sharing
90
+ */
91
+ private fetchAndCacheToken;
92
+ /**
93
+ * Clear the cached token
94
+ *
95
+ * Forces the next getInstallationToken() call to fetch a fresh token.
96
+ * Note: Does not cancel any in-flight request.
97
+ */
98
+ clearCache(): void;
99
+ /**
100
+ * Get information about the cached token (for debugging)
101
+ *
102
+ * @returns Object with cache status, or null if no cached token
103
+ */
104
+ getCacheInfo(): {
105
+ expiresAt: Date;
106
+ isValid: boolean;
107
+ } | null;
108
+ }
109
+ //# sourceMappingURL=github-app-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-auth.d.ts","sourceRoot":"","sources":["../../src/auth/github-app-auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAW/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,WAAW,CAA4B;IAE/C,sEAAsE;IACtE,OAAO,CAAC,mBAAmB,CAAgC;IAE3D,iEAAiE;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAE1D,0DAA0D;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAO;IAErD;;;;;OAKG;gBACS,MAAM,EAAE,eAAe;IAKnC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAoDtB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAenB;;;;;OAKG;YACW,mBAAmB;IAiCjC;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;;;;;OAWG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAuB7C;;;OAGG;YACW,kBAAkB;IAahC;;;;;OAKG;IACH,UAAU,IAAI,IAAI;IAKlB;;;;OAIG;IACH,YAAY,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;CAQ7D"}
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ /**
3
+ * @fractary/core - GitHub App Authentication
4
+ *
5
+ * Full GitHub App authentication with JWT generation, token exchange, and caching.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.GitHubAppAuth = void 0;
42
+ const fs = __importStar(require("fs"));
43
+ const jwt = __importStar(require("jsonwebtoken"));
44
+ const errors_1 = require("../common/errors");
45
+ /**
46
+ * GitHub App authentication handler
47
+ *
48
+ * Handles the complete GitHub App authentication flow:
49
+ * 1. Generates JWT signed with the app's private key
50
+ * 2. Exchanges JWT for an installation access token via GitHub API
51
+ * 3. Caches tokens and auto-refreshes before expiration
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const auth = new GitHubAppAuth({
56
+ * id: '123456',
57
+ * installation_id: '789012',
58
+ * private_key_path: '/path/to/private-key.pem'
59
+ * });
60
+ *
61
+ * const token = await auth.getInstallationToken();
62
+ * ```
63
+ */
64
+ class GitHubAppAuth {
65
+ config;
66
+ privateKey;
67
+ cachedToken = null;
68
+ /** In-flight token request promise (for race condition prevention) */
69
+ pendingTokenRequest = null;
70
+ /** Token refresh buffer - refresh 5 minutes before expiration */
71
+ static REFRESH_BUFFER_MS = 5 * 60 * 1000;
72
+ /** JWT expiration time - 10 minutes (GitHub's maximum) */
73
+ static JWT_EXPIRATION_SECONDS = 600;
74
+ /**
75
+ * Create a new GitHub App authentication handler
76
+ *
77
+ * @param config GitHub App configuration
78
+ * @throws AuthenticationError if private key cannot be loaded
79
+ */
80
+ constructor(config) {
81
+ this.config = config;
82
+ this.privateKey = this.loadPrivateKey();
83
+ }
84
+ /**
85
+ * Load private key from file or environment variable
86
+ *
87
+ * @returns The PEM-encoded private key
88
+ * @throws AuthenticationError if private key cannot be loaded
89
+ */
90
+ loadPrivateKey() {
91
+ // Try loading from file path first
92
+ if (this.config.private_key_path) {
93
+ try {
94
+ const keyPath = this.config.private_key_path;
95
+ if (!fs.existsSync(keyPath)) {
96
+ throw new errors_1.AuthenticationError('github-app', `Private key file not found: ${keyPath}`);
97
+ }
98
+ return fs.readFileSync(keyPath, 'utf-8');
99
+ }
100
+ catch (error) {
101
+ if (error instanceof errors_1.AuthenticationError)
102
+ throw error;
103
+ throw new errors_1.AuthenticationError('github-app', `Failed to read private key file: ${error.message}`);
104
+ }
105
+ }
106
+ // Try loading from environment variable (base64-encoded)
107
+ if (this.config.private_key_env_var) {
108
+ const envValue = process.env[this.config.private_key_env_var];
109
+ if (!envValue) {
110
+ throw new errors_1.AuthenticationError('github-app', `Environment variable ${this.config.private_key_env_var} is not set`);
111
+ }
112
+ try {
113
+ // Decode base64-encoded private key
114
+ const decoded = Buffer.from(envValue, 'base64').toString('utf-8');
115
+ if (!decoded.includes('-----BEGIN')) {
116
+ throw new Error('Decoded value does not appear to be a PEM key');
117
+ }
118
+ return decoded;
119
+ }
120
+ catch (error) {
121
+ throw new errors_1.AuthenticationError('github-app', `Failed to decode private key from ${this.config.private_key_env_var}: ${error.message}`);
122
+ }
123
+ }
124
+ throw new errors_1.AuthenticationError('github-app', 'GitHub App config must specify either private_key_path or private_key_env_var');
125
+ }
126
+ /**
127
+ * Generate a JWT for GitHub App authentication
128
+ *
129
+ * The JWT is signed with the app's private key using RS256.
130
+ *
131
+ * @returns Signed JWT string
132
+ */
133
+ generateJWT() {
134
+ const now = Math.floor(Date.now() / 1000);
135
+ const payload = {
136
+ // Issued at time (60 seconds in the past to account for clock drift)
137
+ iat: now - 60,
138
+ // Expiration time (10 minutes from now)
139
+ exp: now + GitHubAppAuth.JWT_EXPIRATION_SECONDS,
140
+ // GitHub App's identifier
141
+ iss: this.config.id,
142
+ };
143
+ return jwt.sign(payload, this.privateKey, { algorithm: 'RS256' });
144
+ }
145
+ /**
146
+ * Exchange JWT for an installation access token
147
+ *
148
+ * @returns Installation access token response from GitHub
149
+ * @throws AuthenticationError if token exchange fails
150
+ */
151
+ async exchangeJWTForToken() {
152
+ const jwtToken = this.generateJWT();
153
+ const url = `https://api.github.com/app/installations/${this.config.installation_id}/access_tokens`;
154
+ try {
155
+ const response = await fetch(url, {
156
+ method: 'POST',
157
+ headers: {
158
+ 'Accept': 'application/vnd.github+json',
159
+ 'Authorization': `Bearer ${jwtToken}`,
160
+ 'X-GitHub-Api-Version': '2022-11-28',
161
+ },
162
+ });
163
+ if (!response.ok) {
164
+ const errorBody = await response.text();
165
+ throw new errors_1.AuthenticationError('github-app', `GitHub API returned ${response.status}: ${errorBody}`);
166
+ }
167
+ const data = await response.json();
168
+ return data;
169
+ }
170
+ catch (error) {
171
+ if (error instanceof errors_1.AuthenticationError)
172
+ throw error;
173
+ throw new errors_1.AuthenticationError('github-app', `Failed to exchange JWT for installation token: ${error.message}`);
174
+ }
175
+ }
176
+ /**
177
+ * Check if the cached token is still valid
178
+ *
179
+ * A token is considered valid if it exists and won't expire within
180
+ * the refresh buffer window (5 minutes).
181
+ *
182
+ * @returns true if cached token is valid and not near expiration
183
+ */
184
+ isCachedTokenValid() {
185
+ if (!this.cachedToken)
186
+ return false;
187
+ const now = new Date();
188
+ const expirationWithBuffer = new Date(this.cachedToken.expiresAt.getTime() - GitHubAppAuth.REFRESH_BUFFER_MS);
189
+ return now < expirationWithBuffer;
190
+ }
191
+ /**
192
+ * Get a valid installation access token
193
+ *
194
+ * Returns a cached token if still valid, otherwise generates a new one.
195
+ * Tokens are automatically refreshed 5 minutes before expiration.
196
+ *
197
+ * Thread-safe: concurrent calls will share the same pending request
198
+ * to prevent redundant API calls and potential rate limiting.
199
+ *
200
+ * @returns Installation access token string
201
+ * @throws AuthenticationError if token cannot be obtained
202
+ */
203
+ async getInstallationToken() {
204
+ // Return cached token if still valid
205
+ if (this.isCachedTokenValid()) {
206
+ return this.cachedToken.token;
207
+ }
208
+ // If there's already a pending request, wait for it
209
+ // This prevents multiple concurrent calls from triggering multiple API requests
210
+ if (this.pendingTokenRequest) {
211
+ return this.pendingTokenRequest;
212
+ }
213
+ // Create a new token request and track it
214
+ this.pendingTokenRequest = this.fetchAndCacheToken();
215
+ try {
216
+ return await this.pendingTokenRequest;
217
+ }
218
+ finally {
219
+ // Clear the pending request once complete (success or failure)
220
+ this.pendingTokenRequest = null;
221
+ }
222
+ }
223
+ /**
224
+ * Internal method to fetch and cache token
225
+ * Separated from getInstallationToken to enable promise sharing
226
+ */
227
+ async fetchAndCacheToken() {
228
+ // Exchange JWT for new installation token
229
+ const response = await this.exchangeJWTForToken();
230
+ // Cache the token
231
+ this.cachedToken = {
232
+ token: response.token,
233
+ expiresAt: new Date(response.expires_at),
234
+ };
235
+ return response.token;
236
+ }
237
+ /**
238
+ * Clear the cached token
239
+ *
240
+ * Forces the next getInstallationToken() call to fetch a fresh token.
241
+ * Note: Does not cancel any in-flight request.
242
+ */
243
+ clearCache() {
244
+ this.cachedToken = null;
245
+ this.pendingTokenRequest = null;
246
+ }
247
+ /**
248
+ * Get information about the cached token (for debugging)
249
+ *
250
+ * @returns Object with cache status, or null if no cached token
251
+ */
252
+ getCacheInfo() {
253
+ if (!this.cachedToken)
254
+ return null;
255
+ return {
256
+ expiresAt: this.cachedToken.expiresAt,
257
+ isValid: this.isCachedTokenValid(),
258
+ };
259
+ }
260
+ }
261
+ exports.GitHubAppAuth = GitHubAppAuth;
262
+ //# sourceMappingURL=github-app-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-auth.js","sourceRoot":"","sources":["../../src/auth/github-app-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fractary/core - GitHub App Token Provider
3
+ *
4
+ * TokenProvider implementation that wraps GitHubAppAuth.
5
+ */
6
+ import type { TokenProvider, GitHubAppConfig } from './types';
7
+ /**
8
+ * GitHub App token provider
9
+ *
10
+ * Implements the TokenProvider interface using GitHub App authentication.
11
+ * Wraps GitHubAppAuth to provide automatic token caching and refresh.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const provider = new GitHubAppTokenProvider({
16
+ * id: '123456',
17
+ * installation_id: '789012',
18
+ * private_key_path: '/path/to/private-key.pem'
19
+ * });
20
+ *
21
+ * const token = await provider.getToken();
22
+ * ```
23
+ */
24
+ export declare class GitHubAppTokenProvider implements TokenProvider {
25
+ private readonly auth;
26
+ /**
27
+ * Create a new GitHub App token provider
28
+ *
29
+ * @param config GitHub App configuration
30
+ * @throws AuthenticationError if private key cannot be loaded
31
+ */
32
+ constructor(config: GitHubAppConfig);
33
+ /**
34
+ * Get a valid authentication token
35
+ *
36
+ * Delegates to GitHubAppAuth.getInstallationToken() which handles
37
+ * caching and automatic refresh.
38
+ *
39
+ * @returns Promise resolving to the installation access token
40
+ * @throws AuthenticationError if token cannot be obtained
41
+ */
42
+ getToken(): Promise<string>;
43
+ /**
44
+ * Clear the token cache
45
+ *
46
+ * Forces the next getToken() call to fetch a fresh token.
47
+ */
48
+ clearCache(): void;
49
+ /**
50
+ * Get cache information (for debugging)
51
+ *
52
+ * @returns Cache status or null if no cached token
53
+ */
54
+ getCacheInfo(): {
55
+ expiresAt: Date;
56
+ isValid: boolean;
57
+ } | null;
58
+ }
59
+ //# sourceMappingURL=github-app-token-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-token-provider.d.ts","sourceRoot":"","sources":["../../src/auth/github-app-token-provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG9D;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IAErC;;;;;OAKG;gBACS,MAAM,EAAE,eAAe;IAInC;;;;;;;;OAQG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;OAIG;IACH,YAAY,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;CAG7D"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ /**
3
+ * @fractary/core - GitHub App Token Provider
4
+ *
5
+ * TokenProvider implementation that wraps GitHubAppAuth.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.GitHubAppTokenProvider = void 0;
9
+ const github_app_auth_1 = require("./github-app-auth");
10
+ /**
11
+ * GitHub App token provider
12
+ *
13
+ * Implements the TokenProvider interface using GitHub App authentication.
14
+ * Wraps GitHubAppAuth to provide automatic token caching and refresh.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const provider = new GitHubAppTokenProvider({
19
+ * id: '123456',
20
+ * installation_id: '789012',
21
+ * private_key_path: '/path/to/private-key.pem'
22
+ * });
23
+ *
24
+ * const token = await provider.getToken();
25
+ * ```
26
+ */
27
+ class GitHubAppTokenProvider {
28
+ auth;
29
+ /**
30
+ * Create a new GitHub App token provider
31
+ *
32
+ * @param config GitHub App configuration
33
+ * @throws AuthenticationError if private key cannot be loaded
34
+ */
35
+ constructor(config) {
36
+ this.auth = new github_app_auth_1.GitHubAppAuth(config);
37
+ }
38
+ /**
39
+ * Get a valid authentication token
40
+ *
41
+ * Delegates to GitHubAppAuth.getInstallationToken() which handles
42
+ * caching and automatic refresh.
43
+ *
44
+ * @returns Promise resolving to the installation access token
45
+ * @throws AuthenticationError if token cannot be obtained
46
+ */
47
+ async getToken() {
48
+ return this.auth.getInstallationToken();
49
+ }
50
+ /**
51
+ * Clear the token cache
52
+ *
53
+ * Forces the next getToken() call to fetch a fresh token.
54
+ */
55
+ clearCache() {
56
+ this.auth.clearCache();
57
+ }
58
+ /**
59
+ * Get cache information (for debugging)
60
+ *
61
+ * @returns Cache status or null if no cached token
62
+ */
63
+ getCacheInfo() {
64
+ return this.auth.getCacheInfo();
65
+ }
66
+ }
67
+ exports.GitHubAppTokenProvider = GitHubAppTokenProvider;
68
+ //# sourceMappingURL=github-app-token-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-token-provider.js","sourceRoot":"","sources":["../../src/auth/github-app-token-provider.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAGH,uDAAkD;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,sBAAsB;IAChB,IAAI,CAAgB;IAErC;;;;;OAKG;IACH,YAAY,MAAuB;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,+BAAa,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAClC,CAAC;CACF;AA3CD,wDA2CC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @fractary/core - Authentication Module
3
+ *
4
+ * Provides token providers and utilities for GitHub authentication.
5
+ * Supports both Personal Access Token (PAT) and GitHub App authentication.
6
+ */
7
+ export type { TokenProvider, GitHubAppConfig, GitHubConfig } from './types';
8
+ export { StaticTokenProvider } from './static-token-provider';
9
+ export { GitHubAppAuth } from './github-app-auth';
10
+ export { GitHubAppTokenProvider } from './github-app-token-provider';
11
+ import type { TokenProvider, GitHubConfig } from './types';
12
+ /**
13
+ * Create a token provider from GitHub configuration
14
+ *
15
+ * Priority order:
16
+ * 1. If config.app has id + installation_id → GitHubAppTokenProvider
17
+ * 2. If GITHUB_TOKEN env var or config.token → StaticTokenProvider
18
+ * 3. Otherwise throws AuthenticationError
19
+ *
20
+ * @param config GitHub configuration object
21
+ * @returns TokenProvider instance
22
+ * @throws AuthenticationError if no valid authentication method is found
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // GitHub App authentication
27
+ * const provider = createTokenProvider({
28
+ * app: {
29
+ * id: '123456',
30
+ * installation_id: '789012',
31
+ * private_key_path: '/path/to/key.pem'
32
+ * }
33
+ * });
34
+ *
35
+ * // PAT authentication
36
+ * const provider = createTokenProvider({
37
+ * token: 'ghp_xxxx'
38
+ * });
39
+ *
40
+ * // Environment variable (GITHUB_TOKEN)
41
+ * const provider = createTokenProvider({});
42
+ * ```
43
+ */
44
+ export declare function createTokenProvider(config?: GitHubConfig): TokenProvider;
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,YAAiB,GAAG,aAAa,CA6B5E"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * @fractary/core - Authentication Module
4
+ *
5
+ * Provides token providers and utilities for GitHub authentication.
6
+ * Supports both Personal Access Token (PAT) and GitHub App authentication.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.GitHubAppTokenProvider = exports.GitHubAppAuth = exports.StaticTokenProvider = void 0;
10
+ exports.createTokenProvider = createTokenProvider;
11
+ // Providers
12
+ var static_token_provider_1 = require("./static-token-provider");
13
+ Object.defineProperty(exports, "StaticTokenProvider", { enumerable: true, get: function () { return static_token_provider_1.StaticTokenProvider; } });
14
+ var github_app_auth_1 = require("./github-app-auth");
15
+ Object.defineProperty(exports, "GitHubAppAuth", { enumerable: true, get: function () { return github_app_auth_1.GitHubAppAuth; } });
16
+ var github_app_token_provider_1 = require("./github-app-token-provider");
17
+ Object.defineProperty(exports, "GitHubAppTokenProvider", { enumerable: true, get: function () { return github_app_token_provider_1.GitHubAppTokenProvider; } });
18
+ const static_token_provider_2 = require("./static-token-provider");
19
+ const github_app_token_provider_2 = require("./github-app-token-provider");
20
+ const errors_1 = require("../common/errors");
21
+ /**
22
+ * Create a token provider from GitHub configuration
23
+ *
24
+ * Priority order:
25
+ * 1. If config.app has id + installation_id → GitHubAppTokenProvider
26
+ * 2. If GITHUB_TOKEN env var or config.token → StaticTokenProvider
27
+ * 3. Otherwise throws AuthenticationError
28
+ *
29
+ * @param config GitHub configuration object
30
+ * @returns TokenProvider instance
31
+ * @throws AuthenticationError if no valid authentication method is found
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // GitHub App authentication
36
+ * const provider = createTokenProvider({
37
+ * app: {
38
+ * id: '123456',
39
+ * installation_id: '789012',
40
+ * private_key_path: '/path/to/key.pem'
41
+ * }
42
+ * });
43
+ *
44
+ * // PAT authentication
45
+ * const provider = createTokenProvider({
46
+ * token: 'ghp_xxxx'
47
+ * });
48
+ *
49
+ * // Environment variable (GITHUB_TOKEN)
50
+ * const provider = createTokenProvider({});
51
+ * ```
52
+ */
53
+ function createTokenProvider(config = {}) {
54
+ // Priority 1: GitHub App authentication
55
+ if (config.app?.id && config.app?.installation_id) {
56
+ if (!config.app.private_key_path && !config.app.private_key_env_var) {
57
+ throw new errors_1.AuthenticationError('github-app', 'GitHub App config must specify either private_key_path or private_key_env_var');
58
+ }
59
+ return new github_app_token_provider_2.GitHubAppTokenProvider(config.app);
60
+ }
61
+ // Priority 2: PAT from config
62
+ if (config.token) {
63
+ return new static_token_provider_2.StaticTokenProvider(config.token);
64
+ }
65
+ // Priority 3: PAT from environment variable
66
+ const envToken = process.env.GITHUB_TOKEN;
67
+ if (envToken) {
68
+ return new static_token_provider_2.StaticTokenProvider(envToken);
69
+ }
70
+ // No valid authentication method found
71
+ throw new errors_1.AuthenticationError('github', 'No GitHub authentication configured. Set GITHUB_TOKEN environment variable, ' +
72
+ 'provide a token in config, or configure GitHub App authentication.');
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAgDH,kDA6BC;AAxED,YAAY;AACZ,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,yEAAqE;AAA5D,mIAAA,sBAAsB,OAAA;AAI/B,mEAA8D;AAC9D,2EAAqE;AACrE,6CAAuD;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,mBAAmB,CAAC,SAAuB,EAAE;IAC3D,wCAAwC;IACxC,IAAI,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;YACpE,MAAM,IAAI,4BAAmB,CAC3B,YAAY,EACZ,+EAA+E,CAChF,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,kDAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,8BAA8B;IAC9B,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,IAAI,2CAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,IAAI,2CAAmB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,uCAAuC;IACvC,MAAM,IAAI,4BAAmB,CAC3B,QAAQ,EACR,8EAA8E;QAC9E,oEAAoE,CACrE,CAAC;AACJ,CAAC"}