@fractary/core 0.3.3 → 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,5 @@
1
+ /**
2
+ * Unit tests for factory functions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=factories.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factories.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/factories.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for factory functions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const errors_1 = require("../common/errors");
7
+ // We need to test the parseProject function indirectly through the factories
8
+ // Since it's private, we test via integration with buildWorkConfig/buildRepoConfig
9
+ describe('factories', () => {
10
+ describe('project format validation', () => {
11
+ // Import the module dynamically to test internal functions
12
+ // We'll create a test helper that exposes validation behavior
13
+ const validProjects = [
14
+ 'owner/repo',
15
+ 'my-org/my-repo',
16
+ 'user123/project_456',
17
+ 'Org.Name/Repo.Name',
18
+ 'a/b',
19
+ 'fractary/core',
20
+ 'my_org/my_repo',
21
+ 'org-name/repo-name',
22
+ 'ORG/REPO',
23
+ ];
24
+ const invalidProjects = [
25
+ '',
26
+ ' ',
27
+ 'noslash',
28
+ '/leadingslash',
29
+ 'trailingslash/',
30
+ 'too/many/slashes',
31
+ 'owner//repo',
32
+ 'owner/ repo',
33
+ 'owner /repo',
34
+ // Note: ' owner/repo' and 'owner/repo ' become valid after trimming
35
+ // which is the expected behavior - we trim before validation
36
+ 'invalid@char/repo',
37
+ 'owner/invalid@char',
38
+ 'owner/repo/extra',
39
+ ];
40
+ // Test valid formats via regex
41
+ describe('valid project formats', () => {
42
+ const PROJECT_FORMAT_REGEX = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
43
+ validProjects.forEach((project) => {
44
+ it(`should accept "${project}"`, () => {
45
+ expect(PROJECT_FORMAT_REGEX.test(project.trim())).toBe(true);
46
+ });
47
+ });
48
+ });
49
+ describe('invalid project formats', () => {
50
+ const PROJECT_FORMAT_REGEX = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
51
+ invalidProjects.forEach((project) => {
52
+ it(`should reject "${project}"`, () => {
53
+ expect(PROJECT_FORMAT_REGEX.test(project.trim())).toBe(false);
54
+ });
55
+ });
56
+ });
57
+ });
58
+ describe('ConfigurationError', () => {
59
+ it('should include project in details', () => {
60
+ const error = new errors_1.ConfigurationError('Invalid project format', { project: 'bad/format/here' });
61
+ expect(error.details).toEqual({ project: 'bad/format/here' });
62
+ expect(error.code).toBe('CONFIG_ERROR');
63
+ });
64
+ });
65
+ });
66
+ //# sourceMappingURL=factories.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factories.test.js","sourceRoot":"","sources":["../../src/__tests__/factories.test.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,6CAAsD;AAEtD,6EAA6E;AAC7E,mFAAmF;AAEnF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,2DAA2D;QAC3D,8DAA8D;QAE9D,MAAM,aAAa,GAAG;YACpB,YAAY;YACZ,gBAAgB;YAChB,qBAAqB;YACrB,oBAAoB;YACpB,KAAK;YACL,eAAe;YACf,gBAAgB;YAChB,oBAAoB;YACpB,UAAU;SACX,CAAC;QAEF,MAAM,eAAe,GAAG;YACtB,EAAE;YACF,KAAK;YACL,SAAS;YACT,eAAe;YACf,gBAAgB;YAChB,kBAAkB;YAClB,aAAa;YACb,aAAa;YACb,aAAa;YACb,oEAAoE;YACpE,6DAA6D;YAC7D,mBAAmB;YACnB,oBAAoB;YACpB,kBAAkB;SACnB,CAAC;QAEF,+BAA+B;QAC/B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;YACrC,MAAM,oBAAoB,GAAG,oCAAoC,CAAC;YAElE,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChC,EAAE,CAAC,kBAAkB,OAAO,GAAG,EAAE,GAAG,EAAE;oBACpC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACvC,MAAM,oBAAoB,GAAG,oCAAoC,CAAC;YAElE,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAClC,EAAE,CAAC,kBAAkB,OAAO,GAAG,EAAE,GAAG,EAAE;oBACpC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChE,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,2BAAkB,CAClC,wBAAwB,EACxB,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAC/B,CAAC;YAEF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for createTokenProvider factory
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=create-token-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-token-provider.test.d.ts","sourceRoot":"","sources":["../../../src/auth/__tests__/create-token-provider.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for createTokenProvider factory
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const index_1 = require("../index");
7
+ const errors_1 = require("../../common/errors");
8
+ describe('createTokenProvider', () => {
9
+ const originalEnv = process.env;
10
+ beforeEach(() => {
11
+ // Reset environment before each test
12
+ process.env = { ...originalEnv };
13
+ delete process.env.GITHUB_TOKEN;
14
+ });
15
+ afterAll(() => {
16
+ process.env = originalEnv;
17
+ });
18
+ describe('with PAT token in config', () => {
19
+ it('should return StaticTokenProvider when token is provided', () => {
20
+ const provider = (0, index_1.createTokenProvider)({ token: 'ghp_test123' });
21
+ expect(provider).toBeInstanceOf(index_1.StaticTokenProvider);
22
+ });
23
+ it('should return working provider that returns the token', async () => {
24
+ const token = 'ghp_myTestToken';
25
+ const provider = (0, index_1.createTokenProvider)({ token });
26
+ const result = await provider.getToken();
27
+ expect(result).toBe(token);
28
+ });
29
+ });
30
+ describe('with GITHUB_TOKEN env var', () => {
31
+ it('should return StaticTokenProvider when GITHUB_TOKEN is set', () => {
32
+ process.env.GITHUB_TOKEN = 'ghp_envToken';
33
+ const provider = (0, index_1.createTokenProvider)({});
34
+ expect(provider).toBeInstanceOf(index_1.StaticTokenProvider);
35
+ });
36
+ it('should return provider that uses GITHUB_TOKEN value', async () => {
37
+ process.env.GITHUB_TOKEN = 'ghp_envToken456';
38
+ const provider = (0, index_1.createTokenProvider)({});
39
+ const result = await provider.getToken();
40
+ expect(result).toBe('ghp_envToken456');
41
+ });
42
+ it('should prefer config.token over GITHUB_TOKEN', async () => {
43
+ process.env.GITHUB_TOKEN = 'ghp_envToken';
44
+ const configToken = 'ghp_configToken';
45
+ const provider = (0, index_1.createTokenProvider)({ token: configToken });
46
+ const result = await provider.getToken();
47
+ expect(result).toBe(configToken);
48
+ });
49
+ });
50
+ describe('with GitHub App config', () => {
51
+ it('should return GitHubAppTokenProvider when app config has id and installation_id', () => {
52
+ // Note: This will throw because private key is not provided
53
+ // but we're testing the type selection logic
54
+ expect(() => (0, index_1.createTokenProvider)({
55
+ app: {
56
+ id: '123456',
57
+ installation_id: '789012',
58
+ // Missing private_key_path or private_key_env_var
59
+ }
60
+ })).toThrow(errors_1.AuthenticationError);
61
+ });
62
+ it('should throw if app config is incomplete (missing private key source)', () => {
63
+ expect(() => (0, index_1.createTokenProvider)({
64
+ app: {
65
+ id: '123456',
66
+ installation_id: '789012',
67
+ }
68
+ })).toThrow('GitHub App config must specify either private_key_path or private_key_env_var');
69
+ });
70
+ it('should prefer GitHub App auth over PAT when both are provided', () => {
71
+ // When GitHub App config is complete, it should be preferred
72
+ // But since we can't provide a valid private key in tests, we verify the error message
73
+ expect(() => (0, index_1.createTokenProvider)({
74
+ token: 'ghp_shouldBeIgnored',
75
+ app: {
76
+ id: '123456',
77
+ installation_id: '789012',
78
+ private_key_env_var: 'NON_EXISTENT_KEY',
79
+ }
80
+ })).toThrow(); // Will throw because env var doesn't exist
81
+ });
82
+ });
83
+ describe('with no authentication', () => {
84
+ it('should throw AuthenticationError when no auth is configured', () => {
85
+ expect(() => (0, index_1.createTokenProvider)({})).toThrow(errors_1.AuthenticationError);
86
+ });
87
+ it('should provide helpful error message', () => {
88
+ expect(() => (0, index_1.createTokenProvider)({})).toThrow('No GitHub authentication configured');
89
+ });
90
+ it('should throw when config is undefined', () => {
91
+ expect(() => (0, index_1.createTokenProvider)()).toThrow(errors_1.AuthenticationError);
92
+ });
93
+ });
94
+ describe('priority order', () => {
95
+ it('should follow priority: GitHub App > config.token > GITHUB_TOKEN', async () => {
96
+ // Test that config.token takes priority over GITHUB_TOKEN
97
+ process.env.GITHUB_TOKEN = 'ghp_envToken';
98
+ const provider = (0, index_1.createTokenProvider)({ token: 'ghp_configToken' });
99
+ const result = await provider.getToken();
100
+ expect(result).toBe('ghp_configToken');
101
+ });
102
+ });
103
+ });
104
+ //# sourceMappingURL=create-token-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-token-provider.test.js","sourceRoot":"","sources":["../../../src/auth/__tests__/create-token-provider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for GitHubAppAuth
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=github-app-auth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-auth.test.d.ts","sourceRoot":"","sources":["../../../src/auth/__tests__/github-app-auth.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for GitHubAppAuth
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const github_app_auth_1 = require("../github-app-auth");
40
+ const errors_1 = require("../../common/errors");
41
+ const fs = __importStar(require("fs"));
42
+ // Mock fs module
43
+ jest.mock('fs');
44
+ const mockedFs = fs;
45
+ // Mock jsonwebtoken
46
+ jest.mock('jsonwebtoken', () => ({
47
+ sign: jest.fn().mockReturnValue('mocked.jwt.token'),
48
+ }));
49
+ // Mock global fetch
50
+ const mockFetch = jest.fn();
51
+ global.fetch = mockFetch;
52
+ // Sample PEM key for testing (just needs to look like a PEM)
53
+ const SAMPLE_PEM_KEY = `-----BEGIN RSA PRIVATE KEY-----
54
+ MIIEowIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy0AHB7MaXsNxkTMnMQgKpq
55
+ -----END RSA PRIVATE KEY-----`;
56
+ describe('GitHubAppAuth', () => {
57
+ beforeEach(() => {
58
+ jest.clearAllMocks();
59
+ delete process.env.GITHUB_APP_PRIVATE_KEY;
60
+ });
61
+ describe('constructor', () => {
62
+ it('should throw if neither private_key_path nor private_key_env_var is provided', () => {
63
+ expect(() => new github_app_auth_1.GitHubAppAuth({
64
+ id: '123',
65
+ installation_id: '456',
66
+ })).toThrow('GitHub App config must specify either private_key_path or private_key_env_var');
67
+ });
68
+ it('should throw if private key file does not exist', () => {
69
+ mockedFs.existsSync.mockReturnValue(false);
70
+ expect(() => new github_app_auth_1.GitHubAppAuth({
71
+ id: '123',
72
+ installation_id: '456',
73
+ private_key_path: '/path/to/nonexistent.pem',
74
+ })).toThrow('Private key file not found');
75
+ });
76
+ it('should load private key from file', () => {
77
+ mockedFs.existsSync.mockReturnValue(true);
78
+ mockedFs.readFileSync.mockReturnValue(SAMPLE_PEM_KEY);
79
+ const auth = new github_app_auth_1.GitHubAppAuth({
80
+ id: '123',
81
+ installation_id: '456',
82
+ private_key_path: '/path/to/key.pem',
83
+ });
84
+ expect(auth).toBeInstanceOf(github_app_auth_1.GitHubAppAuth);
85
+ expect(mockedFs.readFileSync).toHaveBeenCalledWith('/path/to/key.pem', 'utf-8');
86
+ });
87
+ it('should throw if env var is not set', () => {
88
+ expect(() => new github_app_auth_1.GitHubAppAuth({
89
+ id: '123',
90
+ installation_id: '456',
91
+ private_key_env_var: 'GITHUB_APP_PRIVATE_KEY',
92
+ })).toThrow('Environment variable GITHUB_APP_PRIVATE_KEY is not set');
93
+ });
94
+ it('should decode base64 private key from env var', () => {
95
+ const base64Key = Buffer.from(SAMPLE_PEM_KEY).toString('base64');
96
+ process.env.GITHUB_APP_PRIVATE_KEY = base64Key;
97
+ const auth = new github_app_auth_1.GitHubAppAuth({
98
+ id: '123',
99
+ installation_id: '456',
100
+ private_key_env_var: 'GITHUB_APP_PRIVATE_KEY',
101
+ });
102
+ expect(auth).toBeInstanceOf(github_app_auth_1.GitHubAppAuth);
103
+ });
104
+ it('should throw if decoded env var is not a PEM key', () => {
105
+ process.env.GITHUB_APP_PRIVATE_KEY = Buffer.from('not a pem key').toString('base64');
106
+ expect(() => new github_app_auth_1.GitHubAppAuth({
107
+ id: '123',
108
+ installation_id: '456',
109
+ private_key_env_var: 'GITHUB_APP_PRIVATE_KEY',
110
+ })).toThrow('does not appear to be a PEM key');
111
+ });
112
+ });
113
+ describe('getInstallationToken', () => {
114
+ let auth;
115
+ beforeEach(() => {
116
+ mockedFs.existsSync.mockReturnValue(true);
117
+ mockedFs.readFileSync.mockReturnValue(SAMPLE_PEM_KEY);
118
+ auth = new github_app_auth_1.GitHubAppAuth({
119
+ id: '123',
120
+ installation_id: '456',
121
+ private_key_path: '/path/to/key.pem',
122
+ });
123
+ });
124
+ it('should fetch token from GitHub API', async () => {
125
+ const expiresAt = new Date(Date.now() + 3600000).toISOString();
126
+ mockFetch.mockResolvedValueOnce({
127
+ ok: true,
128
+ json: async () => ({ token: 'ghs_testToken', expires_at: expiresAt }),
129
+ });
130
+ const token = await auth.getInstallationToken();
131
+ expect(token).toBe('ghs_testToken');
132
+ expect(mockFetch).toHaveBeenCalledTimes(1);
133
+ expect(mockFetch).toHaveBeenCalledWith('https://api.github.com/app/installations/456/access_tokens', expect.objectContaining({
134
+ method: 'POST',
135
+ headers: expect.objectContaining({
136
+ 'Accept': 'application/vnd.github+json',
137
+ 'X-GitHub-Api-Version': '2022-11-28',
138
+ }),
139
+ }));
140
+ });
141
+ it('should cache the token', async () => {
142
+ const expiresAt = new Date(Date.now() + 3600000).toISOString();
143
+ mockFetch.mockResolvedValueOnce({
144
+ ok: true,
145
+ json: async () => ({ token: 'ghs_cached', expires_at: expiresAt }),
146
+ });
147
+ // First call - should fetch
148
+ const token1 = await auth.getInstallationToken();
149
+ expect(token1).toBe('ghs_cached');
150
+ expect(mockFetch).toHaveBeenCalledTimes(1);
151
+ // Second call - should use cache
152
+ const token2 = await auth.getInstallationToken();
153
+ expect(token2).toBe('ghs_cached');
154
+ expect(mockFetch).toHaveBeenCalledTimes(1); // Still 1, no new fetch
155
+ });
156
+ it('should refresh token before expiration (5 min buffer)', async () => {
157
+ // Token that expires in 4 minutes (within 5-min buffer)
158
+ const expiresAt = new Date(Date.now() + 4 * 60 * 1000).toISOString();
159
+ mockFetch.mockResolvedValueOnce({
160
+ ok: true,
161
+ json: async () => ({ token: 'ghs_expiring', expires_at: expiresAt }),
162
+ });
163
+ await auth.getInstallationToken();
164
+ // Set up mock for refresh
165
+ const newExpiresAt = new Date(Date.now() + 3600000).toISOString();
166
+ mockFetch.mockResolvedValueOnce({
167
+ ok: true,
168
+ json: async () => ({ token: 'ghs_refreshed', expires_at: newExpiresAt }),
169
+ });
170
+ // Next call should trigger refresh because within buffer
171
+ const token = await auth.getInstallationToken();
172
+ expect(token).toBe('ghs_refreshed');
173
+ expect(mockFetch).toHaveBeenCalledTimes(2);
174
+ });
175
+ it('should throw AuthenticationError on API failure', async () => {
176
+ mockFetch.mockResolvedValueOnce({
177
+ ok: false,
178
+ status: 401,
179
+ text: async () => 'Unauthorized',
180
+ });
181
+ await expect(auth.getInstallationToken()).rejects.toThrow(errors_1.AuthenticationError);
182
+ });
183
+ describe('race condition prevention', () => {
184
+ it('should share pending request between concurrent calls', async () => {
185
+ const expiresAt = new Date(Date.now() + 3600000).toISOString();
186
+ let resolvePromise;
187
+ // Create a delayed response
188
+ mockFetch.mockReturnValueOnce(new Promise((resolve) => {
189
+ resolvePromise = resolve;
190
+ }));
191
+ // Start multiple concurrent requests
192
+ const promise1 = auth.getInstallationToken();
193
+ const promise2 = auth.getInstallationToken();
194
+ const promise3 = auth.getInstallationToken();
195
+ // All should be waiting on the same request
196
+ expect(mockFetch).toHaveBeenCalledTimes(1);
197
+ // Resolve the request
198
+ resolvePromise({
199
+ ok: true,
200
+ json: async () => ({ token: 'ghs_shared', expires_at: expiresAt }),
201
+ });
202
+ // All promises should resolve to the same token
203
+ const [token1, token2, token3] = await Promise.all([promise1, promise2, promise3]);
204
+ expect(token1).toBe('ghs_shared');
205
+ expect(token2).toBe('ghs_shared');
206
+ expect(token3).toBe('ghs_shared');
207
+ expect(mockFetch).toHaveBeenCalledTimes(1); // Only one fetch call
208
+ });
209
+ it('should clear pending request after completion', async () => {
210
+ const expiresAt = new Date(Date.now() + 100).toISOString(); // Expires immediately
211
+ mockFetch.mockResolvedValueOnce({
212
+ ok: true,
213
+ json: async () => ({ token: 'ghs_first', expires_at: expiresAt }),
214
+ });
215
+ await auth.getInstallationToken();
216
+ // Clear cache to force new request
217
+ auth.clearCache();
218
+ mockFetch.mockResolvedValueOnce({
219
+ ok: true,
220
+ json: async () => ({ token: 'ghs_second', expires_at: new Date(Date.now() + 3600000).toISOString() }),
221
+ });
222
+ const token = await auth.getInstallationToken();
223
+ expect(token).toBe('ghs_second');
224
+ expect(mockFetch).toHaveBeenCalledTimes(2);
225
+ });
226
+ it('should clear pending request on error', async () => {
227
+ mockFetch.mockRejectedValueOnce(new Error('Network error'));
228
+ await expect(auth.getInstallationToken()).rejects.toThrow();
229
+ // Next call should try again (not reuse failed promise)
230
+ mockFetch.mockResolvedValueOnce({
231
+ ok: true,
232
+ json: async () => ({ token: 'ghs_retry', expires_at: new Date(Date.now() + 3600000).toISOString() }),
233
+ });
234
+ const token = await auth.getInstallationToken();
235
+ expect(token).toBe('ghs_retry');
236
+ expect(mockFetch).toHaveBeenCalledTimes(2);
237
+ });
238
+ });
239
+ });
240
+ describe('clearCache', () => {
241
+ it('should clear cached token', async () => {
242
+ mockedFs.existsSync.mockReturnValue(true);
243
+ mockedFs.readFileSync.mockReturnValue(SAMPLE_PEM_KEY);
244
+ const auth = new github_app_auth_1.GitHubAppAuth({
245
+ id: '123',
246
+ installation_id: '456',
247
+ private_key_path: '/path/to/key.pem',
248
+ });
249
+ const expiresAt = new Date(Date.now() + 3600000).toISOString();
250
+ mockFetch.mockResolvedValue({
251
+ ok: true,
252
+ json: async () => ({ token: 'ghs_token', expires_at: expiresAt }),
253
+ });
254
+ await auth.getInstallationToken();
255
+ expect(mockFetch).toHaveBeenCalledTimes(1);
256
+ auth.clearCache();
257
+ await auth.getInstallationToken();
258
+ expect(mockFetch).toHaveBeenCalledTimes(2); // New fetch after cache clear
259
+ });
260
+ });
261
+ describe('getCacheInfo', () => {
262
+ it('should return null when no token is cached', () => {
263
+ mockedFs.existsSync.mockReturnValue(true);
264
+ mockedFs.readFileSync.mockReturnValue(SAMPLE_PEM_KEY);
265
+ const auth = new github_app_auth_1.GitHubAppAuth({
266
+ id: '123',
267
+ installation_id: '456',
268
+ private_key_path: '/path/to/key.pem',
269
+ });
270
+ expect(auth.getCacheInfo()).toBeNull();
271
+ });
272
+ it('should return cache info when token is cached', async () => {
273
+ mockedFs.existsSync.mockReturnValue(true);
274
+ mockedFs.readFileSync.mockReturnValue(SAMPLE_PEM_KEY);
275
+ const auth = new github_app_auth_1.GitHubAppAuth({
276
+ id: '123',
277
+ installation_id: '456',
278
+ private_key_path: '/path/to/key.pem',
279
+ });
280
+ const expiresAt = new Date(Date.now() + 3600000);
281
+ mockFetch.mockResolvedValueOnce({
282
+ ok: true,
283
+ json: async () => ({ token: 'ghs_token', expires_at: expiresAt.toISOString() }),
284
+ });
285
+ await auth.getInstallationToken();
286
+ const cacheInfo = auth.getCacheInfo();
287
+ expect(cacheInfo).not.toBeNull();
288
+ expect(cacheInfo?.isValid).toBe(true);
289
+ expect(cacheInfo?.expiresAt).toEqual(expiresAt);
290
+ });
291
+ });
292
+ });
293
+ //# sourceMappingURL=github-app-auth.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-auth.test.js","sourceRoot":"","sources":["../../../src/auth/__tests__/github-app-auth.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for StaticTokenProvider
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=static-token-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-token-provider.test.d.ts","sourceRoot":"","sources":["../../../src/auth/__tests__/static-token-provider.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for StaticTokenProvider
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const static_token_provider_1 = require("../static-token-provider");
7
+ describe('StaticTokenProvider', () => {
8
+ describe('constructor', () => {
9
+ it('should accept a valid token string', () => {
10
+ const provider = new static_token_provider_1.StaticTokenProvider('ghp_test123');
11
+ expect(provider).toBeInstanceOf(static_token_provider_1.StaticTokenProvider);
12
+ });
13
+ it('should throw error for empty string', () => {
14
+ expect(() => new static_token_provider_1.StaticTokenProvider('')).toThrow('Token must be a non-empty string');
15
+ });
16
+ it('should throw error for whitespace-only string', () => {
17
+ expect(() => new static_token_provider_1.StaticTokenProvider(' ')).toThrow('Token must be a non-empty string');
18
+ });
19
+ it('should throw error for undefined', () => {
20
+ expect(() => new static_token_provider_1.StaticTokenProvider(undefined)).toThrow('Token must be a non-empty string');
21
+ });
22
+ it('should throw error for null', () => {
23
+ expect(() => new static_token_provider_1.StaticTokenProvider(null)).toThrow('Token must be a non-empty string');
24
+ });
25
+ it('should throw error for non-string values', () => {
26
+ expect(() => new static_token_provider_1.StaticTokenProvider(123)).toThrow('Token must be a non-empty string');
27
+ });
28
+ });
29
+ describe('getToken', () => {
30
+ it('should return the token', async () => {
31
+ const token = 'ghp_testToken123';
32
+ const provider = new static_token_provider_1.StaticTokenProvider(token);
33
+ const result = await provider.getToken();
34
+ expect(result).toBe(token);
35
+ });
36
+ it('should return the same token on multiple calls', async () => {
37
+ const token = 'ghp_testToken456';
38
+ const provider = new static_token_provider_1.StaticTokenProvider(token);
39
+ const result1 = await provider.getToken();
40
+ const result2 = await provider.getToken();
41
+ const result3 = await provider.getToken();
42
+ expect(result1).toBe(token);
43
+ expect(result2).toBe(token);
44
+ expect(result3).toBe(token);
45
+ });
46
+ it('should handle tokens with special characters', async () => {
47
+ const token = 'github_pat_1234567890abcdef_GHIJKL';
48
+ const provider = new static_token_provider_1.StaticTokenProvider(token);
49
+ const result = await provider.getToken();
50
+ expect(result).toBe(token);
51
+ });
52
+ });
53
+ });
54
+ //# sourceMappingURL=static-token-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-token-provider.test.js","sourceRoot":"","sources":["../../../src/auth/__tests__/static-token-provider.test.ts"],"names":[],"mappings":"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"}