@redocly/cli 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/lib/__tests__/commands/build-docs.test.js +3 -3
- package/lib/__tests__/commands/bundle.test.js +5 -5
- package/lib/__tests__/commands/join.test.js +11 -11
- package/lib/__tests__/commands/lint.test.js +14 -14
- package/lib/__tests__/commands/push-region.test.js +1 -1
- package/lib/__tests__/commands/push.test.js +11 -11
- package/lib/__tests__/fetch-with-timeout.test.js +4 -13
- package/lib/__tests__/spinner.test.js +43 -0
- package/lib/__tests__/utils.test.js +36 -36
- package/lib/__tests__/wrapper.test.js +8 -8
- package/lib/cms/api/__tests__/api-keys.test.d.ts +1 -0
- package/lib/cms/api/__tests__/api-keys.test.js +26 -0
- package/lib/cms/api/__tests__/api.client.test.d.ts +1 -0
- package/lib/cms/api/__tests__/api.client.test.js +217 -0
- package/lib/cms/api/__tests__/domains.test.d.ts +1 -0
- package/lib/cms/api/__tests__/domains.test.js +13 -0
- package/lib/cms/api/api-client.d.ts +50 -0
- package/lib/cms/api/api-client.js +148 -0
- package/lib/cms/api/api-keys.d.ts +1 -0
- package/lib/cms/api/api-keys.js +24 -0
- package/lib/cms/api/domains.d.ts +1 -0
- package/lib/cms/api/domains.js +12 -0
- package/lib/cms/api/index.d.ts +3 -0
- package/lib/cms/api/index.js +19 -0
- package/lib/cms/api/types.d.ts +91 -0
- package/lib/cms/api/types.js +2 -0
- package/lib/cms/commands/__tests__/push-status.test.d.ts +1 -0
- package/lib/cms/commands/__tests__/push-status.test.js +164 -0
- package/lib/cms/commands/__tests__/push.test.d.ts +1 -0
- package/lib/cms/commands/__tests__/push.test.js +226 -0
- package/lib/cms/commands/push-status.d.ts +12 -0
- package/lib/cms/commands/push-status.js +150 -0
- package/lib/cms/commands/push.d.ts +23 -0
- package/lib/cms/commands/push.js +142 -0
- package/lib/cms/utils.d.ts +2 -0
- package/lib/cms/utils.js +6 -0
- package/lib/commands/build-docs/index.js +4 -4
- package/lib/commands/build-docs/utils.js +2 -2
- package/lib/commands/bundle.js +13 -13
- package/lib/commands/join.js +25 -25
- package/lib/commands/lint.js +10 -10
- package/lib/commands/login.js +2 -2
- package/lib/commands/preview-docs/index.js +4 -4
- package/lib/commands/preview-docs/preview-server/preview-server.js +2 -2
- package/lib/commands/preview-project/types.d.ts +1 -1
- package/lib/commands/push.d.ts +5 -0
- package/lib/commands/push.js +25 -17
- package/lib/commands/split/__tests__/index.test.js +2 -2
- package/lib/commands/split/index.js +17 -17
- package/lib/commands/stats.js +4 -4
- package/lib/index.d.ts +1 -1
- package/lib/index.js +130 -17
- package/lib/types.d.ts +8 -1
- package/lib/{__mocks__/utils.js → utils/__mocks__/miscellaneous.js} +1 -1
- package/lib/utils/assert-node-version.d.ts +1 -0
- package/lib/{fetch-with-timeout.js → utils/fetch-with-timeout.js} +2 -7
- package/lib/{utils.d.ts → utils/miscellaneous.d.ts} +1 -1
- package/lib/{utils.js → utils/miscellaneous.js} +2 -2
- package/lib/utils/spinner.d.ts +10 -0
- package/lib/utils/spinner.js +42 -0
- package/lib/{update-version-notifier.js → utils/update-version-notifier.js} +4 -4
- package/lib/wrapper.js +5 -5
- package/package.json +5 -3
- package/src/__tests__/commands/build-docs.test.ts +2 -2
- package/src/__tests__/commands/bundle.test.ts +2 -2
- package/src/__tests__/commands/join.test.ts +2 -2
- package/src/__tests__/commands/lint.test.ts +3 -3
- package/src/__tests__/commands/push-region.test.ts +1 -1
- package/src/__tests__/commands/push.test.ts +2 -2
- package/src/__tests__/fetch-with-timeout.test.ts +4 -16
- package/src/__tests__/spinner.test.ts +51 -0
- package/src/__tests__/utils.test.ts +2 -5
- package/src/__tests__/wrapper.test.ts +2 -2
- package/src/cms/api/__tests__/api-keys.test.ts +37 -0
- package/src/cms/api/__tests__/api.client.test.ts +275 -0
- package/src/cms/api/__tests__/domains.test.ts +15 -0
- package/src/cms/api/api-client.ts +199 -0
- package/src/cms/api/api-keys.ts +26 -0
- package/src/cms/api/domains.ts +11 -0
- package/src/cms/api/index.ts +3 -0
- package/src/cms/api/types.ts +101 -0
- package/src/cms/commands/__tests__/push-status.test.ts +212 -0
- package/src/cms/commands/__tests__/push.test.ts +293 -0
- package/src/cms/commands/push-status.ts +203 -0
- package/src/cms/commands/push.ts +215 -0
- package/src/cms/utils.ts +1 -0
- package/src/commands/build-docs/index.ts +1 -1
- package/src/commands/build-docs/utils.ts +1 -1
- package/src/commands/bundle.ts +2 -2
- package/src/commands/join.ts +2 -2
- package/src/commands/lint.ts +1 -1
- package/src/commands/login.ts +1 -1
- package/src/commands/preview-docs/index.ts +5 -1
- package/src/commands/preview-docs/preview-server/preview-server.ts +1 -1
- package/src/commands/preview-project/types.ts +1 -1
- package/src/commands/push.ts +15 -1
- package/src/commands/split/__tests__/index.test.ts +3 -4
- package/src/commands/split/index.ts +2 -2
- package/src/commands/stats.ts +2 -2
- package/src/index.ts +138 -20
- package/src/types.ts +8 -0
- package/src/{__mocks__/utils.ts → utils/__mocks__/miscellaneous.ts} +1 -1
- package/src/{fetch-with-timeout.ts → utils/fetch-with-timeout.ts} +1 -6
- package/src/{utils.ts → utils/miscellaneous.ts} +2 -2
- package/src/utils/spinner.ts +50 -0
- package/src/{update-version-notifier.ts → utils/update-version-notifier.ts} +2 -2
- package/src/wrapper.ts +7 -2
- package/tsconfig.tsbuildinfo +1 -1
- /package/lib/{assert-node-version.d.ts → __tests__/spinner.test.d.ts} +0 -0
- /package/lib/{__mocks__/utils.d.ts → utils/__mocks__/miscellaneous.d.ts} +0 -0
- /package/lib/{assert-node-version.js → utils/assert-node-version.js} +0 -0
- /package/lib/{fetch-with-timeout.d.ts → utils/fetch-with-timeout.d.ts} +0 -0
- /package/lib/{js-utils.d.ts → utils/js-utils.d.ts} +0 -0
- /package/lib/{js-utils.js → utils/js-utils.js} +0 -0
- /package/lib/{update-version-notifier.d.ts → utils/update-version-notifier.d.ts} +0 -0
- /package/src/{assert-node-version.ts → utils/assert-node-version.ts} +0 -0
- /package/src/{js-utils.ts → utils/js-utils.ts} +0 -0
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const
|
|
12
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
13
13
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
14
14
|
const colorette_1 = require("colorette");
|
|
15
15
|
const fs_1 = require("fs");
|
|
@@ -31,7 +31,7 @@ describe('isSubdir', () => {
|
|
|
31
31
|
['/foo', './bar', false],
|
|
32
32
|
['/foo', '/foo/..bar', true],
|
|
33
33
|
].forEach(([parent, child, expectRes]) => {
|
|
34
|
-
expect((0,
|
|
34
|
+
expect((0, miscellaneous_1.isSubdir)(parent, child)).toBe(expectRes);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
it('can correctly determine if subdir for windows-based paths', () => {
|
|
@@ -42,7 +42,7 @@ describe('isSubdir', () => {
|
|
|
42
42
|
['C:\\Foo', 'C:\\Bar', false],
|
|
43
43
|
['C:\\Foo', 'D:\\Foo\\Bar', false],
|
|
44
44
|
].forEach(([parent, child, expectRes]) => {
|
|
45
|
-
expect((0,
|
|
45
|
+
expect((0, miscellaneous_1.isSubdir)(parent, child)).toBe(expectRes);
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
afterEach(() => {
|
|
@@ -51,14 +51,14 @@ describe('isSubdir', () => {
|
|
|
51
51
|
});
|
|
52
52
|
describe('pathToFilename', () => {
|
|
53
53
|
it('should use correct path separator', () => {
|
|
54
|
-
const processedPath = (0,
|
|
54
|
+
const processedPath = (0, miscellaneous_1.pathToFilename)('/user/createWithList', '_');
|
|
55
55
|
expect(processedPath).toEqual('user_createWithList');
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
describe('getFallbackApisOrExit', () => {
|
|
59
59
|
it('should find alias by filename', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
60
|
fs_1.existsSync.mockImplementationOnce(() => true);
|
|
61
|
-
const entry = yield (0,
|
|
61
|
+
const entry = yield (0, miscellaneous_1.getFallbackApisOrExit)(['./test.yaml'], {
|
|
62
62
|
apis: {
|
|
63
63
|
main: {
|
|
64
64
|
root: 'test.yaml',
|
|
@@ -82,17 +82,17 @@ describe('printConfigLintTotals', () => {
|
|
|
82
82
|
jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
83
83
|
});
|
|
84
84
|
it('should print errors if such exist', () => {
|
|
85
|
-
(0,
|
|
85
|
+
(0, miscellaneous_1.printConfigLintTotals)(totalProblemsMock);
|
|
86
86
|
expect(process.stderr.write).toHaveBeenCalledWith('❌ Your config has 1 error.');
|
|
87
87
|
expect(redColoretteMocks).toHaveBeenCalledWith('❌ Your config has 1 error.');
|
|
88
88
|
});
|
|
89
89
|
it('should print warnign if no error', () => {
|
|
90
|
-
(0,
|
|
90
|
+
(0, miscellaneous_1.printConfigLintTotals)(Object.assign(Object.assign({}, totalProblemsMock), { errors: 0, warnings: 2 }));
|
|
91
91
|
expect(process.stderr.write).toHaveBeenCalledWith('⚠️ Your config has 2 warnings.\n');
|
|
92
92
|
expect(yellowColoretteMocks).toHaveBeenCalledWith('⚠️ Your config has 2 warnings.\n');
|
|
93
93
|
});
|
|
94
94
|
it('should print nothing if no error and no warnings', () => {
|
|
95
|
-
const result = (0,
|
|
95
|
+
const result = (0, miscellaneous_1.printConfigLintTotals)(Object.assign(Object.assign({}, totalProblemsMock), { errors: 0 }));
|
|
96
96
|
expect(result).toBeUndefined();
|
|
97
97
|
expect(process.stderr.write).toHaveBeenCalledTimes(0);
|
|
98
98
|
expect(yellowColoretteMocks).toHaveBeenCalledTimes(0);
|
|
@@ -124,7 +124,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
124
124
|
};
|
|
125
125
|
expect.assertions(1);
|
|
126
126
|
try {
|
|
127
|
-
yield (0,
|
|
127
|
+
yield (0, miscellaneous_1.getFallbackApisOrExit)([''], apisConfig);
|
|
128
128
|
}
|
|
129
129
|
catch (e) {
|
|
130
130
|
expect(e.message).toEqual('Path cannot be empty.');
|
|
@@ -134,7 +134,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
134
134
|
fs_1.existsSync.mockImplementationOnce(() => false);
|
|
135
135
|
expect.assertions(3);
|
|
136
136
|
try {
|
|
137
|
-
yield (0,
|
|
137
|
+
yield (0, miscellaneous_1.getFallbackApisOrExit)(undefined, config);
|
|
138
138
|
}
|
|
139
139
|
catch (e) {
|
|
140
140
|
expect(process.stderr.write).toHaveBeenCalledWith('\nsomeFile.yaml does not exist or is invalid.\n\n');
|
|
@@ -145,7 +145,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
145
145
|
it('should return valid array with results if such file exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
146
146
|
fs_1.existsSync.mockImplementationOnce(() => true);
|
|
147
147
|
jest.spyOn(path, 'resolve').mockImplementationOnce((_, path) => path);
|
|
148
|
-
const result = yield (0,
|
|
148
|
+
const result = yield (0, miscellaneous_1.getFallbackApisOrExit)(undefined, config);
|
|
149
149
|
expect(process.stderr.write).toHaveBeenCalledTimes(0);
|
|
150
150
|
expect(process.exit).toHaveBeenCalledTimes(0);
|
|
151
151
|
expect(result).toStrictEqual([
|
|
@@ -162,7 +162,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
162
162
|
fs_1.existsSync.mockImplementationOnce(() => false);
|
|
163
163
|
expect.assertions(3);
|
|
164
164
|
try {
|
|
165
|
-
yield (0,
|
|
165
|
+
yield (0, miscellaneous_1.getFallbackApisOrExit)(['someFile.yaml'], apisConfig);
|
|
166
166
|
}
|
|
167
167
|
catch (e) {
|
|
168
168
|
expect(process.stderr.write).toHaveBeenCalledWith('\nsomeFile.yaml does not exist or is invalid.\n\n');
|
|
@@ -177,7 +177,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
177
177
|
fs_1.existsSync.mockImplementationOnce(() => false);
|
|
178
178
|
expect.assertions(3);
|
|
179
179
|
try {
|
|
180
|
-
yield (0,
|
|
180
|
+
yield (0, miscellaneous_1.getFallbackApisOrExit)(['someFile.yaml', 'someFile2.yaml'], apisConfig);
|
|
181
181
|
}
|
|
182
182
|
catch (e) {
|
|
183
183
|
expect(process.stderr.write).toHaveBeenCalledWith('\nsomeFile.yaml does not exist or is invalid.\n\n');
|
|
@@ -194,7 +194,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
194
194
|
const existSyncMock = fs_1.existsSync.mockImplementation((path) => path.endsWith('someFile.yaml'));
|
|
195
195
|
expect.assertions(4);
|
|
196
196
|
try {
|
|
197
|
-
yield (0,
|
|
197
|
+
yield (0, miscellaneous_1.getFallbackApisOrExit)(undefined, configStub);
|
|
198
198
|
}
|
|
199
199
|
catch (e) {
|
|
200
200
|
expect(process.stderr.write).toHaveBeenCalledWith('\nnotExist.yaml does not exist or is invalid.\n\n');
|
|
@@ -215,7 +215,7 @@ describe('getFallbackApisOrExit', () => {
|
|
|
215
215
|
},
|
|
216
216
|
},
|
|
217
217
|
};
|
|
218
|
-
const result = yield (0,
|
|
218
|
+
const result = yield (0, miscellaneous_1.getFallbackApisOrExit)(undefined, apisConfig);
|
|
219
219
|
expect(process.stderr.write).toHaveBeenCalledTimes(0);
|
|
220
220
|
expect(result).toStrictEqual([
|
|
221
221
|
{
|
|
@@ -254,10 +254,10 @@ describe('langToExt', () => {
|
|
|
254
254
|
['typescript', '.ts'],
|
|
255
255
|
['tsx', '.tsx'],
|
|
256
256
|
])('should infer file extension from lang - %s', (lang, expected) => {
|
|
257
|
-
expect((0,
|
|
257
|
+
expect((0, miscellaneous_1.langToExt)(lang)).toBe(expected);
|
|
258
258
|
});
|
|
259
259
|
it('should ignore case when inferring file extension', () => {
|
|
260
|
-
expect((0,
|
|
260
|
+
expect((0, miscellaneous_1.langToExt)('JavaScript')).toBe('.js');
|
|
261
261
|
});
|
|
262
262
|
});
|
|
263
263
|
describe('sorTopLevelKeysForOas', () => {
|
|
@@ -288,7 +288,7 @@ describe('sorTopLevelKeysForOas', () => {
|
|
|
288
288
|
'x-webhooks',
|
|
289
289
|
'components',
|
|
290
290
|
];
|
|
291
|
-
const result = (0,
|
|
291
|
+
const result = (0, miscellaneous_1.sortTopLevelKeysForOas)(openApi);
|
|
292
292
|
Object.keys(result).forEach((key, index) => {
|
|
293
293
|
expect(key).toEqual(orderedKeys[index]);
|
|
294
294
|
});
|
|
@@ -328,7 +328,7 @@ describe('sorTopLevelKeysForOas', () => {
|
|
|
328
328
|
'responses',
|
|
329
329
|
'securityDefinitions',
|
|
330
330
|
];
|
|
331
|
-
const result = (0,
|
|
331
|
+
const result = (0, miscellaneous_1.sortTopLevelKeysForOas)(openApi);
|
|
332
332
|
Object.keys(result).forEach((key, index) => {
|
|
333
333
|
expect(key).toEqual(orderedKeys[index]);
|
|
334
334
|
});
|
|
@@ -349,31 +349,31 @@ describe('handleErrors', () => {
|
|
|
349
349
|
});
|
|
350
350
|
it('should handle ResolveError', () => {
|
|
351
351
|
const resolveError = new openapi_core_1.ResolveError(new Error('File not found'));
|
|
352
|
-
expect(() => (0,
|
|
352
|
+
expect(() => (0, miscellaneous_1.handleError)(resolveError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
353
353
|
expect(redColoretteMocks).toHaveBeenCalledTimes(1);
|
|
354
354
|
expect(process.stderr.write).toHaveBeenCalledWith(`Failed to resolve API description at openapi/test.yaml:\n\n - File not found.\n\n`);
|
|
355
355
|
});
|
|
356
356
|
it('should handle YamlParseError', () => {
|
|
357
357
|
const yamlParseError = new openapi_core_1.YamlParseError(new Error('Invalid yaml'), {});
|
|
358
|
-
expect(() => (0,
|
|
358
|
+
expect(() => (0, miscellaneous_1.handleError)(yamlParseError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
359
359
|
expect(redColoretteMocks).toHaveBeenCalledTimes(1);
|
|
360
360
|
expect(process.stderr.write).toHaveBeenCalledWith(`Failed to parse API description at openapi/test.yaml:\n\n - Invalid yaml.\n\n`);
|
|
361
361
|
});
|
|
362
362
|
it('should handle CircularJSONNotSupportedError', () => {
|
|
363
|
-
const circularError = new
|
|
364
|
-
expect(() => (0,
|
|
363
|
+
const circularError = new miscellaneous_1.CircularJSONNotSupportedError(new Error('Circular json'));
|
|
364
|
+
expect(() => (0, miscellaneous_1.handleError)(circularError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
365
365
|
expect(process.stderr.write).toHaveBeenCalledWith(`Detected circular reference which can't be converted to JSON.\n` +
|
|
366
366
|
`Try to use ${(0, colorette_1.blue)('yaml')} output or remove ${(0, colorette_1.blue)('--dereferenced')}.\n\n`);
|
|
367
367
|
});
|
|
368
368
|
it('should handle SyntaxError', () => {
|
|
369
369
|
const testError = new SyntaxError('Unexpected identifier');
|
|
370
370
|
testError.stack = 'test stack';
|
|
371
|
-
expect(() => (0,
|
|
371
|
+
expect(() => (0, miscellaneous_1.handleError)(testError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
372
372
|
expect(process.stderr.write).toHaveBeenCalledWith('Syntax error: Unexpected identifier test stack\n\n');
|
|
373
373
|
});
|
|
374
374
|
it('should throw unknown error', () => {
|
|
375
375
|
const testError = new Error('Test error');
|
|
376
|
-
expect(() => (0,
|
|
376
|
+
expect(() => (0, miscellaneous_1.handleError)(testError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
377
377
|
expect(process.stderr.write).toHaveBeenCalledWith(`Something went wrong when processing openapi/test.yaml:\n\n - Test error.\n\n`);
|
|
378
378
|
});
|
|
379
379
|
});
|
|
@@ -391,7 +391,7 @@ describe('checkIfRulesetExist', () => {
|
|
|
391
391
|
oas3_1: {},
|
|
392
392
|
async2: {},
|
|
393
393
|
};
|
|
394
|
-
expect(() => (0,
|
|
394
|
+
expect(() => (0, miscellaneous_1.checkIfRulesetExist)(rules)).toThrowError('⚠️ No rules were configured. Learn how to configure rules: https://redocly.com/docs/cli/rules/');
|
|
395
395
|
});
|
|
396
396
|
it('should not throw an error if rules are provided', () => {
|
|
397
397
|
const rules = {
|
|
@@ -399,13 +399,13 @@ describe('checkIfRulesetExist', () => {
|
|
|
399
399
|
oas3_0: {},
|
|
400
400
|
oas3_1: {},
|
|
401
401
|
};
|
|
402
|
-
(0,
|
|
402
|
+
(0, miscellaneous_1.checkIfRulesetExist)(rules);
|
|
403
403
|
});
|
|
404
404
|
});
|
|
405
405
|
describe('cleanColors', () => {
|
|
406
406
|
it('should remove colors from string', () => {
|
|
407
407
|
const stringWithColors = `String for ${(0, colorette_1.red)('test')}`;
|
|
408
|
-
const result = (0,
|
|
408
|
+
const result = (0, miscellaneous_1.cleanColors)(stringWithColors);
|
|
409
409
|
expect(result).not.toMatch(/\x1b\[\d+m/g);
|
|
410
410
|
});
|
|
411
411
|
});
|
|
@@ -427,7 +427,7 @@ describe('cleanArgs', () => {
|
|
|
427
427
|
apis: ['main@v1', 'fixtures/openapi.yaml', 'http://some.url/openapi.yaml'],
|
|
428
428
|
format: 'codeframe',
|
|
429
429
|
};
|
|
430
|
-
expect((0,
|
|
430
|
+
expect((0, miscellaneous_1.cleanArgs)(testArgs)).toEqual({
|
|
431
431
|
config: 'file-yaml',
|
|
432
432
|
apis: ['api-name@api-version', 'file-yaml', 'http://url'],
|
|
433
433
|
format: 'codeframe',
|
|
@@ -437,7 +437,7 @@ describe('cleanArgs', () => {
|
|
|
437
437
|
const testArgs = {
|
|
438
438
|
destination: '@org/name@version',
|
|
439
439
|
};
|
|
440
|
-
expect((0,
|
|
440
|
+
expect((0, miscellaneous_1.cleanArgs)(testArgs)).toEqual({
|
|
441
441
|
destination: '@organization/api-name@api-version',
|
|
442
442
|
});
|
|
443
443
|
});
|
|
@@ -465,7 +465,7 @@ describe('cleanRawInput', () => {
|
|
|
465
465
|
'--output',
|
|
466
466
|
'fixtures',
|
|
467
467
|
];
|
|
468
|
-
expect((0,
|
|
468
|
+
expect((0, miscellaneous_1.cleanRawInput)(rawInput)).toEqual('redocly bundle api-name@api-version file-yaml http://url --config=file-yaml --output folder');
|
|
469
469
|
});
|
|
470
470
|
it('should preserve safe data from raw CLI input', () => {
|
|
471
471
|
const rawInput = [
|
|
@@ -478,16 +478,16 @@ describe('cleanRawInput', () => {
|
|
|
478
478
|
'--skip-rule',
|
|
479
479
|
'operation-4xx-response',
|
|
480
480
|
];
|
|
481
|
-
expect((0,
|
|
481
|
+
expect((0, miscellaneous_1.cleanRawInput)(rawInput)).toEqual('redocly lint file-json --format stylish --extends=minimal --skip-rule operation-4xx-response');
|
|
482
482
|
});
|
|
483
483
|
describe('validateFileExtension', () => {
|
|
484
484
|
it('should return current file extension', () => {
|
|
485
|
-
expect((0,
|
|
485
|
+
expect((0, miscellaneous_1.getAndValidateFileExtension)('test.json')).toEqual('json');
|
|
486
486
|
});
|
|
487
487
|
it('should return yaml and print warning if file extension does not supported', () => {
|
|
488
488
|
const stderrMock = jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
489
489
|
colorette_1.yellow.mockImplementation((text) => text);
|
|
490
|
-
expect((0,
|
|
490
|
+
expect((0, miscellaneous_1.getAndValidateFileExtension)('test.xml')).toEqual('yaml');
|
|
491
491
|
expect(stderrMock).toHaveBeenCalledWith(`Unsupported file extension: xml. Using yaml.\n`);
|
|
492
492
|
});
|
|
493
493
|
});
|
|
@@ -500,13 +500,13 @@ describe('cleanRawInput', () => {
|
|
|
500
500
|
jest.restoreAllMocks();
|
|
501
501
|
});
|
|
502
502
|
it('should call stringifyYaml function', () => {
|
|
503
|
-
(0,
|
|
503
|
+
(0, miscellaneous_1.writeToFileByExtension)('test data', 'test.yaml');
|
|
504
504
|
expect(openapi_core_1.stringifyYaml).toHaveBeenCalledWith('test data', { noRefs: false });
|
|
505
505
|
expect(process.stderr.write).toHaveBeenCalledWith(`test data`);
|
|
506
506
|
});
|
|
507
507
|
it('should call JSON.stringify function', () => {
|
|
508
508
|
const stringifySpy = jest.spyOn(JSON, 'stringify').mockImplementation((data) => data);
|
|
509
|
-
(0,
|
|
509
|
+
(0, miscellaneous_1.writeToFileByExtension)('test data', 'test.json');
|
|
510
510
|
expect(stringifySpy).toHaveBeenCalledWith('test data', null, 2);
|
|
511
511
|
expect(process.stderr.write).toHaveBeenCalledWith(`test data`);
|
|
512
512
|
});
|
|
@@ -9,13 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const
|
|
12
|
+
const miscellaneous_1 = require("../utils/miscellaneous");
|
|
13
13
|
const process = require("process");
|
|
14
14
|
const wrapper_1 = require("../wrapper");
|
|
15
15
|
const lint_1 = require("../commands/lint");
|
|
16
16
|
const push_1 = require("../commands/push");
|
|
17
17
|
jest.mock('node-fetch');
|
|
18
|
-
jest.mock('../utils', () => ({
|
|
18
|
+
jest.mock('../utils/miscellaneous', () => ({
|
|
19
19
|
sendTelemetry: jest.fn(),
|
|
20
20
|
loadConfigAndHandleErrors: jest.fn(),
|
|
21
21
|
}));
|
|
@@ -25,29 +25,29 @@ jest.mock('../commands/lint', () => ({
|
|
|
25
25
|
}));
|
|
26
26
|
describe('commandWrapper', () => {
|
|
27
27
|
it('should send telemetry if there is "telemetry: on" in the config', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
-
|
|
28
|
+
miscellaneous_1.loadConfigAndHandleErrors.mockImplementation(() => {
|
|
29
29
|
return { telemetry: 'on', styleguide: { recommendedFallback: true } };
|
|
30
30
|
});
|
|
31
31
|
process.env.REDOCLY_TELEMETRY = 'on';
|
|
32
32
|
const wrappedHandler = (0, wrapper_1.commandWrapper)(lint_1.handleLint);
|
|
33
33
|
yield wrappedHandler({});
|
|
34
34
|
expect(lint_1.handleLint).toHaveBeenCalledTimes(1);
|
|
35
|
-
expect(
|
|
36
|
-
expect(
|
|
35
|
+
expect(miscellaneous_1.sendTelemetry).toHaveBeenCalledTimes(1);
|
|
36
|
+
expect(miscellaneous_1.sendTelemetry).toHaveBeenCalledWith({}, 0, false);
|
|
37
37
|
}));
|
|
38
38
|
it('should NOT send telemetry if there is "telemetry: off" in the config', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
-
|
|
39
|
+
miscellaneous_1.loadConfigAndHandleErrors.mockImplementation(() => {
|
|
40
40
|
return { telemetry: 'off', styleguide: { recommendedFallback: true } };
|
|
41
41
|
});
|
|
42
42
|
process.env.REDOCLY_TELEMETRY = 'on';
|
|
43
43
|
const wrappedHandler = (0, wrapper_1.commandWrapper)(lint_1.handleLint);
|
|
44
44
|
yield wrappedHandler({});
|
|
45
45
|
expect(lint_1.handleLint).toHaveBeenCalledTimes(1);
|
|
46
|
-
expect(
|
|
46
|
+
expect(miscellaneous_1.sendTelemetry).toHaveBeenCalledTimes(0);
|
|
47
47
|
}));
|
|
48
48
|
it('should pass files from arguments to config', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
49
|
const filesToPush = ['test1.yaml', 'test2.yaml'];
|
|
50
|
-
const loadConfigMock =
|
|
50
|
+
const loadConfigMock = miscellaneous_1.loadConfigAndHandleErrors;
|
|
51
51
|
const argv = {
|
|
52
52
|
files: filesToPush,
|
|
53
53
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const api_keys_1 = require("../api-keys");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
describe('getApiKeys()', () => {
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
jest.resetAllMocks();
|
|
8
|
+
});
|
|
9
|
+
it('should return api key from environment variable', () => {
|
|
10
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
11
|
+
expect((0, api_keys_1.getApiKeys)('test-domain')).toEqual('test-api-key');
|
|
12
|
+
});
|
|
13
|
+
it('should return api key from credentials file', () => {
|
|
14
|
+
process.env.REDOCLY_AUTHORIZATION = '';
|
|
15
|
+
jest.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
16
|
+
jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify({
|
|
17
|
+
['test-domain']: 'test-api-key-from-credentials-file',
|
|
18
|
+
}));
|
|
19
|
+
expect((0, api_keys_1.getApiKeys)('test-domain')).toEqual('test-api-key-from-credentials-file');
|
|
20
|
+
});
|
|
21
|
+
it('should throw an error if no api key provided', () => {
|
|
22
|
+
process.env.REDOCLY_AUTHORIZATION = '';
|
|
23
|
+
jest.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
24
|
+
expect(() => (0, api_keys_1.getApiKeys)('test-domain')).toThrowError('No api key provided, please use environment variable REDOCLY_AUTHORIZATION.');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const node_fetch_1 = require("node-fetch");
|
|
13
|
+
const FormData = require("form-data");
|
|
14
|
+
const api_client_1 = require("../api-client");
|
|
15
|
+
jest.mock('node-fetch', () => ({
|
|
16
|
+
default: jest.fn(),
|
|
17
|
+
}));
|
|
18
|
+
function mockFetchResponse(response) {
|
|
19
|
+
node_fetch_1.default.mockResolvedValue(response);
|
|
20
|
+
}
|
|
21
|
+
describe('ApiClient', () => {
|
|
22
|
+
const testToken = 'test-token';
|
|
23
|
+
const testDomain = 'test-domain.com';
|
|
24
|
+
const testOrg = 'test-org';
|
|
25
|
+
const testProject = 'test-project';
|
|
26
|
+
describe('getDefaultBranch()', () => {
|
|
27
|
+
let apiClient;
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
apiClient = new api_client_1.ReuniteApiClient(testDomain, testToken);
|
|
30
|
+
});
|
|
31
|
+
it('should get default project branch', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
mockFetchResponse({
|
|
33
|
+
ok: true,
|
|
34
|
+
json: jest.fn().mockResolvedValue({
|
|
35
|
+
branchName: 'test-branch',
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
const result = yield apiClient.remotes.getDefaultBranch(testOrg, testProject);
|
|
39
|
+
expect(node_fetch_1.default).toHaveBeenCalledWith(`${testDomain}/api/orgs/${testOrg}/projects/${testProject}/source`, {
|
|
40
|
+
method: 'GET',
|
|
41
|
+
headers: {
|
|
42
|
+
'Content-Type': 'application/json',
|
|
43
|
+
Authorization: `Bearer ${testToken}`,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
expect(result).toEqual('test-branch');
|
|
47
|
+
}));
|
|
48
|
+
it('should throw parsed error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
mockFetchResponse({
|
|
50
|
+
ok: false,
|
|
51
|
+
json: jest.fn().mockResolvedValue({
|
|
52
|
+
type: 'about:blank',
|
|
53
|
+
title: 'Project source not found',
|
|
54
|
+
status: 404,
|
|
55
|
+
detail: 'Not Found',
|
|
56
|
+
object: 'problem',
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
yield expect(apiClient.remotes.getDefaultBranch(testOrg, testProject)).rejects.toThrow(new Error('Failed to fetch default branch: Project source not found'));
|
|
60
|
+
}));
|
|
61
|
+
it('should throw statusText error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
+
mockFetchResponse({
|
|
63
|
+
ok: false,
|
|
64
|
+
statusText: 'Not found',
|
|
65
|
+
json: jest.fn().mockResolvedValue({
|
|
66
|
+
unknownField: 'unknown-error',
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
69
|
+
yield expect(apiClient.remotes.getDefaultBranch(testOrg, testProject)).rejects.toThrow(new Error('Failed to fetch default branch: Not found'));
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
describe('upsert()', () => {
|
|
73
|
+
const remotePayload = {
|
|
74
|
+
mountBranchName: 'remote-mount-branch-name',
|
|
75
|
+
mountPath: 'remote-mount-path',
|
|
76
|
+
};
|
|
77
|
+
let apiClient;
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
apiClient = new api_client_1.ReuniteApiClient(testDomain, testToken);
|
|
80
|
+
});
|
|
81
|
+
it('should upsert remote', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
const responseMock = {
|
|
83
|
+
id: 'remote-id',
|
|
84
|
+
type: 'CICD',
|
|
85
|
+
mountPath: 'remote-mount-path',
|
|
86
|
+
mountBranchName: 'remote-mount-branch-name',
|
|
87
|
+
organizationId: testOrg,
|
|
88
|
+
projectId: testProject,
|
|
89
|
+
};
|
|
90
|
+
mockFetchResponse({
|
|
91
|
+
ok: true,
|
|
92
|
+
json: jest.fn().mockResolvedValue(responseMock),
|
|
93
|
+
});
|
|
94
|
+
const result = yield apiClient.remotes.upsert(testOrg, testProject, remotePayload);
|
|
95
|
+
expect(node_fetch_1.default).toHaveBeenCalledWith(`${testDomain}/api/orgs/${testOrg}/projects/${testProject}/remotes`, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: {
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
Authorization: `Bearer ${testToken}`,
|
|
100
|
+
},
|
|
101
|
+
body: JSON.stringify({
|
|
102
|
+
mountPath: remotePayload.mountPath,
|
|
103
|
+
mountBranchName: remotePayload.mountBranchName,
|
|
104
|
+
type: 'CICD',
|
|
105
|
+
autoMerge: true,
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
expect(result).toEqual(responseMock);
|
|
109
|
+
}));
|
|
110
|
+
it('should throw parsed error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
111
|
+
mockFetchResponse({
|
|
112
|
+
ok: false,
|
|
113
|
+
json: jest.fn().mockResolvedValue({
|
|
114
|
+
type: 'about:blank',
|
|
115
|
+
title: 'Not allowed to mount remote outside of project content path: /docs',
|
|
116
|
+
status: 403,
|
|
117
|
+
detail: 'Forbidden',
|
|
118
|
+
object: 'problem',
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
yield expect(apiClient.remotes.upsert(testOrg, testProject, remotePayload)).rejects.toThrow(new Error('Failed to upsert remote: Not allowed to mount remote outside of project content path: /docs'));
|
|
122
|
+
}));
|
|
123
|
+
it('should throw statusText error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
+
mockFetchResponse({
|
|
125
|
+
ok: false,
|
|
126
|
+
statusText: 'Not found',
|
|
127
|
+
json: jest.fn().mockResolvedValue({
|
|
128
|
+
unknownField: 'unknown-error',
|
|
129
|
+
}),
|
|
130
|
+
});
|
|
131
|
+
yield expect(apiClient.remotes.upsert(testOrg, testProject, remotePayload)).rejects.toThrow(new Error('Failed to upsert remote: Not found'));
|
|
132
|
+
}));
|
|
133
|
+
});
|
|
134
|
+
describe('push()', () => {
|
|
135
|
+
const testRemoteId = 'test-remote-id';
|
|
136
|
+
const pushPayload = {
|
|
137
|
+
remoteId: testRemoteId,
|
|
138
|
+
commit: {
|
|
139
|
+
message: 'test-message',
|
|
140
|
+
author: {
|
|
141
|
+
name: 'test-name',
|
|
142
|
+
email: 'test-email',
|
|
143
|
+
},
|
|
144
|
+
branchName: 'test-branch-name',
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
const filesMock = [{ path: 'some-file.yaml', stream: Buffer.from('fefef') }];
|
|
148
|
+
const responseMock = {
|
|
149
|
+
branchName: 'rem/cicd/rem_01he7sr6ys2agb7w0g9t7978fn-main',
|
|
150
|
+
hasChanges: true,
|
|
151
|
+
files: [
|
|
152
|
+
{
|
|
153
|
+
type: 'file',
|
|
154
|
+
name: 'some-file.yaml',
|
|
155
|
+
path: 'docs/remotes/some-file.yaml',
|
|
156
|
+
lastModified: 1698925132394.2993,
|
|
157
|
+
mimeType: 'text/yaml',
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
commitSha: 'bb23a2f8e012ac0b7b9961b57fb40d8686b21b43',
|
|
161
|
+
outdated: false,
|
|
162
|
+
};
|
|
163
|
+
let apiClient;
|
|
164
|
+
beforeEach(() => {
|
|
165
|
+
apiClient = new api_client_1.ReuniteApiClient(testDomain, testToken);
|
|
166
|
+
});
|
|
167
|
+
it('should push to remote', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
+
let passedFormData = new FormData();
|
|
169
|
+
node_fetch_1.default.mockImplementationOnce((_, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
+
passedFormData = options.body;
|
|
171
|
+
return {
|
|
172
|
+
ok: true,
|
|
173
|
+
json: jest.fn().mockResolvedValue(responseMock),
|
|
174
|
+
};
|
|
175
|
+
}));
|
|
176
|
+
const formData = new FormData();
|
|
177
|
+
formData.append('remoteId', testRemoteId);
|
|
178
|
+
formData.append('commit[message]', pushPayload.commit.message);
|
|
179
|
+
formData.append('commit[author][name]', pushPayload.commit.author.name);
|
|
180
|
+
formData.append('commit[author][email]', pushPayload.commit.author.email);
|
|
181
|
+
formData.append('commit[branchName]', pushPayload.commit.branchName);
|
|
182
|
+
formData.append('files[some-file.yaml]', filesMock[0].stream);
|
|
183
|
+
const result = yield apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock);
|
|
184
|
+
expect(node_fetch_1.default).toHaveBeenCalledWith(`${testDomain}/api/orgs/${testOrg}/projects/${testProject}/pushes`, expect.objectContaining({
|
|
185
|
+
method: 'POST',
|
|
186
|
+
headers: {
|
|
187
|
+
Authorization: `Bearer ${testToken}`,
|
|
188
|
+
},
|
|
189
|
+
}));
|
|
190
|
+
expect(JSON.stringify(passedFormData).replace(new RegExp(passedFormData.getBoundary(), 'g'), '')).toEqual(JSON.stringify(formData).replace(new RegExp(formData.getBoundary(), 'g'), ''));
|
|
191
|
+
expect(result).toEqual(responseMock);
|
|
192
|
+
}));
|
|
193
|
+
it('should throw parsed error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
194
|
+
mockFetchResponse({
|
|
195
|
+
ok: false,
|
|
196
|
+
json: jest.fn().mockResolvedValue({
|
|
197
|
+
type: 'about:blank',
|
|
198
|
+
title: 'Cannot push to remote',
|
|
199
|
+
status: 403,
|
|
200
|
+
detail: 'Forbidden',
|
|
201
|
+
object: 'problem',
|
|
202
|
+
}),
|
|
203
|
+
});
|
|
204
|
+
yield expect(apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock)).rejects.toThrow(new Error('Failed to push: Cannot push to remote'));
|
|
205
|
+
}));
|
|
206
|
+
it('should throw statusText error if response is not ok', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
207
|
+
mockFetchResponse({
|
|
208
|
+
ok: false,
|
|
209
|
+
statusText: 'Not found',
|
|
210
|
+
json: jest.fn().mockResolvedValue({
|
|
211
|
+
unknownField: 'unknown-error',
|
|
212
|
+
}),
|
|
213
|
+
});
|
|
214
|
+
yield expect(apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock)).rejects.toThrow(new Error('Failed to push: Not found'));
|
|
215
|
+
}));
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const domains_1 = require("../domains");
|
|
4
|
+
describe('getDomain()', () => {
|
|
5
|
+
it('should return the domain from environment variable', () => {
|
|
6
|
+
process.env.REDOCLY_DOMAIN = 'test-domain';
|
|
7
|
+
expect((0, domains_1.getDomain)()).toBe('test-domain');
|
|
8
|
+
});
|
|
9
|
+
it('should return the default domain if no domain provided', () => {
|
|
10
|
+
process.env.REDOCLY_DOMAIN = '';
|
|
11
|
+
expect((0, domains_1.getDomain)()).toBe('https://app.cloud.redocly.com');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import type { ReadStream } from 'fs';
|
|
4
|
+
import type { ListRemotesResponse, PushResponse, UpsertRemoteResponse } from './types';
|
|
5
|
+
declare class RemotesApiClient {
|
|
6
|
+
private readonly domain;
|
|
7
|
+
private readonly apiKey;
|
|
8
|
+
constructor(domain: string, apiKey: string);
|
|
9
|
+
private getParsedResponse;
|
|
10
|
+
getDefaultBranch(organizationId: string, projectId: string): Promise<string>;
|
|
11
|
+
upsert(organizationId: string, projectId: string, remote: {
|
|
12
|
+
mountPath: string;
|
|
13
|
+
mountBranchName: string;
|
|
14
|
+
}): Promise<UpsertRemoteResponse>;
|
|
15
|
+
push(organizationId: string, projectId: string, payload: PushPayload, files: {
|
|
16
|
+
path: string;
|
|
17
|
+
stream: ReadStream | Buffer;
|
|
18
|
+
}[]): Promise<PushResponse>;
|
|
19
|
+
getRemotesList(organizationId: string, projectId: string, mountPath: string): Promise<ListRemotesResponse>;
|
|
20
|
+
getPush({ organizationId, projectId, pushId, }: {
|
|
21
|
+
organizationId: string;
|
|
22
|
+
projectId: string;
|
|
23
|
+
pushId: string;
|
|
24
|
+
}): Promise<PushResponse>;
|
|
25
|
+
}
|
|
26
|
+
export declare class ReuniteApiClient {
|
|
27
|
+
domain: string;
|
|
28
|
+
private readonly apiKey;
|
|
29
|
+
remotes: RemotesApiClient;
|
|
30
|
+
constructor(domain: string, apiKey: string);
|
|
31
|
+
}
|
|
32
|
+
export type PushPayload = {
|
|
33
|
+
remoteId: string;
|
|
34
|
+
commit: {
|
|
35
|
+
message: string;
|
|
36
|
+
branchName: string;
|
|
37
|
+
sha?: string;
|
|
38
|
+
url?: string;
|
|
39
|
+
createdAt?: string;
|
|
40
|
+
namespace?: string;
|
|
41
|
+
repository?: string;
|
|
42
|
+
author: {
|
|
43
|
+
name: string;
|
|
44
|
+
email: string;
|
|
45
|
+
image?: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
isMainBranch?: boolean;
|
|
49
|
+
};
|
|
50
|
+
export {};
|