@unito/integration-cli 0.57.1 → 0.58.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 (115) hide show
  1. package/dist/.eslintrc.d.ts +6 -0
  2. package/dist/.eslintrc.js +9 -2
  3. package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/src/index.ts +1 -3
  4. package/dist/src/commands/activity.d.ts +2 -2
  5. package/dist/src/commands/activity.js +2 -2
  6. package/dist/src/commands/dev.d.ts +8 -4
  7. package/dist/src/commands/dev.js +42 -5
  8. package/dist/src/commands/encrypt.d.ts +1 -1
  9. package/dist/src/commands/encrypt.js +1 -1
  10. package/dist/src/commands/init.d.ts +1 -1
  11. package/dist/src/commands/init.js +3 -3
  12. package/dist/src/commands/invite.d.ts +1 -1
  13. package/dist/src/commands/invite.js +2 -2
  14. package/dist/src/commands/login.d.ts +1 -1
  15. package/dist/src/commands/login.js +1 -1
  16. package/dist/src/commands/oauth2.d.ts +3 -3
  17. package/dist/src/commands/oauth2.js +19 -14
  18. package/dist/src/commands/publish.d.ts +2 -2
  19. package/dist/src/commands/publish.js +12 -12
  20. package/dist/src/commands/test.js +32 -8
  21. package/dist/src/commands/upgrade.js +3 -3
  22. package/dist/src/errors.d.ts +8 -0
  23. package/dist/src/errors.js +35 -18
  24. package/dist/src/resources/configuration.js +0 -2
  25. package/dist/src/resources/credentials.d.ts +3 -0
  26. package/dist/src/resources/credentials.js +26 -0
  27. package/dist/src/resources/integrations.d.ts +1 -0
  28. package/dist/src/resources/integrations.js +37 -2
  29. package/dist/src/resources/oauth2Helper.d.ts +4 -0
  30. package/dist/src/resources/oauth2Helper.js +30 -0
  31. package/dist/src/services/integrationsPlatform.d.ts +1 -0
  32. package/dist/src/services/integrationsPlatform.js +5 -1
  33. package/dist/src/services/oauth2Helper.d.ts +78 -3
  34. package/dist/src/services/oauth2Helper.js +229 -29
  35. package/dist/test/commands/activity.test.js +12 -9
  36. package/dist/test/commands/dev.test.js +59 -10
  37. package/dist/test/commands/encrypt.test.js +6 -7
  38. package/dist/test/commands/init.test.js +7 -9
  39. package/dist/test/commands/invite.test.js +11 -11
  40. package/dist/test/commands/login.test.js +20 -23
  41. package/dist/test/commands/oauth2.test.js +6 -2
  42. package/dist/test/commands/publish.test.js +152 -218
  43. package/dist/test/commands/test.test.js +65 -13
  44. package/dist/test/commands/upgrade.test.js +4 -6
  45. package/dist/test/errors.test.js +36 -36
  46. package/dist/test/helpers/integrations.d.ts +26 -0
  47. package/dist/test/helpers/integrations.js +25 -0
  48. package/dist/test/helpers/styles.d.ts +1 -0
  49. package/dist/test/helpers/styles.js +8 -0
  50. package/dist/test/oauth2Helper/oauth2Helper.test.js +112 -128
  51. package/dist/test/resources/configuration.test.js +24 -24
  52. package/dist/test/resources/decryption.test.js +9 -9
  53. package/dist/test/resources/globalConfiguration.test.js +4 -4
  54. package/dist/test/resources/integrations.test.js +37 -0
  55. package/dist/test/resources/oauth2Helper.test.js +55 -0
  56. package/dist/test/services/integrationsPlatform.test.js +20 -20
  57. package/oclif.manifest.json +64 -9
  58. package/package.json +10 -14
  59. package/dist/integrationGenerator/errors.d.ts +0 -2
  60. package/dist/integrationGenerator/errors.js +0 -6
  61. package/dist/integrationGenerator/index.d.ts +0 -2
  62. package/dist/integrationGenerator/index.js +0 -5
  63. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +0 -3
  64. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +0 -74
  65. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +0 -1
  66. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +0 -1
  67. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +0 -7
  68. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +0 -1
  69. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +0 -38
  70. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +0 -21
  71. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +0 -94
  72. package/dist/integrationGenerator/integrationBoilerplate/package.json +0 -43
  73. package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +0 -55
  74. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +0 -22
  75. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +0 -13
  76. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +0 -38
  77. package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +0 -59
  78. package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +0 -11
  79. package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +0 -15
  80. package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +0 -12
  81. package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +0 -37
  82. package/dist/integrationGenerator/src/index.d.ts +0 -1
  83. package/dist/integrationGenerator/src/index.js +0 -5
  84. package/dist/integrationGenerator/src/resources/index.d.ts +0 -1
  85. package/dist/integrationGenerator/src/resources/index.js +0 -5
  86. package/dist/integrationGenerator/src/resources/integration.d.ts +0 -9
  87. package/dist/integrationGenerator/src/resources/integration.js +0 -60
  88. package/dist/integrationGenerator/test/resources/integration.test.js +0 -51
  89. package/dist/src/oauth2Helper/oauth2Helper.d.ts +0 -63
  90. package/dist/src/oauth2Helper/oauth2Helper.js +0 -235
  91. package/dist/src/oauth2Helper/types.d.ts +0 -22
  92. package/dist/src/oauth2Helper/types.js +0 -2
  93. package/dist/test/mocha.hooks.d.ts +0 -2
  94. package/dist/test/mocha.hooks.js +0 -37
  95. package/dist/test/services/oauth2Helper.test.js +0 -85
  96. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.dockerignore +0 -0
  97. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.eslintrc.js +0 -0
  98. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.nvmrc +0 -0
  99. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierignore +0 -0
  100. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierrc +0 -0
  101. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.unito.json +0 -0
  102. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/Dockerfile +0 -0
  103. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/README.md +0 -0
  104. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/package.json +0 -0
  105. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/logger.ts +0 -0
  106. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/additionalLoggingContext.ts +0 -0
  107. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/correlationId.ts +0 -0
  108. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/credentials.ts +0 -0
  109. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/request.ts +0 -0
  110. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/index.ts +0 -0
  111. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/me.ts +0 -0
  112. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/root.ts +0 -0
  113. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/tsconfig.json +0 -0
  114. /package/dist/{integrationGenerator/test/resources/integration.test.d.ts → test/resources/integrations.test.d.ts} +0 -0
  115. /package/dist/test/{services → resources}/oauth2Helper.test.d.ts +0 -0
@@ -2,149 +2,133 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
- const chai_1 = require("chai");
5
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
6
6
  const sinon_1 = tslib_1.__importDefault(require("sinon"));
7
- const oauth2Helper_1 = tslib_1.__importStar(require("../../src/oauth2Helper/oauth2Helper")), oauth2Namespace = oauth2Helper_1;
7
+ const oauth2Helper_1 = tslib_1.__importStar(require("../../src/services/oauth2Helper")), oauth2Namespace = oauth2Helper_1;
8
8
  const configurationTypes_1 = require("../../src/configurationTypes");
9
9
  const errors_1 = require("../../src/errors");
10
10
  describe('OAuth2Helper', () => {
11
11
  let oauth2Helper;
12
12
  let openSpy;
13
13
  let fetchStub;
14
- beforeEach(() => {
15
- const authorizationInfo = {
16
- clientId: 'your-client-id',
17
- clientSecret: 'your-client-secret',
18
- authorizationUrl: 'https://provider.com/oauth/authorize',
19
- scopes: [{ name: 'scope1' }, { name: 'scope2' }],
20
- tokenUrl: 'https://provider.com/oauth/token',
21
- grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
22
- requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
23
- responseContentType: configurationTypes_1.RequestContentType.JSON,
24
- tokenRequestParameters: {
25
- header: {
26
- Authorization: 'custom',
27
- },
28
- },
29
- };
30
- oauth2Helper = new oauth2Helper_1.default(authorizationInfo);
31
- fetchStub = sinon_1.default.stub().resolves({ json: sinon_1.default.stub().resolves({}), status: 200 });
32
- sinon_1.default.stub(oauth2Helper, 'startServer').returns('http://localhost:5050');
33
- sinon_1.default.stub(oauth2Helper, 'stopServer');
34
- sinon_1.default.replace(global, 'fetch', fetchStub);
35
- sinon_1.default.replace(oauth2Namespace, 'open', { open: (_url) => undefined });
36
- openSpy = sinon_1.default.spy(oauth2Namespace.open, 'open');
37
- });
38
- afterEach(() => {
39
- sinon_1.default.restore();
40
- });
41
- describe('handleAuthorize', () => {
42
- it('should open the authorization URL', async () => {
43
- const req = {};
44
- const res = { json: sinon_1.default.stub() };
45
- await oauth2Helper['handleAuthorize'](req, res);
46
- sinon_1.default.assert.calledOnce(openSpy);
47
- sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?client_id=your-client-id&redirect_uri=%2Fcredentials%2Fnew%2Foauth2%2Fcallback&scope=scope1+scope2&response_type=code');
48
- sinon_1.default.assert.calledOnce(res.json);
49
- });
50
- it('should maintain the pre-existing query parameters in authorization URL', async () => {
51
- oauth2Helper['providerAuthorizationUrl'] = 'https://provider.com/oauth/authorize?query1=value1&query2=value2';
52
- const req = {};
53
- const res = { json: sinon_1.default.stub() };
54
- await oauth2Helper['handleAuthorize'](req, res);
55
- sinon_1.default.assert.calledOnce(openSpy);
56
- sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?query1=value1&query2=value2&client_id=your-client-id&redirect_uri=%2Fcredentials%2Fnew%2Foauth2%2Fcallback&scope=scope1+scope2&response_type=code');
57
- (0, chai_1.expect)(openSpy.firstCall.args[0]).to.includes('query1=value1');
58
- (0, chai_1.expect)(openSpy.firstCall.args[0]).to.includes('query2=value2');
59
- sinon_1.default.assert.calledOnce(res.json);
60
- });
61
- });
62
- describe('handleCallback', () => {
63
- it('should store the authorization code', async () => {
64
- const code = 'test-code';
65
- const req = { query: { code } };
66
- const res = { json: sinon_1.default.stub() };
67
- await oauth2Helper['handleCallback'](req, res);
68
- (0, chai_1.expect)(oauth2Helper['code']).to.equal(code);
69
- sinon_1.default.assert.calledOnce(res.json);
14
+ describe('constructor', () => {
15
+ it('should throw an error if the request content type is not supported', async () => {
16
+ try {
17
+ new oauth2Helper_1.default({ scopes: [], requestContentType: 'random' });
18
+ }
19
+ catch (err) {
20
+ (0, strict_1.default)(err instanceof errors_1.UnsupportedContentTypeError);
21
+ }
70
22
  });
71
23
  });
72
- describe('handleToken', () => {
73
- it('should retrieve the access token and return it in the response', async () => {
74
- const req = { query: {} };
75
- const res = { json: sinon_1.default.stub() };
76
- await oauth2Helper['handleToken'](req, res);
77
- sinon_1.default.assert.calledOnce(fetchStub);
78
- sinon_1.default.assert.calledWith(fetchStub, 'https://provider.com/oauth/token', {
79
- headers: {
80
- 'Content-type': 'application/x-www-form-urlencoded',
81
- Authorization: 'custom',
24
+ describe('endpoints', () => {
25
+ beforeEach(() => {
26
+ const authorizationInfo = {
27
+ clientId: 'your-client-id',
28
+ clientSecret: 'your-client-secret',
29
+ authorizationUrl: 'https://provider.com/oauth/authorize',
30
+ scopes: [{ name: 'scope1' }, { name: 'scope2' }],
31
+ tokenUrl: 'https://provider.com/oauth/token',
32
+ grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
33
+ requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
34
+ responseContentType: configurationTypes_1.RequestContentType.JSON,
35
+ tokenRequestParameters: {
36
+ header: {
37
+ Authorization: 'custom',
38
+ },
82
39
  },
83
- body: sinon_1.default.match.string,
84
- method: 'POST',
85
- });
86
- sinon_1.default.assert.calledOnce(res.json);
87
- });
88
- it('should handle errors and return 500 status', async () => {
89
- const req = { query: {} };
90
- const res = { status: sinon_1.default.stub().returns({ json: sinon_1.default.stub() }) };
91
- fetchStub.rejects(new Error('Failed to retrieve access token'));
92
- await oauth2Helper['handleToken'](req, res);
93
- sinon_1.default.assert.calledWith(res.status, 500);
94
- });
95
- it('should return an error 400 if the request content type is not supported', async () => {
96
- const req = { query: {} };
97
- const res = { status: sinon_1.default.stub().returns({ json: sinon_1.default.stub() }) };
98
- oauth2Helper['requestContentType'] = 'random';
99
- await oauth2Helper['handleToken'](req, res);
100
- sinon_1.default.assert.calledWith(res.status, 400);
101
- });
102
- });
103
- describe('updateToken', () => {
104
- it('should throw an error when no refresh token is available', async () => {
105
- const response = oauth2Helper.updateToken();
106
- await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.NoRefreshTokenError);
40
+ };
41
+ oauth2Helper = new oauth2Helper_1.default(authorizationInfo);
42
+ fetchStub = sinon_1.default.stub().resolves({ json: sinon_1.default.stub().resolves({}), status: 200 });
43
+ sinon_1.default.stub(oauth2Helper, 'startServer').resolves('http://localhost:5050');
44
+ sinon_1.default.stub(oauth2Helper, 'stopServer');
45
+ sinon_1.default.replace(global, 'fetch', fetchStub);
46
+ sinon_1.default.replace(oauth2Namespace, 'open', { open: (_url) => undefined });
47
+ openSpy = sinon_1.default.stub(oauth2Namespace.open, 'open');
107
48
  });
108
- it('should retrieve the access token when a refresh token is available', async () => {
109
- const refreshToken = 'test-refresh-token';
110
- oauth2Helper['refreshToken'] = refreshToken;
111
- const accessToken = 'test-access-token';
112
- const fetchResponse = { access_token: accessToken, refresh_token: refreshToken };
113
- fetchStub.resolves({ status: 200, json: sinon_1.default.stub().resolves(fetchResponse) });
114
- const result = await oauth2Helper.updateToken();
115
- (0, chai_1.expect)(result).to.deep.equal({ accessToken, refreshToken });
116
- sinon_1.default.assert.calledOnce(fetchStub);
49
+ afterEach(() => {
50
+ sinon_1.default.restore();
117
51
  });
118
- it('should throw an error when failing to refresh the access token', async () => {
119
- const refreshToken = 'test-refresh-token';
120
- oauth2Helper['refreshToken'] = refreshToken;
121
- fetchStub.rejects(new Error('Failed to retrieve access token'));
122
- const response = oauth2Helper.updateToken();
123
- await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.FailedToRetrieveAccessTokenError);
124
- sinon_1.default.assert.calledOnce(fetchStub);
52
+ describe('handleAuthorize', () => {
53
+ it('should open the authorization URL', async () => {
54
+ await oauth2Helper.authorize();
55
+ sinon_1.default.assert.calledOnce(openSpy);
56
+ sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?client_id=your-client-id&redirect_uri=https%3A%2F%2Fintegrations-platform.unito.io%2Fcredentials%2Fnew%2Foauth2%2Fcallback-cli&state=eyJjbGlDYWxsYmFja1VybCI6Ii9vYXV0aDIvY2FsbGJhY2sifQ%3D%3D&scope=scope1+scope2&response_type=code');
57
+ });
58
+ it('should maintain the pre-existing query parameters in authorization URL', async () => {
59
+ oauth2Helper['providerAuthorizationUrl'] = 'https://provider.com/oauth/authorize?query1=value1&query2=value2';
60
+ await oauth2Helper.authorize();
61
+ sinon_1.default.assert.calledOnce(openSpy);
62
+ sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?query1=value1&query2=value2&client_id=your-client-id&redirect_uri=https%3A%2F%2Fintegrations-platform.unito.io%2Fcredentials%2Fnew%2Foauth2%2Fcallback-cli&state=eyJjbGlDYWxsYmFja1VybCI6Ii9vYXV0aDIvY2FsbGJhY2sifQ%3D%3D&scope=scope1+scope2&response_type=code');
63
+ });
125
64
  });
126
- it("should throw an error if we don't support the request content type", async () => {
127
- const refreshToken = 'test-refresh-token';
128
- oauth2Helper['refreshToken'] = refreshToken;
129
- oauth2Helper['requestContentType'] = 'random';
130
- const response = oauth2Helper.updateToken();
131
- await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.InvalidRequestContentTypeError);
65
+ describe('handleCallback', () => {
66
+ it('should retrieve the access token and return it in the response', async () => {
67
+ const code = 'test-code';
68
+ const req = { query: { code } };
69
+ const res = { send: sinon_1.default.stub(), setHeader: sinon_1.default.stub() };
70
+ await oauth2Helper['handleCallback'](req, res);
71
+ sinon_1.default.assert.calledOnce(fetchStub);
72
+ sinon_1.default.assert.calledWith(fetchStub, 'https://provider.com/oauth/token', {
73
+ headers: {
74
+ 'Content-type': 'application/x-www-form-urlencoded',
75
+ Authorization: 'custom',
76
+ },
77
+ body: sinon_1.default.match.string,
78
+ method: 'POST',
79
+ });
80
+ sinon_1.default.assert.calledOnce(res.send);
81
+ sinon_1.default.assert.calledWith(res.send, oauth2Namespace.HTML_SUCCESS_MSG);
82
+ });
83
+ it('should handle errors and return 500 status', async () => {
84
+ const code = 'test-code';
85
+ const req = { query: { code } };
86
+ const res = { send: sinon_1.default.stub(), setHeader: sinon_1.default.stub() };
87
+ fetchStub.rejects(new Error('Failed to retrieve access token'));
88
+ await oauth2Helper['handleCallback'](req, res);
89
+ sinon_1.default.assert.calledOnce(res.send);
90
+ sinon_1.default.assert.calledWith(res.send, oauth2Namespace.HTML_ERROR_MSG);
91
+ });
132
92
  });
133
- });
134
- describe('encodeBody', () => {
135
- it('should encode body data as URL-encoded when content type is URL_ENCODED', () => {
136
- const bodyData = { key1: 'value1', key2: 'value2' };
137
- const contentType = configurationTypes_1.RequestContentType.URL_ENCODED;
138
- const expectedEncodedBody = 'key1=value1&key2=value2';
139
- const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
140
- (0, chai_1.expect)(encodedBody).to.equal(expectedEncodedBody);
93
+ describe('updateToken', () => {
94
+ it('should retrieve the access token when a refresh token is available', async () => {
95
+ const refreshToken = 'test-refresh-token';
96
+ const accessToken = 'test-access-token';
97
+ const fetchResponse = { access_token: accessToken, refresh_token: refreshToken };
98
+ fetchStub.resolves({ status: 200, json: sinon_1.default.stub().resolves(fetchResponse) });
99
+ const result = await oauth2Helper.updateToken(refreshToken);
100
+ strict_1.default.deepEqual(result, { accessToken, refreshToken });
101
+ sinon_1.default.assert.calledOnce(fetchStub);
102
+ });
103
+ it('should throw an error when failing to refresh the access token', async () => {
104
+ const refreshToken = 'test-refresh-token';
105
+ fetchStub.rejects(new Error('Failed to retrieve access token'));
106
+ const response = oauth2Helper.updateToken(refreshToken);
107
+ await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
108
+ sinon_1.default.assert.calledOnce(fetchStub);
109
+ });
110
+ it("should throw an error if we don't support the request content type", async () => {
111
+ const refreshToken = 'test-refresh-token';
112
+ oauth2Helper['requestContentType'] = 'random';
113
+ const response = oauth2Helper.updateToken(refreshToken);
114
+ await strict_1.default.rejects(response, errors_1.InvalidRequestContentTypeError);
115
+ });
141
116
  });
142
- it('should encode body data as JSON when content type is JSON', () => {
143
- const bodyData = { key1: 'value1', key2: 'value2' };
144
- const contentType = configurationTypes_1.RequestContentType.JSON;
145
- const expectedEncodedBody = JSON.stringify(bodyData);
146
- const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
147
- (0, chai_1.expect)(encodedBody).to.equal(expectedEncodedBody);
117
+ describe('encodeBody', () => {
118
+ it('should encode body data as URL-encoded when content type is URL_ENCODED', () => {
119
+ const bodyData = { key1: 'value1', key2: 'value2' };
120
+ const contentType = configurationTypes_1.RequestContentType.URL_ENCODED;
121
+ const expectedEncodedBody = 'key1=value1&key2=value2';
122
+ const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
123
+ strict_1.default.equal(encodedBody, expectedEncodedBody);
124
+ });
125
+ it('should encode body data as JSON when content type is JSON', () => {
126
+ const bodyData = { key1: 'value1', key2: 'value2' };
127
+ const contentType = configurationTypes_1.RequestContentType.JSON;
128
+ const expectedEncodedBody = JSON.stringify(bodyData);
129
+ const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
130
+ strict_1.default.equal(encodedBody, expectedEncodedBody);
131
+ });
148
132
  });
149
133
  });
150
134
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const chai_1 = require("chai");
4
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
5
5
  const tmp_1 = tslib_1.__importDefault(require("tmp"));
6
6
  const fs_1 = tslib_1.__importDefault(require("fs"));
7
7
  const sinon = tslib_1.__importStar(require("sinon"));
@@ -41,19 +41,19 @@ describe('configuration', () => {
41
41
  throw Error('Should have thrown NoConfigurationFileError');
42
42
  }
43
43
  catch (error) {
44
- (0, chai_1.expect)(error).to.be.instanceOf(errors_2.NoConfigurationFileError);
44
+ (0, strict_1.default)(error instanceof errors_2.NoConfigurationFileError);
45
45
  }
46
46
  });
47
47
  it('handles missing specific environment file', async () => {
48
48
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
49
- (0, chai_1.expect)(configuration.name).to.equal(originalConfiguration.name);
49
+ strict_1.default.equal(configuration.name, originalConfiguration.name);
50
50
  });
51
51
  it('returns existing specific environment file', async () => {
52
52
  await fs_1.default.promises.writeFile(`${process.cwd()}/.unito.${globalConfiguration_1.Environment.Staging}.json`, JSON.stringify({
53
53
  name: 'foo',
54
54
  }, null, 2));
55
55
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
56
- (0, chai_1.expect)(configuration.name).to.equal('foo');
56
+ strict_1.default.equal(configuration.name, 'foo');
57
57
  });
58
58
  it('throws on missing custom configuration file', async () => {
59
59
  try {
@@ -61,7 +61,7 @@ describe('configuration', () => {
61
61
  throw Error('Should have thrown NoConfigurationFileError');
62
62
  }
63
63
  catch (error) {
64
- (0, chai_1.expect)(error).to.be.instanceOf(errors_2.NoConfigurationFileError);
64
+ (0, strict_1.default)(error instanceof errors_2.NoConfigurationFileError);
65
65
  }
66
66
  });
67
67
  it('returns existing specific environment file', async () => {
@@ -69,7 +69,7 @@ describe('configuration', () => {
69
69
  name: 'foo',
70
70
  }, null, 2));
71
71
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging, '/custom-config.json');
72
- (0, chai_1.expect)(configuration.name).to.equal('foo');
72
+ strict_1.default.equal(configuration.name, 'foo');
73
73
  });
74
74
  it('sets default values for "oauth2"', async () => {
75
75
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -90,9 +90,9 @@ describe('configuration', () => {
90
90
  }, null, 2));
91
91
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
92
92
  const oauth2 = configuration.authorizations?.at(0)?.oauth2;
93
- (0, chai_1.expect)(oauth2?.requestContentType).to.equal(configurationTypes_1.RequestContentType.URL_ENCODED);
94
- (0, chai_1.expect)(oauth2?.responseContentType).to.equal(configurationTypes_1.RequestContentType.JSON);
95
- (0, chai_1.expect)(oauth2?.grantType).to.equal(configurationTypes_1.GrantType.AUTHORIZATION_CODE);
93
+ strict_1.default.equal(oauth2?.requestContentType, configurationTypes_1.RequestContentType.URL_ENCODED);
94
+ strict_1.default.equal(oauth2?.responseContentType, configurationTypes_1.RequestContentType.JSON);
95
+ strict_1.default.equal(oauth2?.grantType, configurationTypes_1.GrantType.AUTHORIZATION_CODE);
96
96
  });
97
97
  it('accepts password grant for "oauth2"', async () => {
98
98
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -114,7 +114,7 @@ describe('configuration', () => {
114
114
  }, null, 2));
115
115
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
116
116
  const oauth2 = configuration.authorizations?.at(0)?.oauth2;
117
- (0, chai_1.expect)(oauth2?.grantType).to.equal(configurationTypes_1.GrantType.PASSWORD);
117
+ strict_1.default.equal(oauth2?.grantType, configurationTypes_1.GrantType.PASSWORD);
118
118
  });
119
119
  it('accepts request parameters for "oauth2"', async () => {
120
120
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -149,7 +149,7 @@ describe('configuration', () => {
149
149
  }, null, 2));
150
150
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
151
151
  const oauth2 = configuration.authorizations?.at(0)?.oauth2;
152
- (0, chai_1.expect)(oauth2?.tokenRequestParameters).to.deep.equal({
152
+ strict_1.default.deepEqual(oauth2?.tokenRequestParameters, {
153
153
  header: {
154
154
  a: 'yo',
155
155
  },
@@ -157,7 +157,7 @@ describe('configuration', () => {
157
157
  b: false,
158
158
  },
159
159
  });
160
- (0, chai_1.expect)(oauth2?.refreshRequestParameters).to.deep.equal({
160
+ strict_1.default.deepEqual(oauth2?.refreshRequestParameters, {
161
161
  body: {
162
162
  c: 1,
163
163
  },
@@ -172,7 +172,7 @@ describe('configuration', () => {
172
172
  },
173
173
  }, null, 2));
174
174
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
175
- (0, chai_1.expect)(configuration.secrets).to.deep.equal({ foo: 'unito-secret-v1://bar' });
175
+ strict_1.default.deepEqual(configuration.secrets, { foo: 'unito-secret-v1://bar' });
176
176
  });
177
177
  it('invalid secret - type', async () => {
178
178
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -181,7 +181,7 @@ describe('configuration', () => {
181
181
  foo: 123,
182
182
  },
183
183
  }, null, 2));
184
- await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
184
+ await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
185
185
  });
186
186
  it('invalid secret - pattern', async () => {
187
187
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -190,7 +190,7 @@ describe('configuration', () => {
190
190
  foo: 'nope',
191
191
  },
192
192
  }, null, 2));
193
- await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
193
+ await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
194
194
  });
195
195
  });
196
196
  describe('validates test accounts - custom', () => {
@@ -245,8 +245,8 @@ describe('configuration', () => {
245
245
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
246
246
  const developmentKey = configuration.testAccounts?.development?.apiKey;
247
247
  const complianceKey = configuration.testAccounts?.compliance?.apiKey;
248
- (0, chai_1.expect)(developmentKey).to.equal('xyz');
249
- (0, chai_1.expect)(complianceKey).to.equal('xyzw');
248
+ strict_1.default.equal(developmentKey, 'xyz');
249
+ strict_1.default.equal(complianceKey, 'xyzw');
250
250
  });
251
251
  it('invalid test accounts', async () => {
252
252
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -284,7 +284,7 @@ describe('configuration', () => {
284
284
  },
285
285
  },
286
286
  }, null, 2));
287
- await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
287
+ await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
288
288
  });
289
289
  });
290
290
  describe('validates test accounts - oauth', () => {
@@ -364,8 +364,8 @@ describe('configuration', () => {
364
364
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
365
365
  const developmentKey = configuration.testAccounts?.development?.accessToken;
366
366
  const complianceKey = configuration.testAccounts?.compliance?.accessToken;
367
- (0, chai_1.expect)(developmentKey).to.equal('Super_Secret_token');
368
- (0, chai_1.expect)(complianceKey).to.equal('Super_Secret_token_2');
367
+ strict_1.default.equal(developmentKey, 'Super_Secret_token');
368
+ strict_1.default.equal(complianceKey, 'Super_Secret_token_2');
369
369
  });
370
370
  it('invalid test accounts', async () => {
371
371
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -415,7 +415,7 @@ describe('configuration', () => {
415
415
  },
416
416
  },
417
417
  }, null, 2));
418
- await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
418
+ await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
419
419
  });
420
420
  });
421
421
  describe('validates test accounts - multiple authorization methods', () => {
@@ -509,8 +509,8 @@ describe('configuration', () => {
509
509
  const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
510
510
  const developmentKey = configuration.testAccounts?.development?.accessToken;
511
511
  const complianceKey = configuration.testAccounts?.compliance?.apiKey;
512
- (0, chai_1.expect)(developmentKey).to.equal('Super_Secret_token');
513
- (0, chai_1.expect)(complianceKey).to.equal('Super_Secret_api_key_2');
512
+ strict_1.default.equal(developmentKey, 'Super_Secret_token');
513
+ strict_1.default.equal(complianceKey, 'Super_Secret_api_key_2');
514
514
  });
515
515
  it('invalid test accounts', async () => {
516
516
  await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
@@ -579,7 +579,7 @@ describe('configuration', () => {
579
579
  },
580
580
  },
581
581
  }, null, 2));
582
- await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
582
+ await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
583
583
  });
584
584
  });
585
585
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const chai_1 = require("chai");
4
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
5
5
  const sinon_1 = tslib_1.__importDefault(require("sinon"));
6
6
  const IntegrationsPlatformResources = tslib_1.__importStar(require("../../src/resources/integrationsPlatform"));
7
7
  const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform"));
@@ -40,8 +40,8 @@ describe('decryption helper', () => {
40
40
  accessToken: 'developmentToken',
41
41
  accessToken1: 'developmentToken1',
42
42
  });
43
- (0, chai_1.expect)(decryptionResult.decryptedKeys).to.deep.equal([]);
44
- (0, chai_1.expect)(decryptionResult.entries).to.deep.equal({
43
+ strict_1.default.deepEqual(decryptionResult.decryptedKeys, []);
44
+ strict_1.default.deepEqual(decryptionResult.entries, {
45
45
  accessToken1: 'developmentToken1',
46
46
  accessToken: 'developmentToken',
47
47
  });
@@ -51,8 +51,8 @@ describe('decryption helper', () => {
51
51
  accessToken: 'token',
52
52
  encryptedToken: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
53
53
  });
54
- (0, chai_1.expect)(decryptionResult.decryptedKeys).to.deep.equal(['encryptedToken']);
55
- (0, chai_1.expect)(decryptionResult.entries).to.deep.equal({
54
+ strict_1.default.deepEqual(decryptionResult.decryptedKeys, ['encryptedToken']);
55
+ strict_1.default.deepEqual(decryptionResult.entries, {
56
56
  accessToken: 'token',
57
57
  encryptedToken: `decrypted-me`,
58
58
  });
@@ -62,16 +62,16 @@ describe('decryption helper', () => {
62
62
  encryptedSecret1: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
63
63
  encryptedSecret2: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
64
64
  });
65
- (0, chai_1.expect)(decryptionResult.decryptedKeys).to.deep.equal(['encryptedSecret1', 'encryptedSecret2']);
66
- (0, chai_1.expect)(decryptionResult.entries).to.deep.equal({
65
+ strict_1.default.deepEqual(decryptionResult.decryptedKeys, ['encryptedSecret1', 'encryptedSecret2']);
66
+ strict_1.default.deepEqual(decryptionResult.entries, {
67
67
  encryptedSecret1: 'decrypted-me',
68
68
  encryptedSecret2: 'decrypted-me',
69
69
  });
70
70
  });
71
71
  it('support empty object', async () => {
72
72
  const decryptionResult = await decryptionHelper.decryptEntries(configuration.name, GlobalConfiguration.Environment.Local, '/path/to/config', {});
73
- (0, chai_1.expect)(decryptionResult.decryptedKeys).to.deep.equal([]);
74
- (0, chai_1.expect)(decryptionResult.entries).to.deep.equal({});
73
+ strict_1.default.deepEqual(decryptionResult.decryptedKeys, []);
74
+ strict_1.default.deepEqual(decryptionResult.entries, {});
75
75
  });
76
76
  });
77
77
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const chai_1 = require("chai");
4
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
5
5
  const fs_1 = tslib_1.__importDefault(require("fs"));
6
6
  const sinon = tslib_1.__importStar(require("sinon"));
7
7
  const GlobalConfiguration = tslib_1.__importStar(require("../../src/resources/globalConfiguration"));
@@ -10,16 +10,16 @@ describe('globalConfiguration', () => {
10
10
  sinon.restore();
11
11
  });
12
12
  it('reads', async function () {
13
- const configuration = await GlobalConfiguration.getDefault();
13
+ const configuration = GlobalConfiguration.getDefault();
14
14
  configuration.apiKey = 'foo';
15
15
  sinon.stub(fs_1.default.promises, 'mkdir').resolves('');
16
16
  sinon.stub(fs_1.default.promises, 'readFile').resolves(JSON.stringify(configuration));
17
- (0, chai_1.expect)(await GlobalConfiguration.read('bar')).to.deep.equal(configuration);
17
+ strict_1.default.deepEqual(await GlobalConfiguration.read('bar'), configuration);
18
18
  });
19
19
  it('reads - error', async function () {
20
20
  sinon.stub(fs_1.default.promises, 'mkdir').resolves('');
21
21
  sinon.stub(fs_1.default.promises, 'readFile').throws();
22
- (0, chai_1.expect)(await GlobalConfiguration.read('bar')).to.deep.equal(await GlobalConfiguration.getDefault());
22
+ strict_1.default.deepEqual(await GlobalConfiguration.read('bar'), GlobalConfiguration.getDefault());
23
23
  });
24
24
  it('writes', async function () {
25
25
  const configuration = GlobalConfiguration.getDefault();
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
5
+ const path = tslib_1.__importStar(require("path"));
6
+ const tmp_1 = tslib_1.__importDefault(require("tmp"));
7
+ const fs_1 = tslib_1.__importDefault(require("fs"));
8
+ const Integration = tslib_1.__importStar(require("../../src/resources/integrations"));
9
+ const errors_1 = require("../../src/errors");
10
+ describe('integrations', () => {
11
+ let tempDir;
12
+ const boilerplatePath = path.join(__dirname, '../../boilerplate');
13
+ describe('copyBoilerplate', () => {
14
+ beforeEach(() => {
15
+ tempDir = tmp_1.default.dirSync().name;
16
+ });
17
+ it('copy files', async () => {
18
+ const result = await Integration.copyBoilerplate('foo', tempDir);
19
+ strict_1.default.equal(result, path.join(tempDir, 'foo'));
20
+ (0, strict_1.default)(fs_1.default.existsSync(result));
21
+ const expectedFiles = await fs_1.default.promises.readdir(boilerplatePath);
22
+ expectedFiles.push('.npmrc');
23
+ const createdFiles = await fs_1.default.promises.readdir(result);
24
+ strict_1.default.deepEqual(createdFiles, expectedFiles.sort());
25
+ createdFiles.forEach(createdField => (0, strict_1.default)(expectedFiles.includes(createdField)));
26
+ });
27
+ it('already exists', async () => {
28
+ strict_1.default.doesNotThrow(async () => await Integration.copyBoilerplate('foo', tempDir));
29
+ strict_1.default.rejects(Integration.copyBoilerplate('foo', tempDir), errors_1.IntegrationAlreadyExistsError);
30
+ });
31
+ it('generates an .npmrc file', async () => {
32
+ const result = await Integration.copyBoilerplate('foo', tempDir);
33
+ const npmrc = await fs_1.default.promises.readFile(`${result}/.npmrc`, 'utf-8');
34
+ (0, strict_1.default)(npmrc.includes('engine-strict=true'));
35
+ });
36
+ });
37
+ });
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
5
+ const sinon_1 = tslib_1.__importDefault(require("sinon"));
6
+ const oauth2Helper_1 = tslib_1.__importDefault(require("../../src/services/oauth2Helper"));
7
+ const configurationTypes_1 = require("../../src/configurationTypes");
8
+ const oauth2HelperResource = tslib_1.__importStar(require("../../src/resources/oauth2Helper"));
9
+ const errors_1 = require("../../src/errors");
10
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
11
+ describe('OAuth2Helper', () => {
12
+ let fetchStub;
13
+ const authorizationInfo = {
14
+ clientId: 'your-client-id',
15
+ clientSecret: 'your-client-secret',
16
+ authorizationUrl: 'https://provider.com/oauth/authorize',
17
+ scopes: [{ name: 'scope1' }, { name: 'scope2' }],
18
+ tokenUrl: 'https://provider.com/oauth/token',
19
+ grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
20
+ requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
21
+ responseContentType: configurationTypes_1.RequestContentType.JSON,
22
+ };
23
+ beforeEach(() => {
24
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'startServer').resolves('http://localhost:5050');
25
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'stopServer');
26
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'authorize');
27
+ sinon_1.default.stub(inquirer_1.default, 'prompt');
28
+ });
29
+ afterEach(() => {
30
+ sinon_1.default.restore();
31
+ });
32
+ describe('performOAuth2Flow', () => {
33
+ it('should perform the oauth flow', async () => {
34
+ fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
35
+ sinon_1.default.replace(global, 'fetch', fetchStub);
36
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({ accessToken: 'token' });
37
+ await oauth2HelperResource.performOAuth2Flow(authorizationInfo);
38
+ strict_1.default.equal(fetchStub.getCall(0).args.at(0), 'http://localhost:5050/health');
39
+ });
40
+ it('raises a FailedToRetrieveAccessTokenError', async () => {
41
+ fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
42
+ sinon_1.default.replace(global, 'fetch', fetchStub);
43
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({});
44
+ const response = oauth2HelperResource.performOAuth2Flow(authorizationInfo);
45
+ await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
46
+ });
47
+ it('raises a FailedToRetrieveAccessTokenError when the accessToken is not returned', async () => {
48
+ fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
49
+ sinon_1.default.replace(global, 'fetch', fetchStub);
50
+ sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({});
51
+ const response = oauth2HelperResource.performOAuth2Flow(authorizationInfo);
52
+ await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
53
+ });
54
+ });
55
+ });