nango 0.40.0 → 0.40.2
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/dist/cli.d.ts +16 -4
- package/dist/cli.js +76 -124
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +38 -23
- package/dist/index.js.map +1 -1
- package/dist/services/compile.service.d.ts +14 -9
- package/dist/services/compile.service.js +71 -67
- package/dist/services/compile.service.js.map +1 -1
- package/dist/services/compile.service.unit.test.js +17 -7
- package/dist/services/compile.service.unit.test.js.map +1 -1
- package/dist/services/config.service.d.ts +16 -7
- package/dist/services/config.service.js +84 -55
- package/dist/services/config.service.js.map +1 -1
- package/dist/services/config.service.unit.test.d.ts +1 -0
- package/dist/services/config.service.unit.test.js +147 -0
- package/dist/services/config.service.unit.test.js.map +1 -0
- package/dist/services/deploy.service.d.ts +14 -5
- package/dist/services/deploy.service.js +81 -71
- package/dist/services/deploy.service.js.map +1 -1
- package/dist/services/dryrun.service.js +11 -11
- package/dist/services/dryrun.service.js.map +1 -1
- package/dist/services/migration.service.js +23 -26
- package/dist/services/migration.service.js.map +1 -1
- package/dist/services/model.service.d.ts +38 -8
- package/dist/services/model.service.js +129 -167
- package/dist/services/model.service.js.map +1 -1
- package/dist/services/model.service.unit.test.d.ts +1 -0
- package/dist/services/model.service.unit.test.js +138 -0
- package/dist/services/model.service.unit.test.js.map +1 -0
- package/dist/services/parser.service.d.ts +1 -2
- package/dist/services/parser.service.js +3 -4
- package/dist/services/parser.service.js.map +1 -1
- package/dist/services/verification.service.d.ts +9 -2
- package/dist/services/verification.service.js +20 -22
- package/dist/services/verification.service.js.map +1 -1
- package/dist/sync.unit.cli-test.js +157 -222
- package/dist/sync.unit.cli-test.js.map +1 -1
- package/dist/templates/action.ejs +2 -47
- package/dist/templates/nango.yaml +1 -2
- package/dist/templates/sync.ejs +1 -4
- package/dist/utils/layoutMode.d.ts +7 -0
- package/dist/utils/layoutMode.js +41 -0
- package/dist/utils/layoutMode.js.map +1 -0
- package/dist/utils.d.ts +0 -3
- package/dist/utils.js +4 -127
- package/dist/utils.js.map +1 -1
- package/lib/nango.yaml.schema.v2.json +183 -178
- package/package.json +7 -6
- package/dist/nango-sync.d.ts +0 -299
|
@@ -1,46 +1,50 @@
|
|
|
1
|
-
import { expect, describe, it, afterEach,
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import
|
|
1
|
+
import { expect, describe, it, afterEach, vi } from 'vitest';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'fs';
|
|
4
4
|
import yaml from 'js-yaml';
|
|
5
|
-
import
|
|
5
|
+
import stripAnsi from 'strip-ansi';
|
|
6
6
|
import { init, generate } from './cli.js';
|
|
7
7
|
import { exampleSyncName } from './constants.js';
|
|
8
|
-
import configService from './services/config.service.js';
|
|
9
8
|
import { compileAllFiles, compileSingleFile, getFileToCompile } from './services/compile.service.js';
|
|
10
9
|
import { getNangoRootPath } from './utils.js';
|
|
11
10
|
import parserService from './services/parser.service.js';
|
|
12
11
|
import { copyDirectoryAndContents } from './tests/helpers.js';
|
|
12
|
+
import { load } from './services/config.service.js';
|
|
13
|
+
function getTestDirectory(name) {
|
|
14
|
+
const dir = `/tmp/${name}/nango-integrations/`;
|
|
15
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
16
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
17
|
+
return dir;
|
|
18
|
+
}
|
|
13
19
|
describe('generate function tests', () => {
|
|
14
|
-
const testDirectory = './nango-integrations';
|
|
15
20
|
const fixturesPath = './packages/cli/fixtures';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
afterEach(async () => {
|
|
22
|
-
await fs.promises.rm(testDirectory, { recursive: true, force: true });
|
|
21
|
+
// Not the best but until we have a logger it will work
|
|
22
|
+
const consoleMock = vi.spyOn(console, 'log').mockImplementation(() => undefined);
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
consoleMock.mockReset();
|
|
23
25
|
});
|
|
24
26
|
it('should init the expected files in the nango-integrations directory', async () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
expect(fs.existsSync(
|
|
28
|
-
expect(fs.existsSync(
|
|
27
|
+
const dir = getTestDirectory('init');
|
|
28
|
+
init({ absolutePath: path.resolve(dir, '..'), debug: false });
|
|
29
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/${exampleSyncName}.ts`)).toBe(true);
|
|
30
|
+
expect(fs.existsSync(`${dir}/.env`)).toBe(true);
|
|
31
|
+
expect(fs.existsSync(`${dir}/nango.yaml`)).toBe(true);
|
|
29
32
|
});
|
|
30
33
|
it('should not overwrite existing integration files', async () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
await fs.promises.writeFile(`${
|
|
34
|
+
const dir = getTestDirectory('overwrite');
|
|
35
|
+
init({ absolutePath: dir, debug: false });
|
|
36
|
+
await fs.promises.writeFile(`${dir}/${exampleSyncName}.ts`, 'dummy fake content', 'utf8');
|
|
34
37
|
const dummyContent = 'This is dummy content. Do not overwrite!';
|
|
35
|
-
const exampleFilePath = path.join(
|
|
38
|
+
const exampleFilePath = path.join(dir, `${exampleSyncName}.ts`);
|
|
36
39
|
await fs.promises.writeFile(exampleFilePath, dummyContent, 'utf8');
|
|
37
|
-
|
|
40
|
+
init({ absolutePath: dir });
|
|
38
41
|
expect(fs.existsSync(exampleFilePath)).toBe(true);
|
|
39
42
|
const fileContentAfterInit = await fs.promises.readFile(exampleFilePath, 'utf8');
|
|
40
43
|
expect(fileContentAfterInit).toBe(dummyContent);
|
|
41
44
|
});
|
|
42
45
|
it('should generate a different sync correctly', async () => {
|
|
43
|
-
|
|
46
|
+
const dir = getTestDirectory('generate');
|
|
47
|
+
init({ absolutePath: dir });
|
|
44
48
|
const data = {
|
|
45
49
|
integrations: {
|
|
46
50
|
'demo-github-integration': {
|
|
@@ -68,12 +72,13 @@ describe('generate function tests', () => {
|
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
const yamlData = yaml.dump(data);
|
|
71
|
-
await fs.promises.writeFile(`${
|
|
72
|
-
|
|
73
|
-
expect(fs.existsSync(`${
|
|
75
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
76
|
+
generate({ debug: true, fullPath: dir });
|
|
77
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/some-other-sync.ts`)).toBe(true);
|
|
74
78
|
});
|
|
75
79
|
it('should support a single model return in v1 format', async () => {
|
|
76
|
-
|
|
80
|
+
const dir = getTestDirectory('single-model-v1');
|
|
81
|
+
init({ absolutePath: dir });
|
|
77
82
|
const data = {
|
|
78
83
|
integrations: {
|
|
79
84
|
'demo-github-integration': {
|
|
@@ -101,20 +106,20 @@ describe('generate function tests', () => {
|
|
|
101
106
|
}
|
|
102
107
|
};
|
|
103
108
|
const yamlData = yaml.dump(data);
|
|
104
|
-
await fs.promises.writeFile(`${
|
|
105
|
-
|
|
106
|
-
expect(fs.existsSync(`${
|
|
109
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
110
|
+
generate({ debug: false, fullPath: dir });
|
|
111
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(true);
|
|
107
112
|
});
|
|
108
113
|
it('should support a single model return in v2 format', async () => {
|
|
109
|
-
|
|
114
|
+
const dir = getTestDirectory('single-model-v2');
|
|
115
|
+
init({ absolutePath: dir });
|
|
110
116
|
const data = {
|
|
111
117
|
integrations: {
|
|
112
118
|
'demo-github-integration': {
|
|
113
119
|
syncs: {
|
|
114
120
|
'single-model-return': {
|
|
115
|
-
type: 'sync',
|
|
116
121
|
runs: 'every half hour',
|
|
117
|
-
endpoint: '/issues',
|
|
122
|
+
endpoint: 'GET /issues',
|
|
118
123
|
output: 'GithubIssue'
|
|
119
124
|
}
|
|
120
125
|
}
|
|
@@ -137,12 +142,13 @@ describe('generate function tests', () => {
|
|
|
137
142
|
}
|
|
138
143
|
};
|
|
139
144
|
const yamlData = yaml.dump(data);
|
|
140
|
-
await fs.promises.writeFile(`${
|
|
141
|
-
|
|
142
|
-
expect(fs.existsSync(`${
|
|
145
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
146
|
+
generate({ debug: false, fullPath: dir });
|
|
147
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(true);
|
|
143
148
|
});
|
|
144
149
|
it('should not create a file if endpoint is missing from a v2 config', async () => {
|
|
145
|
-
|
|
150
|
+
const dir = getTestDirectory('endpoint-missing-v2');
|
|
151
|
+
init({ absolutePath: dir });
|
|
146
152
|
const data = {
|
|
147
153
|
integrations: {
|
|
148
154
|
'demo-github-integration': {
|
|
@@ -172,17 +178,17 @@ describe('generate function tests', () => {
|
|
|
172
178
|
}
|
|
173
179
|
};
|
|
174
180
|
const yamlData = yaml.dump(data);
|
|
175
|
-
await fs.promises.writeFile(`${
|
|
176
|
-
expect(fs.existsSync(`${
|
|
181
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
182
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(false);
|
|
177
183
|
});
|
|
178
184
|
it('should generate missing from a v2 config', async () => {
|
|
179
|
-
|
|
185
|
+
const dir = getTestDirectory('v2-incremental-compile');
|
|
186
|
+
init({ absolutePath: dir });
|
|
180
187
|
const data = {
|
|
181
188
|
integrations: {
|
|
182
189
|
'demo-github-integration': {
|
|
183
190
|
syncs: {
|
|
184
191
|
'single-model-issue-output': {
|
|
185
|
-
type: 'sync',
|
|
186
192
|
runs: 'every half hour',
|
|
187
193
|
endpoint: 'GET /tickets/issue',
|
|
188
194
|
output: 'GithubIssue'
|
|
@@ -207,12 +213,13 @@ describe('generate function tests', () => {
|
|
|
207
213
|
}
|
|
208
214
|
};
|
|
209
215
|
const yamlData = yaml.dump(data);
|
|
210
|
-
await fs.promises.writeFile(`${
|
|
211
|
-
|
|
212
|
-
expect(fs.existsSync(`${
|
|
216
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
217
|
+
generate({ debug: false, fullPath: dir });
|
|
218
|
+
expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-issue-output.ts`)).toBe(true);
|
|
213
219
|
});
|
|
214
220
|
it('should throw an error if a model is missing an id that is actively used', async () => {
|
|
215
|
-
|
|
221
|
+
const dir = getTestDirectory('missing-id');
|
|
222
|
+
init({ absolutePath: dir });
|
|
216
223
|
const data = {
|
|
217
224
|
integrations: {
|
|
218
225
|
'demo-github-integration': {
|
|
@@ -239,11 +246,20 @@ describe('generate function tests', () => {
|
|
|
239
246
|
}
|
|
240
247
|
};
|
|
241
248
|
const yamlData = yaml.dump(data);
|
|
242
|
-
await fs.promises.writeFile(`${
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
249
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
250
|
+
const acc = [];
|
|
251
|
+
consoleMock.mockImplementation((m) => acc.push(stripAnsi(m)));
|
|
252
|
+
generate({ debug: false, fullPath: dir });
|
|
253
|
+
expect(acc).toStrictEqual([
|
|
254
|
+
'demo-github-integration > syncs > single-model-return > [output]',
|
|
255
|
+
' error Model "GithubIssue" doesn\'t have an id field. This is required to be able to uniquely identify the data record [model_missing_id]',
|
|
256
|
+
'',
|
|
257
|
+
'Your nango.yaml contains some errors'
|
|
258
|
+
]);
|
|
259
|
+
});
|
|
260
|
+
it('should allow models to end with an "s"', async () => {
|
|
261
|
+
const dir = getTestDirectory('model-with-an-s');
|
|
262
|
+
init({ absolutePath: dir });
|
|
247
263
|
const data = {
|
|
248
264
|
integrations: {
|
|
249
265
|
'demo-github-integration': {
|
|
@@ -271,13 +287,14 @@ describe('generate function tests', () => {
|
|
|
271
287
|
}
|
|
272
288
|
};
|
|
273
289
|
const yamlData = yaml.dump(data);
|
|
274
|
-
await fs.promises.writeFile(`${
|
|
275
|
-
|
|
276
|
-
const modelsFile = await fs.promises.readFile(`${
|
|
290
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
291
|
+
generate({ debug: false, fullPath: dir });
|
|
292
|
+
const modelsFile = await fs.promises.readFile(`${dir}/models.ts`, 'utf8');
|
|
277
293
|
expect(modelsFile).toContain('export interface GithubIssues');
|
|
278
294
|
});
|
|
279
295
|
it('should not throw an error if a model is missing an id for an action', async () => {
|
|
280
|
-
|
|
296
|
+
const dir = getTestDirectory('missing-id-action');
|
|
297
|
+
init({ absolutePath: dir });
|
|
281
298
|
const data = {
|
|
282
299
|
integrations: {
|
|
283
300
|
'demo-github-integration': {
|
|
@@ -303,11 +320,12 @@ describe('generate function tests', () => {
|
|
|
303
320
|
}
|
|
304
321
|
};
|
|
305
322
|
const yamlData = yaml.dump(data);
|
|
306
|
-
await fs.promises.writeFile(`${
|
|
307
|
-
|
|
323
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
324
|
+
generate({ debug: false, fullPath: dir });
|
|
308
325
|
});
|
|
309
326
|
it('should allow javascript primitives as a return type with no model', async () => {
|
|
310
|
-
|
|
327
|
+
const dir = getTestDirectory('model-returns-primitives');
|
|
328
|
+
init({ absolutePath: dir });
|
|
311
329
|
const data = {
|
|
312
330
|
integrations: {
|
|
313
331
|
'demo-github-integration': {
|
|
@@ -323,11 +341,12 @@ describe('generate function tests', () => {
|
|
|
323
341
|
}
|
|
324
342
|
};
|
|
325
343
|
const yamlData = yaml.dump(data);
|
|
326
|
-
await fs.promises.writeFile(`${
|
|
327
|
-
|
|
344
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
345
|
+
generate({ debug: false, fullPath: dir });
|
|
328
346
|
});
|
|
329
347
|
it('should catch non javascript primitives in the config', async () => {
|
|
330
|
-
|
|
348
|
+
const dir = getTestDirectory('model-returns-invalid-primitives');
|
|
349
|
+
init({ absolutePath: dir });
|
|
331
350
|
const data = {
|
|
332
351
|
integrations: {
|
|
333
352
|
'demo-github-integration': {
|
|
@@ -343,221 +362,137 @@ describe('generate function tests', () => {
|
|
|
343
362
|
}
|
|
344
363
|
};
|
|
345
364
|
const yamlData = yaml.dump(data);
|
|
346
|
-
await fs.promises.writeFile(`${
|
|
347
|
-
expect(
|
|
365
|
+
await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8');
|
|
366
|
+
expect(generate({ debug: false, fullPath: dir })).toBeUndefined();
|
|
348
367
|
});
|
|
349
368
|
it('should not complain of try catch not being awaited', () => {
|
|
350
|
-
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/sync.ts`,
|
|
369
|
+
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/sync.ts`, 'sync', ['GithubIssue']);
|
|
351
370
|
expect(awaiting).toBe(true);
|
|
352
371
|
});
|
|
353
372
|
it('should complain when a return statement is used', () => {
|
|
354
|
-
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/return-sync.ts`,
|
|
373
|
+
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/return-sync.ts`, 'sync', ['GithubIssue']);
|
|
355
374
|
expect(noReturnUsed).toBe(false);
|
|
356
375
|
});
|
|
357
376
|
it('should not complain when a return statement is used but does not return anything', () => {
|
|
358
|
-
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/void-return-sync.ts`,
|
|
377
|
+
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/void-return-sync.ts`, 'sync', ['GithubIssue']);
|
|
359
378
|
expect(noReturnUsed).toBe(true);
|
|
360
379
|
});
|
|
361
380
|
it('should not complain when a return statement is used in a nested function', () => {
|
|
362
|
-
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/nested-return-sync.ts`,
|
|
381
|
+
const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/nested-return-sync.ts`, 'sync', ['GreenhouseEeoc']);
|
|
363
382
|
expect(noReturnUsed).toBe(true);
|
|
364
383
|
});
|
|
365
384
|
it('should complain of a non try catch not being awaited', () => {
|
|
366
|
-
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/failing-sync.ts`,
|
|
385
|
+
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/failing-sync.ts`, 'sync', ['GithubIssue']);
|
|
367
386
|
expect(awaiting).toBe(false);
|
|
368
387
|
});
|
|
369
388
|
it('should not complain about a correct model', () => {
|
|
370
|
-
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`,
|
|
389
|
+
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`, 'sync', ['SomeBadModel']);
|
|
371
390
|
expect(usedCorrectly).toBe(true);
|
|
372
391
|
});
|
|
373
392
|
it('should not complain about awaiting when it is returned for an action', () => {
|
|
374
|
-
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/no-async-return.ts`,
|
|
393
|
+
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/no-async-return.ts`, 'action', ['SomeModel']);
|
|
375
394
|
expect(awaiting).toBe(true);
|
|
376
395
|
});
|
|
377
396
|
it('should complain about an incorrect model', () => {
|
|
378
|
-
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`,
|
|
397
|
+
const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`, 'sync', ['GithubIssue']);
|
|
379
398
|
expect(awaiting).toBe(false);
|
|
380
399
|
});
|
|
381
400
|
it('should complain if retryOn is used without retries', () => {
|
|
382
|
-
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-bad.ts`,
|
|
401
|
+
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-bad.ts`, 'sync', ['GithubIssue']);
|
|
383
402
|
expect(usedCorrectly).toBe(false);
|
|
384
403
|
});
|
|
385
404
|
it('should not complain if retryOn is used with retries', () => {
|
|
386
|
-
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-good.ts`,
|
|
405
|
+
const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-good.ts`, 'sync', ['GithubIssue']);
|
|
387
406
|
expect(usedCorrectly).toBe(false);
|
|
388
407
|
});
|
|
389
|
-
it('should parse a nango.yaml file that is version 1 as expected', async () => {
|
|
390
|
-
const { response: config } = await configService.load(path.resolve(__dirname, `../fixtures/nango-yaml/v1/valid`));
|
|
391
|
-
expect(config).toBeDefined();
|
|
392
|
-
expect(config).toMatchSnapshot();
|
|
393
|
-
});
|
|
394
|
-
it('v1 - should complain about commas at the end of declared types', async () => {
|
|
395
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
396
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v1/no-commas/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
397
|
-
expect(generate(false, true)).rejects.toThrow(`Field "integer," in the model GithubIssue ends with a comma or semicolon which is not allowed.`);
|
|
398
|
-
});
|
|
399
|
-
it('v1 - should complain about semi colons at the end of declared types', async () => {
|
|
400
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
401
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v1/no-semi-colons/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
402
|
-
expect(generate(false, true)).rejects.toThrow(`Field "integer;" in the model GithubIssue ends with a comma or semicolon which is not allowed.`);
|
|
403
|
-
});
|
|
404
|
-
it('should parse a nango.yaml file that is version 2 as expected', async () => {
|
|
405
|
-
const { response: config } = await configService.load(path.resolve(__dirname, `../fixtures/nango-yaml/v2/valid`));
|
|
406
|
-
expect(config).toBeDefined();
|
|
407
|
-
expect(config).toMatchSnapshot();
|
|
408
|
-
});
|
|
409
|
-
it('should throw a validation error on a nango.yaml file that is not formatted correctly -- missing endpoint', async () => {
|
|
410
|
-
const { response: config, error } = await configService.load(path.resolve(__dirname, `../fixtures/nango-yaml/v2/invalid.1`));
|
|
411
|
-
expect(config).toBeNull();
|
|
412
|
-
expect(error).toBeDefined();
|
|
413
|
-
expect(error?.message).toEqual('Problem validating the nango.yaml file.');
|
|
414
|
-
});
|
|
415
|
-
it('should throw a validation error on a nango.yaml file that is not formatted correctly -- webhook subscriptions are not allowed in an action', async () => {
|
|
416
|
-
const { response: config, error } = await configService.load(path.resolve(__dirname, `../fixtures/nango-yaml/v2/invalid.2`));
|
|
417
|
-
expect(config).toBeNull();
|
|
418
|
-
expect(error).toBeDefined();
|
|
419
|
-
expect(error?.message).toEqual('Problem validating the nango.yaml file.');
|
|
420
|
-
});
|
|
421
|
-
it('should correctly interpret a string union literal type', async () => {
|
|
422
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
423
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/string-literal/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
424
|
-
expect(generate(false, true));
|
|
425
|
-
const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
|
|
426
|
-
expect(modelsFile).toContain(`gender: 'male' | 'female';`);
|
|
427
|
-
});
|
|
428
|
-
it('should correctly interpret a union literal type with a string and a primitive', async () => {
|
|
429
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
430
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/mixed-literal/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
431
|
-
expect(generate(false, true));
|
|
432
|
-
const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
|
|
433
|
-
expect(modelsFile).toContain(`gender: 'male' | null;`);
|
|
434
|
-
});
|
|
435
|
-
it('should correctly interpret a union literal type with a string and a model', async () => {
|
|
436
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
437
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/mixed-literal-model/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
438
|
-
expect(generate(false, true));
|
|
439
|
-
const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
|
|
440
|
-
expect(modelsFile).toContain(`gender: 'male' | Other`);
|
|
441
|
-
expect(modelsFile).toContain(`user: User | Account`);
|
|
442
|
-
});
|
|
443
|
-
it('should correctly interpret a union types, array types, and record types', async () => {
|
|
444
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
445
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/mixed-types/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
446
|
-
expect(generate(false, true));
|
|
447
|
-
const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
|
|
448
|
-
expect(modelsFile).toContain(`record: Record<string, string>;`);
|
|
449
|
-
expect(modelsFile).toContain(`und: string | null | undefined;`);
|
|
450
|
-
expect(modelsFile).toContain(`def: 'male' | string | null | undefined;`);
|
|
451
|
-
expect(modelsFile).toContain(`reference: Other[];`);
|
|
452
|
-
expect(modelsFile).toContain(`nullableDate: Date | null;`);
|
|
453
|
-
});
|
|
454
|
-
it('should correctly interpret a union type with an array model', async () => {
|
|
455
|
-
await fs.promises.mkdir(testDirectory, { recursive: true });
|
|
456
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/model-array-types/nango.yaml`, `${testDirectory}/nango.yaml`);
|
|
457
|
-
expect(generate(false, true));
|
|
458
|
-
const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
|
|
459
|
-
expect(modelsFile).not.toContain(`'Other[]' | null | undefined;`);
|
|
460
|
-
expect(modelsFile).toContain(`Other[] | null | undefined;`);
|
|
461
|
-
});
|
|
462
408
|
it('should be able to compile files in nested directories', async () => {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`,
|
|
466
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`,
|
|
467
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`,
|
|
468
|
-
const success = await compileAllFiles({ debug: true });
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
await fs.promises.rm('./models.ts', { force: true });
|
|
409
|
+
const dir = getTestDirectory('nested');
|
|
410
|
+
init({ absolutePath: dir });
|
|
411
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, `${dir}/hubspot`);
|
|
412
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, `${dir}/github`);
|
|
413
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, `${dir}/nango.yaml`);
|
|
414
|
+
const success = await compileAllFiles({ fullPath: dir, debug: true });
|
|
415
|
+
expect(fs.existsSync(path.join(dir, 'models.ts'))).toBe(true);
|
|
416
|
+
expect(fs.existsSync(path.join(dir, 'hubspot/syncs/contacts.ts'))).toBe(true);
|
|
417
|
+
expect(fs.existsSync(path.join(dir, 'dist/contacts-hubspot.js'))).toBe(true);
|
|
418
|
+
expect(fs.existsSync(path.join(dir, 'dist/issues-github.js'))).toBe(true);
|
|
474
419
|
expect(success).toBe(true);
|
|
475
420
|
});
|
|
476
421
|
it('should be backwards compatible with the single directory for integration files', async () => {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/non-nested-integrations`,
|
|
480
|
-
const success = await compileAllFiles({ debug:
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
await fs.promises.rm('./contacts.ts', { force: true });
|
|
485
|
-
await fs.promises.rm('./create-contact.ts', { force: true });
|
|
486
|
-
await fs.promises.rm('./create-issue.ts', { force: true });
|
|
487
|
-
await fs.promises.rm('./issues.ts', { force: true });
|
|
422
|
+
const dir = getTestDirectory('old-directory');
|
|
423
|
+
init({ absolutePath: dir });
|
|
424
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/non-nested-integrations`, dir);
|
|
425
|
+
const success = await compileAllFiles({ fullPath: dir, debug: false });
|
|
426
|
+
expect(fs.existsSync(path.join(dir, 'models.ts'))).toBe(true);
|
|
427
|
+
expect(fs.existsSync(path.join(dir, 'contacts.ts'))).toBe(true);
|
|
428
|
+
expect(fs.existsSync(path.join(dir, 'dist/contacts-hubspot.js'))).toBe(true);
|
|
488
429
|
expect(success).toBe(true);
|
|
489
430
|
});
|
|
490
431
|
it('should be able to compile and run imported files', async () => {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`,
|
|
494
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`,
|
|
495
|
-
const success = await compileAllFiles({ debug:
|
|
496
|
-
|
|
497
|
-
const module = await import('./dist/issues.cjs');
|
|
432
|
+
const dir = getTestDirectory('relative-imports');
|
|
433
|
+
init({ absolutePath: dir });
|
|
434
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`, `${dir}/github`);
|
|
435
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`, `${dir}/nango.yaml`);
|
|
436
|
+
const success = await compileAllFiles({ fullPath: dir, debug: false });
|
|
437
|
+
const module = await import(`${dir}dist/issues-github.js`);
|
|
498
438
|
const result = module.default.default();
|
|
499
439
|
expect(result).toBe('Hello, world!');
|
|
500
|
-
await fs.promises.rm('./github', { recursive: true, force: true });
|
|
501
|
-
await fs.promises.rm('./dist', { recursive: true, force: true });
|
|
502
|
-
await fs.promises.rm('./nango.yaml', { force: true });
|
|
503
|
-
await fs.promises.rm('./models.ts', { force: true });
|
|
504
440
|
expect(success).toBe(true);
|
|
505
441
|
});
|
|
506
442
|
it('should compile helper functions and throw an error if there is a complication error with an imported file', async () => {
|
|
507
443
|
const name = 'relative-imports-with-error';
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`,
|
|
511
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`,
|
|
444
|
+
const dir = getTestDirectory('relative-imports-with-error');
|
|
445
|
+
init({ absolutePath: dir });
|
|
446
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`);
|
|
447
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`);
|
|
512
448
|
const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8');
|
|
513
|
-
const { response:
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
449
|
+
const { response: parsed } = load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
|
|
450
|
+
expect(parsed).not.toBeNull();
|
|
451
|
+
const result = await compileSingleFile({
|
|
452
|
+
fullPath: dir,
|
|
453
|
+
file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }),
|
|
454
|
+
tsconfig,
|
|
455
|
+
parsed: parsed,
|
|
456
|
+
debug: false
|
|
457
|
+
});
|
|
458
|
+
expect(result).toBe(false);
|
|
523
459
|
});
|
|
524
460
|
it('should complain if a nango call is used incorrectly in a nested file', async () => {
|
|
525
461
|
const name = 'relative-imports-with-nango-misuse';
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`,
|
|
529
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`,
|
|
462
|
+
const dir = getTestDirectory('relative-imports-with-nango-misuse');
|
|
463
|
+
init({ absolutePath: dir });
|
|
464
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`);
|
|
465
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`);
|
|
530
466
|
const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8');
|
|
531
|
-
const { response:
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
467
|
+
const { response: parsed } = load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
|
|
468
|
+
expect(parsed).not.toBeNull();
|
|
469
|
+
const result = await compileSingleFile({
|
|
470
|
+
fullPath: dir,
|
|
471
|
+
file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }),
|
|
472
|
+
tsconfig,
|
|
473
|
+
parsed: parsed,
|
|
474
|
+
debug: false
|
|
475
|
+
});
|
|
476
|
+
expect(result).toBe(false);
|
|
541
477
|
});
|
|
542
478
|
it('should not allow imports higher than the current directory', async () => {
|
|
543
479
|
const name = 'relative-imports-with-higher-import';
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`,
|
|
547
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`,
|
|
548
|
-
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`,
|
|
480
|
+
const dir = getTestDirectory('relative-imports-with-higher-import');
|
|
481
|
+
init({ absolutePath: dir });
|
|
482
|
+
await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`);
|
|
483
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`);
|
|
484
|
+
await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, `${dir}/welcomer.ts`);
|
|
549
485
|
const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8');
|
|
550
|
-
const { response:
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
await fs.promises.rm('../welcomer.ts', { force: true });
|
|
486
|
+
const { response: parsed } = load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
|
|
487
|
+
expect(parsed).not.toBeNull();
|
|
488
|
+
const result = await compileSingleFile({
|
|
489
|
+
fullPath: dir,
|
|
490
|
+
file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }),
|
|
491
|
+
tsconfig,
|
|
492
|
+
parsed: parsed,
|
|
493
|
+
debug: false
|
|
494
|
+
});
|
|
495
|
+
expect(result).toBe(false);
|
|
561
496
|
});
|
|
562
497
|
});
|
|
563
498
|
//# sourceMappingURL=sync.unit.cli-test.js.map
|