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.
Files changed (52) hide show
  1. package/dist/cli.d.ts +16 -4
  2. package/dist/cli.js +76 -124
  3. package/dist/cli.js.map +1 -1
  4. package/dist/constants.d.ts +0 -1
  5. package/dist/constants.js +0 -1
  6. package/dist/constants.js.map +1 -1
  7. package/dist/index.js +38 -23
  8. package/dist/index.js.map +1 -1
  9. package/dist/services/compile.service.d.ts +14 -9
  10. package/dist/services/compile.service.js +71 -67
  11. package/dist/services/compile.service.js.map +1 -1
  12. package/dist/services/compile.service.unit.test.js +17 -7
  13. package/dist/services/compile.service.unit.test.js.map +1 -1
  14. package/dist/services/config.service.d.ts +16 -7
  15. package/dist/services/config.service.js +84 -55
  16. package/dist/services/config.service.js.map +1 -1
  17. package/dist/services/config.service.unit.test.d.ts +1 -0
  18. package/dist/services/config.service.unit.test.js +147 -0
  19. package/dist/services/config.service.unit.test.js.map +1 -0
  20. package/dist/services/deploy.service.d.ts +14 -5
  21. package/dist/services/deploy.service.js +81 -71
  22. package/dist/services/deploy.service.js.map +1 -1
  23. package/dist/services/dryrun.service.js +11 -11
  24. package/dist/services/dryrun.service.js.map +1 -1
  25. package/dist/services/migration.service.js +23 -26
  26. package/dist/services/migration.service.js.map +1 -1
  27. package/dist/services/model.service.d.ts +38 -8
  28. package/dist/services/model.service.js +129 -167
  29. package/dist/services/model.service.js.map +1 -1
  30. package/dist/services/model.service.unit.test.d.ts +1 -0
  31. package/dist/services/model.service.unit.test.js +138 -0
  32. package/dist/services/model.service.unit.test.js.map +1 -0
  33. package/dist/services/parser.service.d.ts +1 -2
  34. package/dist/services/parser.service.js +3 -4
  35. package/dist/services/parser.service.js.map +1 -1
  36. package/dist/services/verification.service.d.ts +9 -2
  37. package/dist/services/verification.service.js +20 -22
  38. package/dist/services/verification.service.js.map +1 -1
  39. package/dist/sync.unit.cli-test.js +157 -222
  40. package/dist/sync.unit.cli-test.js.map +1 -1
  41. package/dist/templates/action.ejs +2 -47
  42. package/dist/templates/nango.yaml +1 -2
  43. package/dist/templates/sync.ejs +1 -4
  44. package/dist/utils/layoutMode.d.ts +7 -0
  45. package/dist/utils/layoutMode.js +41 -0
  46. package/dist/utils/layoutMode.js.map +1 -0
  47. package/dist/utils.d.ts +0 -3
  48. package/dist/utils.js +4 -127
  49. package/dist/utils.js.map +1 -1
  50. package/lib/nango.yaml.schema.v2.json +183 -178
  51. package/package.json +7 -6
  52. package/dist/nango-sync.d.ts +0 -299
@@ -1,46 +1,50 @@
1
- import { expect, describe, it, afterEach, beforeAll } from 'vitest';
2
- import path from 'path';
3
- import * as fs from 'fs';
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 { SyncConfigType } from '@nangohq/shared';
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
- beforeAll(async () => {
17
- if (!fs.existsSync('./packages/cli/dist/nango-sync.d.ts')) {
18
- await fs.promises.writeFile('./packages/cli/dist/nango-sync.d.ts', '', 'utf8');
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
- await init();
26
- expect(fs.existsSync(`./${testDirectory}/demo-github-integration/syncs/${exampleSyncName}.ts`)).toBe(true);
27
- expect(fs.existsSync(`./${testDirectory}/.env`)).toBe(true);
28
- expect(fs.existsSync(`./${testDirectory}/nango.yaml`)).toBe(true);
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
32
- await fs.promises.mkdir(testDirectory, { recursive: true });
33
- await fs.promises.writeFile(`${testDirectory}/${exampleSyncName}.ts`, 'dummy fake content', 'utf8');
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(testDirectory, `${exampleSyncName}.ts`);
38
+ const exampleFilePath = path.join(dir, `${exampleSyncName}.ts`);
36
39
  await fs.promises.writeFile(exampleFilePath, dummyContent, 'utf8');
37
- await init();
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
72
- await generate(false, true);
73
- expect(fs.existsSync(`${testDirectory}/some-other-sync.ts`)).toBe(true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
105
- await generate(false, true);
106
- expect(fs.existsSync(`${testDirectory}/single-model-return.ts`)).toBe(true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
141
- await generate(false, true);
142
- expect(fs.existsSync(`${testDirectory}/demo-github-integration/syncs/single-model-return.ts`)).toBe(true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
176
- expect(fs.existsSync(`${testDirectory}/demo-github-integration/syncs/single-model-return.ts`)).toBe(false);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
211
- await generate(false, true);
212
- expect(fs.existsSync(`${testDirectory}/demo-github-integration/syncs/single-model-issue-output.ts`)).toBe(true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
243
- await expect(generate(false, true)).rejects.toThrow(`Model "GithubIssue" doesn't have an id field. This is required to be able to uniquely identify the data record.`);
244
- });
245
- it('should allow models to end in an s', async () => {
246
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
275
- await generate(false, true);
276
- const modelsFile = await fs.promises.readFile(`${testDirectory}/models.ts`, 'utf8');
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
307
- await generate(false, true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
327
- await generate(false, true);
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
- await init();
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(`${testDirectory}/nango.yaml`, yamlData, 'utf8');
347
- expect(await generate(false, true)).toBeUndefined();
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['GreenhouseEeoc']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['SomeBadModel']);
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`, SyncConfigType.ACTION, ['SomeModel']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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`, SyncConfigType.SYNC, ['GithubIssue']);
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
464
- await fs.promises.mkdir(testDirectory, { recursive: true });
465
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, './hubspot');
466
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, './github');
467
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, `./nango.yaml`);
468
- const success = await compileAllFiles({ debug: true });
469
- await fs.promises.rm('./hubspot', { recursive: true, force: true });
470
- await fs.promises.rm('./github', { recursive: true, force: true });
471
- await fs.promises.rm('./dist', { recursive: true, force: true });
472
- await fs.promises.rm('./nango.yaml', { force: true });
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
478
- await fs.promises.mkdir(testDirectory, { recursive: true });
479
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/non-nested-integrations`, './');
480
- const success = await compileAllFiles({ debug: true });
481
- await fs.promises.rm('./dist', { recursive: true, force: true });
482
- await fs.promises.rm('./nango.yaml', { force: true });
483
- await fs.promises.rm('./models.ts', { force: true });
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
492
- await fs.promises.mkdir(testDirectory, { recursive: true });
493
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`, './github');
494
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`, `./nango.yaml`);
495
- const success = await compileAllFiles({ debug: true });
496
- // @ts-expect-error - dynamic import
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
509
- await fs.promises.mkdir(testDirectory, { recursive: true });
510
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, './github');
511
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `./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: config } = await configService.load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
514
- if (config) {
515
- const modelNames = configService.getModelNames(config);
516
- const result = await compileSingleFile({ file: getFileToCompile('./github/actions/gh-issues.ts'), tsconfig, config, modelNames, debug: true });
517
- expect(result).toBe(false);
518
- }
519
- await fs.promises.rm('./github', { recursive: true, force: true });
520
- await fs.promises.rm('./dist', { recursive: true, force: true });
521
- await fs.promises.rm('./nango.yaml', { force: true });
522
- await fs.promises.rm('./models.ts', { force: true });
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
527
- await fs.promises.mkdir(testDirectory, { recursive: true });
528
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, './github');
529
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `./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: config } = await configService.load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
532
- if (config) {
533
- const modelNames = configService.getModelNames(config);
534
- const result = await compileSingleFile({ file: getFileToCompile('./github/actions/gh-issues.ts'), tsconfig, config, modelNames, debug: true });
535
- expect(result).toBe(false);
536
- }
537
- await fs.promises.rm('./github', { recursive: true, force: true });
538
- await fs.promises.rm('./dist', { recursive: true, force: true });
539
- await fs.promises.rm('./nango.yaml', { force: true });
540
- await fs.promises.rm('./models.ts', { force: true });
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
- await fs.promises.rm(testDirectory, { recursive: true, force: true });
545
- await fs.promises.mkdir(testDirectory, { recursive: true });
546
- await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, './github');
547
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `./nango.yaml`);
548
- await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, `../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: config } = await configService.load(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`));
551
- if (config) {
552
- const modelNames = configService.getModelNames(config);
553
- const result = await compileSingleFile({ file: getFileToCompile('./github/actions/gh-issues.ts'), tsconfig, config, modelNames, debug: true });
554
- expect(result).toBe(false);
555
- }
556
- await fs.promises.rm('./github', { recursive: true, force: true });
557
- await fs.promises.rm('./dist', { recursive: true, force: true });
558
- await fs.promises.rm('./nango.yaml', { force: true });
559
- await fs.promises.rm('./models.ts', { force: true });
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