From 89a7c5cd89af8b65ac3946de559fb41f13438cab Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Tue, 25 Jun 2024 04:51:53 -0500 Subject: [PATCH 01/10] fix(cli): handle Windows paths in `nango compile` (#2312) --- packages/cli/lib/services/compile.service.ts | 25 +++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index cc4aef6dda2..ea24efc8824 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -250,7 +250,7 @@ export function getFileToCompile({ fullPath, filePath }: { fullPath: string; fil const baseName = path.basename(filePath, '.ts'); return { inputPath: filePath, - outputPath: path.join(fullPath, '/dist/', `${baseName}.js`), + outputPath: path.join(fullPath, 'dist', `${baseName}.js`), baseName }; } @@ -295,7 +295,7 @@ export function listFilesToCompile({ files = [path.join(fullPath, scriptDirectory || '', `${scriptName}.ts`)]; } else { - files = glob.sync(`${fullPath}/*.ts`); + files = getMatchingFiles(fullPath, 'ts'); // models.ts is the one expected file if (files.length === 1 && debug) { @@ -309,19 +309,19 @@ export function listFilesToCompile({ files = [ ...files, - ...glob.sync(`${fullPath}/${syncPath}/*.ts`), - ...glob.sync(`${fullPath}/${actionPath}/*.ts`), - ...glob.sync(`${fullPath}/${postConnectionPath}/*.ts`) + ...getMatchingFiles(fullPath, syncPath, 'ts'), + ...getMatchingFiles(fullPath, actionPath, 'ts'), + ...getMatchingFiles(fullPath, postConnectionPath, 'ts') ]; if (debug) { - if (glob.sync(`${fullPath}/${syncPath}/*.ts`).length > 0) { + if (getMatchingFiles(fullPath, syncPath, 'ts').length > 0) { printDebug(`Found nested sync files in ${syncPath}`); } - if (glob.sync(`${fullPath}/${actionPath}/*.ts`).length > 0) { + if (getMatchingFiles(fullPath, actionPath, 'ts').length > 0) { printDebug(`Found nested action files in ${actionPath}`); } - if (glob.sync(`${fullPath}/${postConnectionPath}/*.ts`).length > 0) { + if (getMatchingFiles(fullPath, postConnectionPath, 'ts').length > 0) { printDebug(`Found nested post connection script files in ${postConnectionPath}`); } } @@ -332,3 +332,12 @@ export function listFilesToCompile({ return getFileToCompile({ fullPath, filePath }); }); } + +// get array of posix file paths that match the given path parts. +// last part is treated as a file extension. +// eg getMatchingFiles('foo', 'ts') -> glob.sync('foo/*.ts') +function getMatchingFiles(...args: string[]): string[] { + args.splice(-1, 1, `*.${args.slice(-1)[0]}`); + const pattern = args.join('/'); + return glob.sync(pattern, { posix: true }); +} From 2f8cbd472f7be144a4947b41b39954f4aa74ed00 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Tue, 25 Jun 2024 04:59:49 -0500 Subject: [PATCH 02/10] fix(cli): handle Windows paths in `nango dev` (#2312) replaces \ in paths with / --- packages/cli/lib/cli.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index fad2164d65b..66d99a4be0c 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -238,6 +238,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? } watcher.on('add', async (filePath: string) => { + filePath = filePath.replace(/\\/g, '/'); if (filePath === nangoConfigFile) { return; } @@ -245,6 +246,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('unlink', (filePath: string) => { + filePath = filePath.replace(/\\/g, '/'); if (filePath === nangoConfigFile) { return; } @@ -261,6 +263,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('change', async (filePath: string) => { + filePath = filePath.replace(/\\/g, '/'); if (filePath === nangoConfigFile) { await compileAllFiles({ fullPath, debug }); return; From 578f270806d113d34fdbd9ea81106513a4152349 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Tue, 25 Jun 2024 19:21:34 -0500 Subject: [PATCH 03/10] fix(cli): handle Windows paths in `npm run test:cli` (#2312) some tests failed on Windows --- packages/cli/lib/services/model.service.ts | 3 ++- packages/cli/lib/sync.unit.cli-test.ts | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/cli/lib/services/model.service.ts b/packages/cli/lib/services/model.service.ts index 647933939d2..1207d9beda9 100644 --- a/packages/cli/lib/services/model.service.ts +++ b/packages/cli/lib/services/model.service.ts @@ -153,7 +153,8 @@ export function fieldToTypescript({ field }: { field: NangoModelField }): string */ export function generateSDKTypes() { const filePath = resolve('@nangohq/shared/dist/sdk/sync.d.ts', import.meta.url); - const typesContent = fs.readFileSync(filePath.replace('file://', ''), 'utf8'); + const url = new URL(filePath); + const typesContent = fs.readFileSync(url, 'utf8'); return ` ${typesContent} diff --git a/packages/cli/lib/sync.unit.cli-test.ts b/packages/cli/lib/sync.unit.cli-test.ts index 5e4c3affbe6..387ecc434d6 100644 --- a/packages/cli/lib/sync.unit.cli-test.ts +++ b/packages/cli/lib/sync.unit.cli-test.ts @@ -1,5 +1,6 @@ import { expect, describe, it, afterEach, vi } from 'vitest'; import path from 'node:path'; +import os from 'node:os'; import fs from 'fs'; import yaml from 'js-yaml'; import stripAnsi from 'strip-ansi'; @@ -12,7 +13,8 @@ import { copyDirectoryAndContents, removeVersion } from './tests/helpers.js'; import { parse } from './services/config.service.js'; function getTestDirectory(name: string) { - const dir = `/tmp/${name}/nango-integrations/`; + const tmpdir = os.tmpdir(); + const dir = path.join(tmpdir, name, 'nango-integrations'); fs.mkdirSync(dir, { recursive: true }); fs.rmSync(dir, { recursive: true, force: true }); return dir; @@ -480,7 +482,7 @@ describe('generate function tests', () => { const success = await compileAllFiles({ fullPath: dir, debug: false }); - const module = await import(`${dir}dist/issues-github.js`); + const module = await import(`${dir}/dist/issues-github.js`); const result = module.default.default(); expect(result).toBe('Hello, world!'); From 419fe0930e40803e1efe1b87ab4145ca31807ab8 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Tue, 2 Jul 2024 15:04:02 -0500 Subject: [PATCH 04/10] temp --- .github/workflows/tests.yaml | 5 +- packages/cli/lib/cli.ts | 19 +++-- packages/cli/lib/services/compile.service.ts | 79 +++++++++++++++---- .../lib/services/compile.service.unit.test.ts | 14 +++- packages/cli/lib/services/config.service.ts | 4 +- packages/cli/lib/sync.unit.cli-test.ts | 10 ++- packages/cli/lib/tests/helpers.ts | 3 + packages/nango-yaml/lib/helpers.ts | 8 +- packages/nango-yaml/lib/load.ts | 3 +- packages/node-client/lib/utils.unit.test.ts | 2 +- 10 files changed, 113 insertions(+), 34 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 8ed18ebe879..ceea62e9a0a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,11 +13,14 @@ concurrency: jobs: tests: - runs-on: ubuntu-latest + # runs-on: ubuntu-latest strategy: matrix: + os: [ubuntu-latest, windows-latest] node-version: [18.x, 20.x] + runs-on: ${{ matrix.os }} + steps: - uses: actions/checkout@v4 with: diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index 66d99a4be0c..159c200b960 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -54,9 +54,11 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? }); const stripped = rendered.replace(/^\s+/, ''); - if (!fs.existsSync(`${fullPath}/${providerConfigKey}/${type}s/${name}.ts`)) { - fs.mkdirSync(`${fullPath}/${providerConfigKey}/${type}s`, { recursive: true }); - fs.writeFileSync(`${fullPath}/${providerConfigKey}/${type}s/${name}.ts`, stripped); + //.............. + // if (!fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`)) { + if (!fs.existsSync(path.join(fullPath, `{providerConfigKey}/${type}s/${name}.ts`))) { + fs.mkdirSync(path.join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); + fs.writeFileSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); if (debug) { printDebug(`Created ${name}.ts file`); } @@ -81,7 +83,7 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? process.exit(1); } - if (fs.existsSync(`${fullPath}/${name}.ts`) || fs.existsSync(`${fullPath}/${providerConfigKey}/${type}s/${name}.ts`)) { + if (fs.existsSync(path.join(fullPath, `${name}.ts`)) || fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { if (debug) { printDebug(`${name}.ts file already exists, so will not overwrite it.`); } @@ -119,10 +121,10 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? const stripped = rendered.replace(/^\s+/, ''); if (layoutMode === 'root') { - fs.writeFileSync(`${fullPath}/${name}.ts`, stripped); + fs.writeFileSync(path.join(fullPath, `${name}.ts`), stripped); } else { - fs.mkdirSync(`${fullPath}/${providerConfigKey}/${type}s`, { recursive: true }); - fs.writeFileSync(`${fullPath}/${providerConfigKey}/${type}s/${name}.ts`, stripped); + fs.mkdirSync(path.join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); + fs.writeFileSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); } if (debug) { console.log(chalk.green(`Created ${name}.ts file`)); @@ -203,7 +205,8 @@ NANGO_DEPLOY_AUTO_CONFIRM=false # Default value` } export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + // const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + const tsconfig = fs.readFileSync(path.join(getNangoRootPath()!, 'tsconfig.dev.json'), 'utf8'); const res = loadYamlAndGenerate({ fullPath, debug }); if (!res.success) { console.log(chalk.red(res.error?.message)); diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index ea24efc8824..2c749dd9811 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -26,7 +26,11 @@ export async function compileAllFiles({ providerConfigKey?: string; type?: ScriptFileType; }): Promise { - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + console.log('compileAllFiles', fullPath); + + // const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + const tsconfig = fs.readFileSync(path.join(getNangoRootPath() || '', 'tsconfig.dev.json'), 'utf8'); + console.log('tsconfig', tsconfig); const distDir = path.join(fullPath, 'dist'); if (!fs.existsSync(distDir)) { @@ -43,15 +47,15 @@ export async function compileAllFiles({ const parsed = res.response!; const compilerOptions = (JSON.parse(tsconfig) as { compilerOptions: Record }).compilerOptions; + if (debug) { + printDebug(`Compiler options: ${JSON.stringify(compilerOptions, null, 2)}`); + } + const compiler = tsNode.create({ skipProject: true, // when installed locally we don't want ts-node to pick up the package tsconfig.json file compilerOptions }); - if (debug) { - printDebug(`Compiler options: ${JSON.stringify(compilerOptions, null, 2)}`); - } - let scriptDirectory: string | undefined; if (scriptName && providerConfigKey && type) { scriptDirectory = resolveTsFileLocation({ fullPath, scriptName, providerConfigKey, type }).replace(fullPath, ''); @@ -59,10 +63,12 @@ export async function compileAllFiles({ } const integrationFiles = listFilesToCompile({ scriptName, fullPath, scriptDirectory, parsed, debug }); - let success = true; + console.log('integrationFiles', integrationFiles); + let success = true; for (const file of integrationFiles) { try { + // console.log('calling compile', { fullPath, file, parsed }); const completed = await compile({ fullPath, file, parsed, compiler, debug }); if (!completed) { if (scriptName && file.inputPath.includes(scriptName)) { @@ -191,42 +197,50 @@ async function compile({ compiler: tsNode.Service; debug: boolean; }): Promise { - const providerConfiguration = getProviderConfigurationFromPath({ filePath: file.inputPath, parsed }); + console.log('compile', { fullPath, file }); + //. get _, eg foo.yaml? + const providerConfiguration = getProviderConfigurationFromPath({ filePath: file.inputPath, parsed }); if (!providerConfiguration) { return false; } + // get _, eg 'sync', ... const syncConfig = [...providerConfiguration.syncs, ...providerConfiguration.actions].find((sync) => sync.name === file.baseName); const type = syncConfig?.type || 'sync'; + //. compile any imported files? const success = compileImportedFile({ fullPath, filePath: file.inputPath, compiler, type, parsed }); - if (!success) { return false; } + //. compile ts file with tsNode ? + console.log('compile with tsNode...'); compiler.compile(fs.readFileSync(file.inputPath, 'utf8'), file.inputPath); + // get output path, eg 'email-gmail-... .ts' ? const dirname = path.dirname(file.outputPath); const extname = path.extname(file.outputPath); const basename = path.basename(file.outputPath, extname); - const fileNameWithExtension = `${basename}-${providerConfiguration.providerConfigKey}${extname}`; const outputPath = path.join(dirname, fileNameWithExtension); - if (debug) { printDebug(`Compiling ${file.inputPath} -> ${outputPath}`); } + //. compile with tsup ? but used tsNode above? + console.log('calling build...'); + // build may throw an error await build({ entryPoints: [file.inputPath], - tsconfig: path.join(getNangoRootPath()!, 'tsconfig.dev.json'), + tsconfig: path.join(getNangoRootPath() || '', 'tsconfig.dev.json'), skipNodeModulesBundle: true, silent: !debug, outDir: path.join(fullPath, 'dist'), outExtension: () => ({ js: '.js' }), onSuccess: async () => { + console.log('onSuccess - file:', file); if (fs.existsSync(file.outputPath)) { await fs.promises.rename(file.outputPath, outputPath); console.log(chalk.green(`Compiled "${file.inputPath}" successfully`)); @@ -250,7 +264,8 @@ export function getFileToCompile({ fullPath, filePath }: { fullPath: string; fil const baseName = path.basename(filePath, '.ts'); return { inputPath: filePath, - outputPath: path.join(fullPath, 'dist', `${baseName}.js`), + // outputPath: path.join(fullPath, 'dist', `${baseName}.js`), + outputPath: path.join(fullPath, `dist/${baseName}.js`), baseName }; } @@ -266,7 +281,8 @@ export function resolveTsFileLocation({ providerConfigKey: string; type: ScriptFileType; }) { - const nestedPath = path.resolve(fullPath, providerConfigKey, type, `${scriptName}.ts`); + // const nestedPath = path.resolve(fullPath, providerConfigKey, type, `${scriptName}.ts`); + const nestedPath = path.resolve(fullPath, `${providerConfigKey}/${type}/${scriptName}.ts`); if (fs.existsSync(nestedPath)) { return fs.realpathSync(path.resolve(nestedPath, '../')); } @@ -313,6 +329,7 @@ export function listFilesToCompile({ ...getMatchingFiles(fullPath, actionPath, 'ts'), ...getMatchingFiles(fullPath, postConnectionPath, 'ts') ]; + console.log('files', files); if (debug) { if (getMatchingFiles(fullPath, syncPath, 'ts').length > 0) { @@ -333,11 +350,41 @@ export function listFilesToCompile({ }); } -// get array of posix file paths that match the given path parts. +// get array of file paths that match the given path parts. // last part is treated as a file extension. // eg getMatchingFiles('foo', 'ts') -> glob.sync('foo/*.ts') function getMatchingFiles(...args: string[]): string[] { args.splice(-1, 1, `*.${args.slice(-1)[0]}`); - const pattern = args.join('/'); - return glob.sync(pattern, { posix: true }); + console.log('args', args); + // const pattern = args.join('/'); + // console.log('pattern', pattern); + // return glob.sync(pattern, { posix: true }); + const pattern = path.join(...args); + console.log('pattern', pattern); + + // windowsPathsNoEscape + // Use \\ as a path separator only, and never as an escape + // character. + // If set, all \\ characters are replaced with / in the + // pattern. Note that this makes it impossible to match + // against paths containing literal glob pattern characters, + // but allows matching with patterns constructed using + // path.join() and path.resolve() on Windows platforms, + // mimicking the (buggy!) behavior of Glob v7 and before on + // Windows. + + // absolute + // Set to false to always return relative paths. When + // this option is not set, absolute paths are returned for + // patterns that are absolute, and otherwise paths are + // returned that are relative to the cwd setting. + + // posix + // Return / delimited paths, even on Windows. + // On posix systems, this has no effect. But, on Windows, it + // means that paths will be / delimited, and absolute paths + // will be their full resolved UNC forms, eg instead of + // 'C:\\foo\\bar', it would return '//?/C:/foo/bar' + + return glob.sync(pattern, { windowsPathsNoEscape: true, absolute: false, posix: true }); } diff --git a/packages/cli/lib/services/compile.service.unit.test.ts b/packages/cli/lib/services/compile.service.unit.test.ts index 1b5f9242217..038aa9164e2 100644 --- a/packages/cli/lib/services/compile.service.unit.test.ts +++ b/packages/cli/lib/services/compile.service.unit.test.ts @@ -4,16 +4,26 @@ import { getFileToCompile, listFilesToCompile } from './compile.service'; import { fileURLToPath } from 'node:url'; import type { NangoYamlParsed } from '@nangohq/types'; +// eg "C:\Users\bburns\Workspace\test\various\src" const thisFolder = path.dirname(fileURLToPath(import.meta.url)); +// function join(...args) { +// args = args.map(arg => ) +// return path.join(...args) +// } + describe('listFiles', () => { it('should list files with glob', () => { const files = listFilesToCompile({ fullPath: thisFolder, parsed: { integrations: [], models: new Map(), yamlVersion: 'v2' } }); expect(files.length).toBeGreaterThan(1); expect(files[0]).toStrictEqual({ baseName: 'verification.service', - inputPath: `${thisFolder}/verification.service.ts`, - outputPath: `${thisFolder}/dist/verification.service.js` + // inputPath: `${thisFolder}/verification.service.ts`, + // outputPath: `${thisFolder}/dist/verification.service.js` + // inputPath: path.join(thisFolder, 'verification.service.ts'), + // outputPath: path.join(thisFolder, 'dist', 'verification.service.js') + inputPath: path.join(thisFolder, 'verification.service.ts'), + outputPath: path.join(thisFolder, 'dist/verification.service.js') }); }); diff --git a/packages/cli/lib/services/config.service.ts b/packages/cli/lib/services/config.service.ts index 833cc3be401..53978f2f95e 100644 --- a/packages/cli/lib/services/config.service.ts +++ b/packages/cli/lib/services/config.service.ts @@ -1,4 +1,5 @@ import fs from 'fs'; +import path from 'path'; import Ajv from 'ajv'; import addErrors from 'ajv-errors'; import chalk from 'chalk'; @@ -100,7 +101,8 @@ export function validateYaml(yaml: any): ValidationMessage[] { const version = determineVersion(yaml); const validationFile = version === 'v1' ? 'nango.yaml.schema.v1.json' : 'nango.yaml.schema.v2.json'; - const schema = fs.readFileSync(`${getNangoRootPath()}/lib/${validationFile}`, 'utf8'); + // const schema = fs.readFileSync(`${getNangoRootPath()}/lib/${validationFile}`, 'utf8'); + const schema = fs.readFileSync(path.join(getNangoRootPath() || '', `lib/${validationFile}`), 'utf8'); const validate = ajv.compile(JSON.parse(schema)); if (validate(yaml)) { diff --git a/packages/cli/lib/sync.unit.cli-test.ts b/packages/cli/lib/sync.unit.cli-test.ts index 387ecc434d6..962ee341a95 100644 --- a/packages/cli/lib/sync.unit.cli-test.ts +++ b/packages/cli/lib/sync.unit.cli-test.ts @@ -445,12 +445,16 @@ describe('generate function tests', () => { const dir = getTestDirectory('nested'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, `${dir}/hubspot`); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, `${dir}/github`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, `${dir}/nango.yaml`); + // await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, `${dir}/hubspot`); + await copyDirectoryAndContents(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/hubspot'), path.join(dir, 'hubspot')); + // await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, `${dir}/github`); + await copyDirectoryAndContents(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/github'), path.join(dir, 'github')); + // await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, `${dir}/nango.yaml`); + await fs.promises.copyFile(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/nango.yaml'), path.join(dir, 'nango.yaml')); const success = await compileAllFiles({ fullPath: dir, debug: true }); + //. these should report any failed paths somehow, not just true!=false expect(fs.existsSync(path.join(dir, 'models.ts'))).toBe(true); expect(fs.existsSync(path.join(dir, 'hubspot/syncs/contacts.ts'))).toBe(true); expect(fs.existsSync(path.join(dir, 'dist/contacts-hubspot.js'))).toBe(true); diff --git a/packages/cli/lib/tests/helpers.ts b/packages/cli/lib/tests/helpers.ts index 6f216a47cdc..a712d8d61a3 100644 --- a/packages/cli/lib/tests/helpers.ts +++ b/packages/cli/lib/tests/helpers.ts @@ -2,6 +2,9 @@ import path from 'path'; import fs from 'fs/promises'; export const copyDirectoryAndContents = async (source: string, destination: string) => { + // source = path.join(...source.split('/')); + // destination = path.join(...destination.split('/')); + await fs.mkdir(destination, { recursive: true }); const files = await fs.readdir(source, { withFileTypes: true }); diff --git a/packages/nango-yaml/lib/helpers.ts b/packages/nango-yaml/lib/helpers.ts index 6bf6f2a3e2f..ac019a9147e 100644 --- a/packages/nango-yaml/lib/helpers.ts +++ b/packages/nango-yaml/lib/helpers.ts @@ -178,8 +178,14 @@ export function shouldQuote(name: string) { return !regQuote.test(name); } +//. add to nodejs +// function split(filepath: string) { +// return filepath.split(path.sep); +// } + export function getProviderConfigurationFromPath({ filePath, parsed }: { filePath: string; parsed: NangoYamlParsed }): NangoYamlParsedIntegration | null { - const pathSegments = filePath.split('/'); + // const pathSegments = filePath.split('/'); + const pathSegments = filePath.split(path.sep); const scriptType = pathSegments.length > 1 ? pathSegments[pathSegments.length - 2] : null; const isNested = scriptType === 'syncs' || scriptType === 'actions' || scriptType === 'post-connection-scripts'; diff --git a/packages/nango-yaml/lib/load.ts b/packages/nango-yaml/lib/load.ts index db27157bb08..df62f16f9ac 100644 --- a/packages/nango-yaml/lib/load.ts +++ b/packages/nango-yaml/lib/load.ts @@ -14,7 +14,8 @@ import { nangoConfigFile } from './constant.js'; * Load nango.yaml */ export function loadNangoYaml({ fullPath }: { fullPath: string }): NangoYamlParser { - const location = path.resolve(`${fullPath}/${nangoConfigFile}`); + // const location = path.resolve(`${fullPath}/${nangoConfigFile}`); + const location = path.resolve(fullPath, nangoConfigFile); try { const content = fs.readFileSync(location, 'utf8'); const raw = yaml.load(content) as NangoYaml; diff --git a/packages/node-client/lib/utils.unit.test.ts b/packages/node-client/lib/utils.unit.test.ts index 41f614f5ddf..0499c22ffae 100644 --- a/packages/node-client/lib/utils.unit.test.ts +++ b/packages/node-client/lib/utils.unit.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { getUserAgent } from './utils.js'; -const regex = 'nango-node-client/[0-9.]+ .[a-z]+/[0-9a-z.-]+; node.js/[0-9.]+.'; +const regex = 'nango-node-client/[0-9.]+ .[a-z0-9]+/[0-9a-z.-]+; node.js/[0-9.]+.'; describe('getUserAgent', () => { it('should output default user agent', () => { expect(getUserAgent()).toMatch(new RegExp(regex)); From 0bdfe13f012fb75f137329b98978db2f4840b4ab Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Wed, 3 Jul 2024 15:49:30 -0500 Subject: [PATCH 05/10] wip path stuff --- package-lock.json | 13 +++++++++ packages/cli/lib/cli.ts | 26 ++++++++++------- packages/cli/lib/index.ts | 29 ++++++++++--------- packages/cli/lib/ourpath.ts | 10 +++++++ packages/cli/lib/services/compile.service.ts | 17 ++++++----- .../lib/services/compile.service.unit.test.ts | 20 +++++-------- packages/cli/lib/services/config.service.ts | 2 +- .../lib/services/config.service.unit.test.ts | 2 +- packages/cli/lib/services/deploy.service.ts | 2 +- packages/cli/lib/services/dryrun.service.ts | 5 ++-- .../cli/lib/services/migration.service.ts | 2 +- packages/cli/lib/services/model.service.ts | 3 +- .../lib/services/model.service.unit.test.ts | 5 ++-- .../cli/lib/services/verification.service.ts | 2 +- packages/cli/lib/sync.unit.cli-test.ts | 15 ++++++---- packages/cli/lib/tests/helpers.ts | 5 +--- packages/cli/lib/utils.ts | 12 +++++--- packages/cli/lib/utils/layoutMode.ts | 2 +- packages/cli/package.json | 1 + .../shared/lib/services/file/local.service.ts | 2 ++ 20 files changed, 105 insertions(+), 70 deletions(-) create mode 100644 packages/cli/lib/ourpath.ts diff --git a/package-lock.json b/package-lock.json index b9ec2f8f717..6cf5f4d47ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31100,6 +31100,7 @@ "npm-package-arg": "^10.1.0", "promptly": "^3.2.0", "semver": "^7.5.2", + "slash": "^5.1.0", "ts-json-schema-generator": "^2.3.0", "ts-node": "^10.9.1", "tsup": "^8.1.0", @@ -31228,6 +31229,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "packages/cli/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/cli/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index 159c200b960..c51b14be18b 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -1,5 +1,10 @@ import fs from 'node:fs'; -import path, { dirname } from 'node:path'; + +// import path from 'node:path'; +// import { join } from 'node:path/posix'; +// import path from 'node:path/posix'; +// import { resolve } from 'node:path'; +import path from './ourpath.js'; import { fileURLToPath } from 'node:url'; import chalk from 'chalk'; import chokidar from 'chokidar'; @@ -7,6 +12,7 @@ import ejs from 'ejs'; import * as dotenv from 'dotenv'; import { spawn } from 'child_process'; import type { ChildProcess } from 'node:child_process'; +import slash from 'slash'; import { NANGO_INTEGRATIONS_NAME, getNangoRootPath, getPkgVersion, printDebug } from './utils.js'; import { loadYamlAndGenerate } from './services/model.service.js'; @@ -16,7 +22,7 @@ import { getLayoutMode } from './utils/layoutMode.js'; import { getProviderConfigurationFromPath, nangoConfigFile } from '@nangohq/nango-yaml'; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); dotenv.config(); @@ -54,9 +60,7 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? }); const stripped = rendered.replace(/^\s+/, ''); - //.............. - // if (!fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`)) { - if (!fs.existsSync(path.join(fullPath, `{providerConfigKey}/${type}s/${name}.ts`))) { + if (!fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { fs.mkdirSync(path.join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); fs.writeFileSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); if (debug) { @@ -205,8 +209,7 @@ NANGO_DEPLOY_AUTO_CONFIRM=false # Default value` } export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - // const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); - const tsconfig = fs.readFileSync(path.join(getNangoRootPath()!, 'tsconfig.dev.json'), 'utf8'); + const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); const res = loadYamlAndGenerate({ fullPath, debug }); if (!res.success) { console.log(chalk.red(res.error?.message)); @@ -241,7 +244,8 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? } watcher.on('add', async (filePath: string) => { - filePath = filePath.replace(/\\/g, '/'); + // filePath = filePath.replace(/\\/g, '/'); + filePath = slash(filePath); if (filePath === nangoConfigFile) { return; } @@ -249,7 +253,8 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('unlink', (filePath: string) => { - filePath = filePath.replace(/\\/g, '/'); + // filePath = filePath.replace(/\\/g, '/'); + filePath = slash(filePath); if (filePath === nangoConfigFile) { return; } @@ -266,7 +271,8 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('change', async (filePath: string) => { - filePath = filePath.replace(/\\/g, '/'); + // filePath = filePath.replace(/\\/g, '/'); + filePath = slash(filePath); if (filePath === nangoConfigFile) { await compileAllFiles({ fullPath, debug }); return; diff --git a/packages/cli/lib/index.ts b/packages/cli/lib/index.ts index 074d6e7cfc8..d8b0575ba50 100644 --- a/packages/cli/lib/index.ts +++ b/packages/cli/lib/index.ts @@ -8,8 +8,9 @@ import { Command } from 'commander'; import fs from 'fs'; import chalk from 'chalk'; import figlet from 'figlet'; -import path from 'path'; +import path from 'path/posix'; import * as dotenv from 'dotenv'; +import slash from 'slash'; import { init, generate, tscWatch, configWatch, dockerRun, version } from './cli.js'; import deployService from './services/deploy.service.js'; @@ -88,7 +89,7 @@ program .description('Initialize a new Nango project') .action(function (this: Command) { const { debug } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); init({ absolutePath: fullPath, debug }); console.log(chalk.green(`Nango integrations initialized!`)); @@ -99,7 +100,7 @@ program .description('Generate a new Nango integration') .action(function (this: Command) { const { debug } = this.opts(); - generate({ fullPath: process.cwd(), debug }); + generate({ fullPath: slash(process.cwd()), debug }); }); program @@ -125,7 +126,7 @@ program ) .action(async function (this: Command, sync: string, connectionId: string) { const { autoConfirm, debug, e: environment, integrationId } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug }); const dryRun = new DryRunService({ fullPath }); await dryRun.run({ ...this.opts(), sync, connectionId, optionalEnvironment: environment, optionalProviderConfigKey: integrationId }, debug); @@ -137,7 +138,7 @@ program .option('--no-compile-interfaces', `Watch the ${nangoConfigFile} and recompile the interfaces on change`, true) .action(async function (this: Command) { const { compileInterfaces, autoConfirm, debug } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug, checkDist: false }); if (compileInterfaces) { @@ -158,7 +159,7 @@ program .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); const { debug } = options; - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await deployService.prep({ fullPath, options: { ...options, env: 'production' as ENV }, environment, debug }); }); @@ -166,7 +167,7 @@ program .command('migrate-config') .description('Migrate the nango.yaml from v1 (deprecated) to v2') .action(function (this: Command) { - v1toV2Migration(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION)); + v1toV2Migration(slash(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION))); }); program @@ -174,7 +175,7 @@ program .description('Migrate the script files from root level to structured directories.') .action(async function (this: Command) { const { debug } = this.opts(); - await directoryMigration(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION), debug); + await directoryMigration(slash(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION)), debug); }); // Hidden commands // @@ -188,7 +189,7 @@ program .option('--no-compile-interfaces', `Don't compile the ${nangoConfigFile}`, true) .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await deployService.prep({ fullPath, options: { ...options, env: 'local' }, environment, debug: options.debug }); }); @@ -208,7 +209,7 @@ program .option('--no-compile-interfaces', `Don't compile the ${nangoConfigFile}`, true) .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await deployService.prep({ fullPath, options: { ...options, env: 'staging' }, environment, debug: options.debug }); }); @@ -217,7 +218,7 @@ program .description('Compile the integration files to JavaScript') .action(async function (this: Command) { const { autoConfirm, debug } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug, checkDist: false }); const match = verificationService.filesMatchConfig({ fullPath }); @@ -238,7 +239,7 @@ program .option('--no-compile-interfaces', `Watch the ${nangoConfigFile} and recompile the interfaces on change`, true) .action(async function (this: Command) { const { compileInterfaces, autoConfirm, debug } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug }); if (compileInterfaces) { configWatch({ fullPath, debug }); @@ -262,7 +263,7 @@ program .description('Verify the parsed sync config and output the object for verification') .action(async function (this: Command) { const { autoConfirm } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await verificationService.necessaryFilesExist({ fullPath, autoConfirm }); const { success, error, response } = parse(path.resolve(fullPath, NANGO_INTEGRATIONS_LOCATION)); @@ -282,7 +283,7 @@ program .arguments('environmentName') .action(async function (this: Command, environmentName: string) { const { debug } = this.opts(); - const fullPath = process.cwd(); + const fullPath = slash(process.cwd()); await deployService.admin({ fullPath, environmentName, debug }); }); diff --git a/packages/cli/lib/ourpath.ts b/packages/cli/lib/ourpath.ts new file mode 100644 index 00000000000..84e3fd1302e --- /dev/null +++ b/packages/cli/lib/ourpath.ts @@ -0,0 +1,10 @@ +import platform from 'node:path'; +// import pathPosix from 'node:path/posix'; +import slash from 'slash'; + +export default { + ...platform, + // join: pathPosix.join, + join: (...paths: string[]) => slash(platform.join(...paths)) + // resolve: (...paths: string[]) => slash(pathPosix.resolve(...paths)) +}; diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index 2c749dd9811..810c880c791 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -2,8 +2,9 @@ import fs from 'fs'; import { glob } from 'glob'; import * as tsNode from 'ts-node'; import chalk from 'chalk'; -import path from 'path'; +import path from 'path/posix'; import { build } from 'tsup'; +// import slash from 'slash'; import { getNangoRootPath, printDebug } from '../utils.js'; import { loadYamlAndGenerate } from './model.service.js'; @@ -264,7 +265,6 @@ export function getFileToCompile({ fullPath, filePath }: { fullPath: string; fil const baseName = path.basename(filePath, '.ts'); return { inputPath: filePath, - // outputPath: path.join(fullPath, 'dist', `${baseName}.js`), outputPath: path.join(fullPath, `dist/${baseName}.js`), baseName }; @@ -355,12 +355,13 @@ export function listFilesToCompile({ // eg getMatchingFiles('foo', 'ts') -> glob.sync('foo/*.ts') function getMatchingFiles(...args: string[]): string[] { args.splice(-1, 1, `*.${args.slice(-1)[0]}`); - console.log('args', args); - // const pattern = args.join('/'); + // console.log('args', args); + const pattern = args.join('/'); + // console.log('pattern', pattern); + return glob.sync(pattern, { posix: true }); + + // const pattern = path.join(...args); // console.log('pattern', pattern); - // return glob.sync(pattern, { posix: true }); - const pattern = path.join(...args); - console.log('pattern', pattern); // windowsPathsNoEscape // Use \\ as a path separator only, and never as an escape @@ -386,5 +387,5 @@ function getMatchingFiles(...args: string[]): string[] { // will be their full resolved UNC forms, eg instead of // 'C:\\foo\\bar', it would return '//?/C:/foo/bar' - return glob.sync(pattern, { windowsPathsNoEscape: true, absolute: false, posix: true }); + // return glob.sync(pattern, { windowsPathsNoEscape: true, absolute: false, posix: true }); } diff --git a/packages/cli/lib/services/compile.service.unit.test.ts b/packages/cli/lib/services/compile.service.unit.test.ts index 038aa9164e2..0178d30d03b 100644 --- a/packages/cli/lib/services/compile.service.unit.test.ts +++ b/packages/cli/lib/services/compile.service.unit.test.ts @@ -1,29 +1,23 @@ -import path from 'node:path'; +import path from 'node:path/posix'; import { describe, expect, it } from 'vitest'; import { getFileToCompile, listFilesToCompile } from './compile.service'; import { fileURLToPath } from 'node:url'; import type { NangoYamlParsed } from '@nangohq/types'; +import slash from 'slash'; // eg "C:\Users\bburns\Workspace\test\various\src" -const thisFolder = path.dirname(fileURLToPath(import.meta.url)); - -// function join(...args) { -// args = args.map(arg => ) -// return path.join(...args) -// } +// const thisFolder = path.dirname(fileURLToPath(import.meta.url)); +const thisFolder = path.dirname(slash(fileURLToPath(import.meta.url))); describe('listFiles', () => { it('should list files with glob', () => { const files = listFilesToCompile({ fullPath: thisFolder, parsed: { integrations: [], models: new Map(), yamlVersion: 'v2' } }); expect(files.length).toBeGreaterThan(1); + //. why should this be the first entry? expect(files[0]).toStrictEqual({ baseName: 'verification.service', - // inputPath: `${thisFolder}/verification.service.ts`, - // outputPath: `${thisFolder}/dist/verification.service.js` - // inputPath: path.join(thisFolder, 'verification.service.ts'), - // outputPath: path.join(thisFolder, 'dist', 'verification.service.js') - inputPath: path.join(thisFolder, 'verification.service.ts'), - outputPath: path.join(thisFolder, 'dist/verification.service.js') + inputPath: `${thisFolder}/verification.service.ts`, + outputPath: `${thisFolder}/dist/verification.service.js` }); }); diff --git a/packages/cli/lib/services/config.service.ts b/packages/cli/lib/services/config.service.ts index 53978f2f95e..df32033e282 100644 --- a/packages/cli/lib/services/config.service.ts +++ b/packages/cli/lib/services/config.service.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import path from 'path'; +import path from 'path/posix'; import Ajv from 'ajv'; import addErrors from 'ajv-errors'; import chalk from 'chalk'; diff --git a/packages/cli/lib/services/config.service.unit.test.ts b/packages/cli/lib/services/config.service.unit.test.ts index a10d05f5959..cea404abb2e 100644 --- a/packages/cli/lib/services/config.service.unit.test.ts +++ b/packages/cli/lib/services/config.service.unit.test.ts @@ -1,4 +1,4 @@ -import path from 'node:path'; +import path from 'node:path/posix'; import yaml from 'js-yaml'; import stripAnsi from 'strip-ansi'; import { afterEach, describe, expect, it, vi } from 'vitest'; diff --git a/packages/cli/lib/services/deploy.service.ts b/packages/cli/lib/services/deploy.service.ts index 0f7f0552b27..b5376f87bb7 100644 --- a/packages/cli/lib/services/deploy.service.ts +++ b/packages/cli/lib/services/deploy.service.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import path from 'node:path'; +import path from 'node:path/posix'; import chalk from 'chalk'; import promptly from 'promptly'; import type { AxiosResponse } from 'axios'; diff --git a/packages/cli/lib/services/dryrun.service.ts b/packages/cli/lib/services/dryrun.service.ts index 6ce844b1a07..bf8703015f6 100644 --- a/packages/cli/lib/services/dryrun.service.ts +++ b/packages/cli/lib/services/dryrun.service.ts @@ -1,5 +1,6 @@ import promptly from 'promptly'; import chalk from 'chalk'; +import slash from 'slash'; import type { NangoConnection } from '@nangohq/shared'; import type { Metadata, ScriptFileType } from '@nangohq/types'; @@ -74,7 +75,7 @@ export class DryRunService { return; } - const { success, error, response } = parse(process.cwd(), debug); + const { success, error, response } = parse(slash(process.cwd()), debug); if (!success || !response?.parsed) { console.log(chalk.red(error?.message)); return; @@ -175,7 +176,7 @@ export class DryRunService { type = 'post-connection-scripts'; } - const result = await compileAllFiles({ fullPath: process.cwd(), debug, scriptName: syncName, providerConfigKey, type }); + const result = await compileAllFiles({ fullPath: slash(process.cwd()), debug, scriptName: syncName, providerConfigKey, type }); if (!result) { console.log(chalk.red('The sync/action did not compile successfully. Exiting')); diff --git a/packages/cli/lib/services/migration.service.ts b/packages/cli/lib/services/migration.service.ts index d28dc22a620..e07f597c16c 100644 --- a/packages/cli/lib/services/migration.service.ts +++ b/packages/cli/lib/services/migration.service.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import path from 'path'; +import path from 'path/posix'; import chalk from 'chalk'; import { exec } from 'child_process'; diff --git a/packages/cli/lib/services/model.service.ts b/packages/cli/lib/services/model.service.ts index 1207d9beda9..b3a5b36d421 100644 --- a/packages/cli/lib/services/model.service.ts +++ b/packages/cli/lib/services/model.service.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; -import path from 'node:path'; +// import path from 'node:path/posix'; +import path from '../ourpath.js'; import { resolve } from 'import-meta-resolve'; import chalk from 'chalk'; import type { JSONSchema7 } from 'json-schema'; diff --git a/packages/cli/lib/services/model.service.unit.test.ts b/packages/cli/lib/services/model.service.unit.test.ts index 7eeab48ab04..017263cc427 100644 --- a/packages/cli/lib/services/model.service.unit.test.ts +++ b/packages/cli/lib/services/model.service.unit.test.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; -import path from 'node:path'; +import path from 'node:path/posix'; +import { resolve } from 'node:path'; import { describe, expect, it } from 'vitest'; import { buildModelsTS, fieldToTypescript, fieldsToTypescript, getExportToJSON } from './model.service.js'; import type { NangoModel } from '@nangohq/types'; @@ -68,7 +69,7 @@ describe('buildModelTs', () => { }); it('should support all advanced syntax', () => { - const { response } = parse(path.resolve(__dirname, `../../fixtures/nango-yaml/v2/advanced-syntax`)); + const { response } = parse(resolve(__dirname, `../../fixtures/nango-yaml/v2/advanced-syntax`)); const res = buildModelsTS({ parsed: response!.parsed! }); const acc = []; for (const line of res.split('\n')) { diff --git a/packages/cli/lib/services/verification.service.ts b/packages/cli/lib/services/verification.service.ts index db0636e098f..14059ff0b32 100644 --- a/packages/cli/lib/services/verification.service.ts +++ b/packages/cli/lib/services/verification.service.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import chalk from 'chalk'; import promptly from 'promptly'; -import path from 'path'; +import path from 'path/posix'; import { nangoConfigFile } from '@nangohq/nango-yaml'; import { parse } from './config.service.js'; diff --git a/packages/cli/lib/sync.unit.cli-test.ts b/packages/cli/lib/sync.unit.cli-test.ts index 962ee341a95..63d3bbd12bb 100644 --- a/packages/cli/lib/sync.unit.cli-test.ts +++ b/packages/cli/lib/sync.unit.cli-test.ts @@ -1,5 +1,6 @@ import { expect, describe, it, afterEach, vi } from 'vitest'; -import path from 'node:path'; +import path from 'node:path/posix'; +import { resolve } from 'node:path'; import os from 'node:os'; import fs from 'fs'; import yaml from 'js-yaml'; @@ -11,9 +12,11 @@ import { getNangoRootPath } from './utils.js'; import parserService from './services/parser.service.js'; import { copyDirectoryAndContents, removeVersion } from './tests/helpers.js'; import { parse } from './services/config.service.js'; +import slash from 'slash'; +//. on windows, want this to give a fwdslash path function getTestDirectory(name: string) { - const tmpdir = os.tmpdir(); + const tmpdir = slash(os.tmpdir()); const dir = path.join(tmpdir, name, 'nango-integrations'); fs.mkdirSync(dir, { recursive: true }); fs.rmSync(dir, { recursive: true, force: true }); @@ -31,7 +34,7 @@ describe('generate function tests', () => { it('should init the expected files in the nango-integrations directory', () => { const dir = getTestDirectory('init'); - init({ absolutePath: path.resolve(dir, '..'), debug: false }); + init({ absolutePath: resolve(dir, '..'), debug: false }); expect(fs.existsSync(`${dir}/demo-github-integration/syncs/${exampleSyncName}.ts`)).toBe(true); expect(fs.existsSync(`${dir}/.env`)).toBe(true); expect(fs.existsSync(`${dir}/nango.yaml`)).toBe(true); @@ -503,7 +506,7 @@ describe('generate function tests', () => { await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`); const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); - const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); expect(response?.parsed).not.toBeNull(); const result = await compileSingleFile({ @@ -525,7 +528,7 @@ describe('generate function tests', () => { await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`); const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); - const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); expect(response).not.toBeNull(); const result = await compileSingleFile({ @@ -548,7 +551,7 @@ describe('generate function tests', () => { await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, `${dir}/welcomer.ts`); const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); - const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); expect(response).not.toBeNull(); const result = await compileSingleFile({ diff --git a/packages/cli/lib/tests/helpers.ts b/packages/cli/lib/tests/helpers.ts index a712d8d61a3..9c14a7ca58f 100644 --- a/packages/cli/lib/tests/helpers.ts +++ b/packages/cli/lib/tests/helpers.ts @@ -1,10 +1,7 @@ -import path from 'path'; +import path from 'path/posix'; import fs from 'fs/promises'; export const copyDirectoryAndContents = async (source: string, destination: string) => { - // source = path.join(...source.split('/')); - // destination = path.join(...destination.split('/')); - await fs.mkdir(destination, { recursive: true }); const files = await fs.readdir(source, { withFileTypes: true }); diff --git a/packages/cli/lib/utils.ts b/packages/cli/lib/utils.ts index e54e8f52889..99f7dcb2fdc 100644 --- a/packages/cli/lib/utils.ts +++ b/packages/cli/lib/utils.ts @@ -3,7 +3,8 @@ import fs from 'fs'; import os from 'os'; import npa from 'npm-package-arg'; import Module from 'node:module'; -import path, { dirname } from 'path'; +// import path, { dirname } from 'path/posix'; +import path from './ourpath.js'; import { fileURLToPath } from 'url'; import semver from 'semver'; import util from 'util'; @@ -14,9 +15,10 @@ import { cloudHost, stagingHost, NANGO_VERSION } from '@nangohq/shared'; import * as dotenv from 'dotenv'; import { state } from './state.js'; import https from 'node:https'; +// import slash from 'slash'; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const require = Module.createRequire(import.meta.url); @@ -280,11 +282,13 @@ export function getNangoRootPath(debug = false) { return null; } + const rootPath = path.resolve(packagePath, '..'); + if (debug) { - printDebug(`Found the nango cli root path at ${path.resolve(packagePath, '..')}`); + printDebug(`Found the nango cli root path at ${rootPath}`); } - return path.resolve(packagePath, '..'); + return rootPath; } function getPackagePath(debug = false) { diff --git a/packages/cli/lib/utils/layoutMode.ts b/packages/cli/lib/utils/layoutMode.ts index c599b5c7490..a7a00fab192 100644 --- a/packages/cli/lib/utils/layoutMode.ts +++ b/packages/cli/lib/utils/layoutMode.ts @@ -1,6 +1,6 @@ import type { LayoutMode } from '@nangohq/types'; import fs from 'node:fs'; -import path from 'node:path'; +import path from 'node:path/posix'; /* * Get Layout Mode diff --git a/packages/cli/package.json b/packages/cli/package.json index 61e7c813d68..cdfba718fa8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -46,6 +46,7 @@ "npm-package-arg": "^10.1.0", "promptly": "^3.2.0", "semver": "^7.5.2", + "slash": "^5.1.0", "ts-json-schema-generator": "^2.3.0", "ts-node": "^10.9.1", "tsup": "^8.1.0", diff --git a/packages/shared/lib/services/file/local.service.ts b/packages/shared/lib/services/file/local.service.ts index 217460b3beb..25c472e6745 100644 --- a/packages/shared/lib/services/file/local.service.ts +++ b/packages/shared/lib/services/file/local.service.ts @@ -8,8 +8,10 @@ import { NangoError } from '../../utils/error.js'; import { LogActionEnum } from '../../models/Telemetry.js'; import type { LayoutMode } from '../../models/NangoConfig.js'; import { nangoConfigFile, SYNC_FILE_EXTENSION } from '../nango-config.service.js'; +// import slash from 'slash'; const __filename = fileURLToPath(import.meta.url); +// const __filename = slash(fileURLToPath(import.meta.url)); const __dirname = dirname(__filename); class LocalFileService { From e4101ecb0fde1bde2244f245f6990b6f5cbad96e Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Wed, 3 Jul 2024 17:32:22 -0500 Subject: [PATCH 06/10] wip --- packages/cli/lib/cli.ts | 8 +- packages/cli/lib/ourpath.ts | 12 +-- packages/cli/lib/sync.unit.cli-test.ts | 127 ++++++++++++------------- packages/cli/lib/utils.ts | 10 +- 4 files changed, 80 insertions(+), 77 deletions(-) diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index c51b14be18b..905c63cb32c 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -36,10 +36,10 @@ export const version = (debug: boolean) => { }; export function generate({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - const syncTemplateContents = fs.readFileSync(path.resolve(__dirname, './templates/sync.ejs'), 'utf8'); - const actionTemplateContents = fs.readFileSync(path.resolve(__dirname, './templates/action.ejs'), 'utf8'); - const githubExampleTemplateContents = fs.readFileSync(path.resolve(__dirname, './templates/github.sync.ejs'), 'utf8'); - const postConnectionTemplateContents = fs.readFileSync(path.resolve(__dirname, './templates/post-connection.ejs'), 'utf8'); + const syncTemplateContents = fs.readFileSync(path.join(__dirname, './templates/sync.ejs'), 'utf8'); + const actionTemplateContents = fs.readFileSync(path.join(__dirname, './templates/action.ejs'), 'utf8'); + const githubExampleTemplateContents = fs.readFileSync(path.join(__dirname, './templates/github.sync.ejs'), 'utf8'); + const postConnectionTemplateContents = fs.readFileSync(path.join(__dirname, './templates/post-connection.ejs'), 'utf8'); const res = loadYamlAndGenerate({ fullPath, debug }); if (!res.success) { diff --git a/packages/cli/lib/ourpath.ts b/packages/cli/lib/ourpath.ts index 84e3fd1302e..9f0d3033270 100644 --- a/packages/cli/lib/ourpath.ts +++ b/packages/cli/lib/ourpath.ts @@ -1,10 +1,10 @@ import platform from 'node:path'; -// import pathPosix from 'node:path/posix'; -import slash from 'slash'; +// import posix from 'node:path/posix'; +// import slash from 'slash'; export default { - ...platform, - // join: pathPosix.join, - join: (...paths: string[]) => slash(platform.join(...paths)) - // resolve: (...paths: string[]) => slash(pathPosix.resolve(...paths)) + ...platform + // join: posix.join, + // join: (...paths: string[]) => slash(platform.join(...paths)) + // resolve: (...paths: string[]) => slash(posix.resolve(...paths)) }; diff --git a/packages/cli/lib/sync.unit.cli-test.ts b/packages/cli/lib/sync.unit.cli-test.ts index 63d3bbd12bb..63728706861 100644 --- a/packages/cli/lib/sync.unit.cli-test.ts +++ b/packages/cli/lib/sync.unit.cli-test.ts @@ -1,6 +1,7 @@ import { expect, describe, it, afterEach, vi } from 'vitest'; -import path from 'node:path/posix'; -import { resolve } from 'node:path'; +// import path from 'node:path/posix'; +// import path, { join } from './ourpath.js'; +import path, { join } from 'node:path'; import os from 'node:os'; import fs from 'fs'; import yaml from 'js-yaml'; @@ -12,12 +13,13 @@ import { getNangoRootPath } from './utils.js'; import parserService from './services/parser.service.js'; import { copyDirectoryAndContents, removeVersion } from './tests/helpers.js'; import { parse } from './services/config.service.js'; -import slash from 'slash'; +// import slash from 'slash'; -//. on windows, want this to give a fwdslash path -function getTestDirectory(name: string) { - const tmpdir = slash(os.tmpdir()); - const dir = path.join(tmpdir, name, 'nango-integrations'); +//. this returns a platpath - ie windows or posix +// eg 'C:\\Users\\bburns\\AppData\\Local\\Temp\\foo\\nango-integrations' +function getTestDirectory(name: string): string { + const tmpdir = os.tmpdir(); // eg 'c:\\users\\...' + const dir = join(tmpdir, name, 'nango-integrations'); // eg 'c:/users/...' fs.mkdirSync(dir, { recursive: true }); fs.rmSync(dir, { recursive: true, force: true }); return dir; @@ -34,22 +36,22 @@ describe('generate function tests', () => { it('should init the expected files in the nango-integrations directory', () => { const dir = getTestDirectory('init'); - init({ absolutePath: resolve(dir, '..'), debug: false }); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/${exampleSyncName}.ts`)).toBe(true); - expect(fs.existsSync(`${dir}/.env`)).toBe(true); - expect(fs.existsSync(`${dir}/nango.yaml`)).toBe(true); - expect(fs.existsSync(`${dir}/models.ts`)).toBe(true); - expect(removeVersion(fs.readFileSync(`${dir}/.nango/schema.ts`).toString())).toMatchSnapshot(); - expect(removeVersion(fs.readFileSync(`${dir}/.nango/schema.json`).toString())).toMatchSnapshot(); + init({ absolutePath: path.resolve(dir, '..'), debug: false }); + expect(fs.existsSync(join(dir, `demo-github-integration/syncs/${exampleSyncName}.ts`))).toBe(true); + expect(fs.existsSync(join(dir, '.env'))).toBe(true); + expect(fs.existsSync(join(dir, 'nango.yaml'))).toBe(true); + expect(fs.existsSync(join(dir, 'models.ts'))).toBe(true); + expect(removeVersion(fs.readFileSync(join(dir, '.nango/schema.ts')).toString())).toMatchSnapshot(); + expect(removeVersion(fs.readFileSync(join(dir, '.nango/schema.json')).toString())).toMatchSnapshot(); }); it('should not overwrite existing integration files', async () => { const dir = getTestDirectory('overwrite'); init({ absolutePath: dir, debug: false }); - await fs.promises.writeFile(`${dir}/${exampleSyncName}.ts`, 'dummy fake content', 'utf8'); + await fs.promises.writeFile(join(dir, '${exampleSyncName}.ts'), 'dummy fake content', 'utf8'); const dummyContent = 'This is dummy content. Do not overwrite!'; - const exampleFilePath = path.join(dir, `${exampleSyncName}.ts`); + const exampleFilePath = join(dir, `${exampleSyncName}.ts`); await fs.promises.writeFile(exampleFilePath, dummyContent, 'utf8'); init({ absolutePath: dir }); @@ -89,9 +91,9 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: true, fullPath: dir }); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/some-other-sync.ts`)).toBe(true); + expect(fs.existsSync(join(dir, 'demo-github-integration/syncs/some-other-sync.ts'))).toBe(true); }); it('should support a single model return in v1 format', async () => { @@ -124,9 +126,9 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(true); + expect(fs.existsSync(join(dir, 'demo-github-integration/syncs/single-model-return.ts'))).toBe(true); }); it('should support a single model return in v2 format', async () => { @@ -161,9 +163,9 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(true); + expect(fs.existsSync(join(dir, 'demo-github-integration/syncs/single-model-return.ts'))).toBe(true); }); it('should not create a file if endpoint is missing from a v2 config', async () => { @@ -198,8 +200,8 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-return.ts`)).toBe(false); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); + expect(fs.existsSync(join(dir, 'demo-github-integration/syncs/single-model-return.ts'))).toBe(false); }); it('should generate missing from a v2 config', async () => { @@ -234,9 +236,9 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); - expect(fs.existsSync(`${dir}/demo-github-integration/syncs/single-model-issue-output.ts`)).toBe(true); + expect(fs.existsSync(join(dir, 'demo-github-integration/syncs/single-model-issue-output.ts'))).toBe(true); }); it('should throw an error if a model is missing an id that is actively used', async () => { @@ -268,7 +270,7 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); const acc: string[] = []; consoleMock.mockImplementation((m) => acc.push(stripAnsi(m))); @@ -312,9 +314,9 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); - const modelsFile = await fs.promises.readFile(`${dir}/models.ts`, 'utf8'); + const modelsFile = await fs.promises.readFile(join(dir, 'models.ts'), 'utf8'); expect(modelsFile).toContain('export interface GithubIssues'); }); @@ -346,7 +348,7 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); }); @@ -368,7 +370,7 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); generate({ debug: false, fullPath: dir }); }); @@ -390,7 +392,7 @@ describe('generate function tests', () => { } }; const yamlData = yaml.dump(data); - await fs.promises.writeFile(`${dir}/nango.yaml`, yamlData, 'utf8'); + await fs.promises.writeFile(join(dir, 'nango.yaml'), yamlData, 'utf8'); expect(generate({ debug: false, fullPath: dir })).toBeUndefined(); }); @@ -448,20 +450,17 @@ describe('generate function tests', () => { const dir = getTestDirectory('nested'); init({ absolutePath: dir }); - // await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, `${dir}/hubspot`); - await copyDirectoryAndContents(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/hubspot'), path.join(dir, 'hubspot')); - // await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, `${dir}/github`); - await copyDirectoryAndContents(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/github'), path.join(dir, 'github')); - // await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, `${dir}/nango.yaml`); - await fs.promises.copyFile(path.join(fixturesPath, 'nango-yaml/v2/nested-integrations/nango.yaml'), path.join(dir, 'nango.yaml')); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, join(dir, 'hubspot')); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, join(dir, 'github')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, join(dir, 'nango.yaml')); const success = await compileAllFiles({ fullPath: dir, debug: true }); //. these should report any failed paths somehow, not just true!=false - expect(fs.existsSync(path.join(dir, 'models.ts'))).toBe(true); - expect(fs.existsSync(path.join(dir, 'hubspot/syncs/contacts.ts'))).toBe(true); - expect(fs.existsSync(path.join(dir, 'dist/contacts-hubspot.js'))).toBe(true); - expect(fs.existsSync(path.join(dir, 'dist/issues-github.js'))).toBe(true); + expect(fs.existsSync(join(dir, 'models.ts'))).toBe(true); + expect(fs.existsSync(join(dir, 'hubspot/syncs/contacts.ts'))).toBe(true); + expect(fs.existsSync(join(dir, 'dist/contacts-hubspot.js'))).toBe(true); + expect(fs.existsSync(join(dir, 'dist/issues-github.js'))).toBe(true); expect(success).toBe(true); }); @@ -474,9 +473,9 @@ describe('generate function tests', () => { const success = await compileAllFiles({ fullPath: dir, debug: false }); - expect(fs.existsSync(path.join(dir, 'models.ts'))).toBe(true); - expect(fs.existsSync(path.join(dir, 'contacts.ts'))).toBe(true); - expect(fs.existsSync(path.join(dir, 'dist/contacts-hubspot.js'))).toBe(true); + expect(fs.existsSync(join(dir, 'models.ts'))).toBe(true); + expect(fs.existsSync(join(dir, 'contacts.ts'))).toBe(true); + expect(fs.existsSync(join(dir, 'dist/contacts-hubspot.js'))).toBe(true); expect(success).toBe(true); }); @@ -484,12 +483,12 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`, `${dir}/github`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`, `${dir}/nango.yaml`); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`, join(dir, 'github')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`, join(dir, 'nango.yaml')); const success = await compileAllFiles({ fullPath: dir, debug: false }); - const module = await import(`${dir}/dist/issues-github.js`); + const module = await import(join(dir, 'dist/issues-github.js')); const result = module.default.default(); expect(result).toBe('Hello, world!'); @@ -502,16 +501,16 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-error'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`); - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); + const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(fixturesPath, `nango-yaml/v2/${name}`)); expect(response?.parsed).not.toBeNull(); const result = await compileSingleFile({ fullPath: dir, - file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }), + file: getFileToCompile({ fullPath: dir, filePath: join(dir, './github/actions/gh-issues.ts') }), tsconfig, parsed: response!.parsed!, debug: false @@ -524,16 +523,16 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-nango-misuse'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`); - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); + const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); expect(response).not.toBeNull(); const result = await compileSingleFile({ fullPath: dir, - file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }), + file: getFileToCompile({ fullPath: dir, filePath: join(dir, './github/actions/gh-issues.ts') }), tsconfig, parsed: response!.parsed!, debug: false @@ -546,17 +545,17 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-higher-import'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, `${dir}/github`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, `${dir}/nango.yaml`); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, `${dir}/welcomer.ts`); - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); + await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, join(dir, 'welcomer.ts')); + const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); expect(response).not.toBeNull(); const result = await compileSingleFile({ fullPath: dir, - file: getFileToCompile({ fullPath: dir, filePath: path.join(dir, './github/actions/gh-issues.ts') }), + file: getFileToCompile({ fullPath: dir, filePath: join(dir, './github/actions/gh-issues.ts') }), tsconfig, parsed: response!.parsed!, debug: false diff --git a/packages/cli/lib/utils.ts b/packages/cli/lib/utils.ts index 99f7dcb2fdc..a30a8c0ce1a 100644 --- a/packages/cli/lib/utils.ts +++ b/packages/cli/lib/utils.ts @@ -273,13 +273,16 @@ export function getUserAgent(): string { return `nango-cli/${clientVersion} (${osName}/${osVersion}; node.js/${nodeVersion})`; } -export function getNangoRootPath(debug = false) { +//. returns a platpath - so use with path.join - wrap in slash() if needed +export function getNangoRootPath(debug = false): string { const packagePath = getPackagePath(debug); if (!packagePath) { if (debug) { printDebug('Could not find nango cli root path locally'); } - return null; + // return null; + //. or throw error? + return ''; } const rootPath = path.resolve(packagePath, '..'); @@ -291,7 +294,8 @@ export function getNangoRootPath(debug = false) { return rootPath; } -function getPackagePath(debug = false) { +//. returns a platpath +function getPackagePath(debug = false): string { if (process.env['CI'] || process.env['VITEST']) { return path.join(__dirname); } From 5aa0c485d3236f644d2aaae82be3667f74add879 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Thu, 4 Jul 2024 05:04:55 -0500 Subject: [PATCH 07/10] test cli passes --- packages/cli/lib/cli.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index 905c63cb32c..c51b7cd56d1 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -296,7 +296,8 @@ export function configWatch({ fullPath, debug = false }: { fullPath: string; deb let child: ChildProcess | undefined; process.on('SIGINT', () => { if (child) { - const dockerDown = spawn('docker', ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'down'], { + // const dockerDown = spawn('docker', ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'down'], { + const dockerDown = spawn('docker', ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'down'], { stdio: 'inherit' }); dockerDown.on('exit', () => { @@ -315,7 +316,8 @@ process.on('SIGINT', () => { export const dockerRun = async (debug = false) => { const cwd = process.cwd(); - const args = ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'up', '--build']; + // const args = ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'up', '--build']; + const args = ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'up', '--build']; if (debug) { printDebug(`Running docker with args: ${args.join(' ')}`); From a843c0d5e48a613ecdf788449b94731cdfc1a963 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Fri, 5 Jul 2024 02:55:36 -0500 Subject: [PATCH 08/10] win passing --- packages/cli/lib/cli.ts | 45 ++++++------ packages/cli/lib/index.ts | 30 ++++---- packages/cli/lib/ourpath.ts | 10 --- packages/cli/lib/services/compile.service.ts | 42 ++++++------ .../lib/services/compile.service.unit.test.ts | 20 +++--- packages/cli/lib/services/config.service.ts | 5 +- .../lib/services/config.service.unit.test.ts | 3 +- packages/cli/lib/services/deploy.service.ts | 2 +- .../cli/lib/services/migration.service.ts | 5 +- packages/cli/lib/services/model.service.ts | 3 +- .../lib/services/model.service.unit.test.ts | 12 ++-- .../cli/lib/services/verification.service.ts | 2 +- packages/cli/lib/sync.unit.cli-test.ts | 68 ++++++++++--------- packages/cli/lib/tests/helpers.ts | 2 +- packages/cli/lib/utils.ts | 7 +- packages/cli/lib/utils/layoutMode.ts | 2 +- 16 files changed, 121 insertions(+), 137 deletions(-) delete mode 100644 packages/cli/lib/ourpath.ts diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index c51b7cd56d1..e570888d790 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -1,10 +1,5 @@ import fs from 'node:fs'; - -// import path from 'node:path'; -// import { join } from 'node:path/posix'; -// import path from 'node:path/posix'; -// import { resolve } from 'node:path'; -import path from './ourpath.js'; +import path, { join } from 'node:path'; import { fileURLToPath } from 'node:url'; import chalk from 'chalk'; import chokidar from 'chokidar'; @@ -36,10 +31,10 @@ export const version = (debug: boolean) => { }; export function generate({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - const syncTemplateContents = fs.readFileSync(path.join(__dirname, './templates/sync.ejs'), 'utf8'); - const actionTemplateContents = fs.readFileSync(path.join(__dirname, './templates/action.ejs'), 'utf8'); - const githubExampleTemplateContents = fs.readFileSync(path.join(__dirname, './templates/github.sync.ejs'), 'utf8'); - const postConnectionTemplateContents = fs.readFileSync(path.join(__dirname, './templates/post-connection.ejs'), 'utf8'); + const syncTemplateContents = fs.readFileSync(join(__dirname, './templates/sync.ejs'), 'utf8'); + const actionTemplateContents = fs.readFileSync(join(__dirname, './templates/action.ejs'), 'utf8'); + const githubExampleTemplateContents = fs.readFileSync(join(__dirname, './templates/github.sync.ejs'), 'utf8'); + const postConnectionTemplateContents = fs.readFileSync(join(__dirname, './templates/post-connection.ejs'), 'utf8'); const res = loadYamlAndGenerate({ fullPath, debug }); if (!res.success) { @@ -60,9 +55,9 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? }); const stripped = rendered.replace(/^\s+/, ''); - if (!fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { - fs.mkdirSync(path.join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); - fs.writeFileSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); + if (!fs.existsSync(join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { + fs.mkdirSync(join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); + fs.writeFileSync(join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); if (debug) { printDebug(`Created ${name}.ts file`); } @@ -87,7 +82,7 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? process.exit(1); } - if (fs.existsSync(path.join(fullPath, `${name}.ts`)) || fs.existsSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { + if (fs.existsSync(join(fullPath, `${name}.ts`)) || fs.existsSync(join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`))) { if (debug) { printDebug(`${name}.ts file already exists, so will not overwrite it.`); } @@ -125,10 +120,10 @@ export function generate({ fullPath, debug = false }: { fullPath: string; debug? const stripped = rendered.replace(/^\s+/, ''); if (layoutMode === 'root') { - fs.writeFileSync(path.join(fullPath, `${name}.ts`), stripped); + fs.writeFileSync(join(fullPath, `${name}.ts`), stripped); } else { - fs.mkdirSync(path.join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); - fs.writeFileSync(path.join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); + fs.mkdirSync(join(fullPath, `${providerConfigKey}/${type}s`), { recursive: true }); + fs.writeFileSync(join(fullPath, `${providerConfigKey}/${type}s/${name}.ts`), stripped); } if (debug) { console.log(chalk.green(`Created ${name}.ts file`)); @@ -209,7 +204,7 @@ NANGO_DEPLOY_AUTO_CONFIRM=false # Default value` } export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); + const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); const res = loadYamlAndGenerate({ fullPath, debug }); if (!res.success) { console.log(chalk.red(res.error?.message)); @@ -234,7 +229,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? } }); - const distDir = path.join(fullPath, 'dist'); + const distDir = join(fullPath, 'dist'); if (!fs.existsSync(distDir)) { if (debug) { @@ -254,7 +249,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? watcher.on('unlink', (filePath: string) => { // filePath = filePath.replace(/\\/g, '/'); - filePath = slash(filePath); + // filePath = slash(filePath); if (filePath === nangoConfigFile) { return; } @@ -272,7 +267,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? watcher.on('change', async (filePath: string) => { // filePath = filePath.replace(/\\/g, '/'); - filePath = slash(filePath); + // filePath = slash(filePath); if (filePath === nangoConfigFile) { await compileAllFiles({ fullPath, debug }); return; @@ -282,7 +277,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? } export function configWatch({ fullPath, debug = false }: { fullPath: string; debug?: boolean }) { - const watchPath = path.join(fullPath, nangoConfigFile); + const watchPath = join(fullPath, nangoConfigFile); if (debug) { printDebug(`Watching ${watchPath}`); } @@ -296,8 +291,7 @@ export function configWatch({ fullPath, debug = false }: { fullPath: string; deb let child: ChildProcess | undefined; process.on('SIGINT', () => { if (child) { - // const dockerDown = spawn('docker', ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'down'], { - const dockerDown = spawn('docker', ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'down'], { + const dockerDown = spawn('docker', ['compose', '-f', join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'down'], { stdio: 'inherit' }); dockerDown.on('exit', () => { @@ -316,8 +310,7 @@ process.on('SIGINT', () => { export const dockerRun = async (debug = false) => { const cwd = process.cwd(); - // const args = ['compose', '-f', `${getNangoRootPath()}/docker/docker-compose.yaml`, '--project-directory', '.', 'up', '--build']; - const args = ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'up', '--build']; + const args = ['compose', '-f', join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'up', '--build']; if (debug) { printDebug(`Running docker with args: ${args.join(' ')}`); diff --git a/packages/cli/lib/index.ts b/packages/cli/lib/index.ts index d8b0575ba50..beefa190f4b 100644 --- a/packages/cli/lib/index.ts +++ b/packages/cli/lib/index.ts @@ -8,9 +8,9 @@ import { Command } from 'commander'; import fs from 'fs'; import chalk from 'chalk'; import figlet from 'figlet'; -import path from 'path/posix'; +import path from 'path'; import * as dotenv from 'dotenv'; -import slash from 'slash'; +// import slash from 'slash'; import { init, generate, tscWatch, configWatch, dockerRun, version } from './cli.js'; import deployService from './services/deploy.service.js'; @@ -89,7 +89,7 @@ program .description('Initialize a new Nango project') .action(function (this: Command) { const { debug } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); init({ absolutePath: fullPath, debug }); console.log(chalk.green(`Nango integrations initialized!`)); @@ -100,7 +100,7 @@ program .description('Generate a new Nango integration') .action(function (this: Command) { const { debug } = this.opts(); - generate({ fullPath: slash(process.cwd()), debug }); + generate({ fullPath: process.cwd(), debug }); }); program @@ -126,7 +126,7 @@ program ) .action(async function (this: Command, sync: string, connectionId: string) { const { autoConfirm, debug, e: environment, integrationId } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug }); const dryRun = new DryRunService({ fullPath }); await dryRun.run({ ...this.opts(), sync, connectionId, optionalEnvironment: environment, optionalProviderConfigKey: integrationId }, debug); @@ -138,7 +138,7 @@ program .option('--no-compile-interfaces', `Watch the ${nangoConfigFile} and recompile the interfaces on change`, true) .action(async function (this: Command) { const { compileInterfaces, autoConfirm, debug } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug, checkDist: false }); if (compileInterfaces) { @@ -159,7 +159,7 @@ program .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); const { debug } = options; - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await deployService.prep({ fullPath, options: { ...options, env: 'production' as ENV }, environment, debug }); }); @@ -167,7 +167,7 @@ program .command('migrate-config') .description('Migrate the nango.yaml from v1 (deprecated) to v2') .action(function (this: Command) { - v1toV2Migration(slash(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION))); + v1toV2Migration(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION)); }); program @@ -175,7 +175,7 @@ program .description('Migrate the script files from root level to structured directories.') .action(async function (this: Command) { const { debug } = this.opts(); - await directoryMigration(slash(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION)), debug); + await directoryMigration(path.resolve(process.cwd(), NANGO_INTEGRATIONS_LOCATION), debug); }); // Hidden commands // @@ -189,7 +189,7 @@ program .option('--no-compile-interfaces', `Don't compile the ${nangoConfigFile}`, true) .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await deployService.prep({ fullPath, options: { ...options, env: 'local' }, environment, debug: options.debug }); }); @@ -209,7 +209,7 @@ program .option('--no-compile-interfaces', `Don't compile the ${nangoConfigFile}`, true) .action(async function (this: Command, environment: string) { const options: DeployOptions = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await deployService.prep({ fullPath, options: { ...options, env: 'staging' }, environment, debug: options.debug }); }); @@ -218,7 +218,7 @@ program .description('Compile the integration files to JavaScript') .action(async function (this: Command) { const { autoConfirm, debug } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug, checkDist: false }); const match = verificationService.filesMatchConfig({ fullPath }); @@ -239,7 +239,7 @@ program .option('--no-compile-interfaces', `Watch the ${nangoConfigFile} and recompile the interfaces on change`, true) .action(async function (this: Command) { const { compileInterfaces, autoConfirm, debug } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug }); if (compileInterfaces) { configWatch({ fullPath, debug }); @@ -263,7 +263,7 @@ program .description('Verify the parsed sync config and output the object for verification') .action(async function (this: Command) { const { autoConfirm } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await verificationService.necessaryFilesExist({ fullPath, autoConfirm }); const { success, error, response } = parse(path.resolve(fullPath, NANGO_INTEGRATIONS_LOCATION)); @@ -283,7 +283,7 @@ program .arguments('environmentName') .action(async function (this: Command, environmentName: string) { const { debug } = this.opts(); - const fullPath = slash(process.cwd()); + const fullPath = process.cwd(); await deployService.admin({ fullPath, environmentName, debug }); }); diff --git a/packages/cli/lib/ourpath.ts b/packages/cli/lib/ourpath.ts deleted file mode 100644 index 9f0d3033270..00000000000 --- a/packages/cli/lib/ourpath.ts +++ /dev/null @@ -1,10 +0,0 @@ -import platform from 'node:path'; -// import posix from 'node:path/posix'; -// import slash from 'slash'; - -export default { - ...platform - // join: posix.join, - // join: (...paths: string[]) => slash(platform.join(...paths)) - // resolve: (...paths: string[]) => slash(posix.resolve(...paths)) -}; diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index 810c880c791..a88b3d9fa6f 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -2,9 +2,9 @@ import fs from 'fs'; import { glob } from 'glob'; import * as tsNode from 'ts-node'; import chalk from 'chalk'; -import path from 'path/posix'; +import path from 'path'; import { build } from 'tsup'; -// import slash from 'slash'; +import slash from 'slash'; import { getNangoRootPath, printDebug } from '../utils.js'; import { loadYamlAndGenerate } from './model.service.js'; @@ -29,8 +29,7 @@ export async function compileAllFiles({ }): Promise { console.log('compileAllFiles', fullPath); - // const tsconfig = fs.readFileSync(`${getNangoRootPath()}/tsconfig.dev.json`, 'utf8'); - const tsconfig = fs.readFileSync(path.join(getNangoRootPath() || '', 'tsconfig.dev.json'), 'utf8'); + const tsconfig = fs.readFileSync(path.join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); console.log('tsconfig', tsconfig); const distDir = path.join(fullPath, 'dist'); @@ -69,7 +68,6 @@ export async function compileAllFiles({ let success = true; for (const file of integrationFiles) { try { - // console.log('calling compile', { fullPath, file, parsed }); const completed = await compile({ fullPath, file, parsed, compiler, debug }); if (!completed) { if (scriptName && file.inputPath.includes(scriptName)) { @@ -232,10 +230,13 @@ async function compile({ //. compile with tsup ? but used tsNode above? console.log('calling build...'); + const tsconfigPath = slash(path.join(getNangoRootPath(), 'tsconfig.dev.json')); // build may throw an error await build({ - entryPoints: [file.inputPath], - tsconfig: path.join(getNangoRootPath() || '', 'tsconfig.dev.json'), + // entryPoints: [file.inputPath], + entryPoints: [slash(file.inputPath)], + // tsconfig: path.join(getNangoRootPath(), 'tsconfig.dev.json'), + tsconfig: tsconfigPath, skipNodeModulesBundle: true, silent: !debug, outDir: path.join(fullPath, 'dist'), @@ -281,7 +282,6 @@ export function resolveTsFileLocation({ providerConfigKey: string; type: ScriptFileType; }) { - // const nestedPath = path.resolve(fullPath, providerConfigKey, type, `${scriptName}.ts`); const nestedPath = path.resolve(fullPath, `${providerConfigKey}/${type}/${scriptName}.ts`); if (fs.existsSync(nestedPath)) { return fs.realpathSync(path.resolve(nestedPath, '../')); @@ -321,25 +321,24 @@ export function listFilesToCompile({ parsed.integrations.forEach((integration) => { const syncPath = `${integration.providerConfigKey}/syncs`; const actionPath = `${integration.providerConfigKey}/actions`; - const postConnectionPath = `${integration.providerConfigKey}/post-connection-scripts`; - - files = [ - ...files, - ...getMatchingFiles(fullPath, syncPath, 'ts'), - ...getMatchingFiles(fullPath, actionPath, 'ts'), - ...getMatchingFiles(fullPath, postConnectionPath, 'ts') - ]; + const postPath = `${integration.providerConfigKey}/post-connection-scripts`; + + const syncFiles = getMatchingFiles(fullPath, syncPath, 'ts'); + const actionFiles = getMatchingFiles(fullPath, actionPath, 'ts'); + const postFiles = getMatchingFiles(fullPath, postPath, 'ts'); + + files = [...files, ...syncFiles, ...actionFiles, ...postFiles]; console.log('files', files); if (debug) { - if (getMatchingFiles(fullPath, syncPath, 'ts').length > 0) { + if (syncFiles.length > 0) { printDebug(`Found nested sync files in ${syncPath}`); } - if (getMatchingFiles(fullPath, actionPath, 'ts').length > 0) { + if (actionFiles.length > 0) { printDebug(`Found nested action files in ${actionPath}`); } - if (getMatchingFiles(fullPath, postConnectionPath, 'ts').length > 0) { - printDebug(`Found nested post connection script files in ${postConnectionPath}`); + if (postFiles.length > 0) { + printDebug(`Found nested post connection script files in ${postPath}`); } } }); @@ -358,7 +357,8 @@ function getMatchingFiles(...args: string[]): string[] { // console.log('args', args); const pattern = args.join('/'); // console.log('pattern', pattern); - return glob.sync(pattern, { posix: true }); + // return glob.sync(pattern, { posix: true }); + return glob.sync(pattern); // const pattern = path.join(...args); // console.log('pattern', pattern); diff --git a/packages/cli/lib/services/compile.service.unit.test.ts b/packages/cli/lib/services/compile.service.unit.test.ts index 0178d30d03b..e030d2a9c07 100644 --- a/packages/cli/lib/services/compile.service.unit.test.ts +++ b/packages/cli/lib/services/compile.service.unit.test.ts @@ -1,13 +1,11 @@ -import path from 'node:path/posix'; +import path, { join } from 'node:path'; import { describe, expect, it } from 'vitest'; import { getFileToCompile, listFilesToCompile } from './compile.service'; import { fileURLToPath } from 'node:url'; import type { NangoYamlParsed } from '@nangohq/types'; -import slash from 'slash'; // eg "C:\Users\bburns\Workspace\test\various\src" -// const thisFolder = path.dirname(fileURLToPath(import.meta.url)); -const thisFolder = path.dirname(slash(fileURLToPath(import.meta.url))); +const thisFolder = path.dirname(fileURLToPath(import.meta.url)); describe('listFiles', () => { it('should list files with glob', () => { @@ -16,8 +14,8 @@ describe('listFiles', () => { //. why should this be the first entry? expect(files[0]).toStrictEqual({ baseName: 'verification.service', - inputPath: `${thisFolder}/verification.service.ts`, - outputPath: `${thisFolder}/dist/verification.service.js` + inputPath: join(thisFolder, 'verification.service.ts'), + outputPath: join(thisFolder, 'dist/verification.service.js') }); }); @@ -26,8 +24,8 @@ describe('listFiles', () => { expect(files.length).toBe(1); expect(files[0]).toStrictEqual({ baseName: 'compile.service', - inputPath: `${thisFolder}/compile.service.ts`, - outputPath: `${thisFolder}/dist/compile.service.js` + inputPath: join(thisFolder, 'compile.service.ts'), + outputPath: join(thisFolder, 'dist/compile.service.js') }); }); @@ -37,8 +35,8 @@ describe('listFiles', () => { expect(files.length).toBe(1); expect(files[0]).toStrictEqual({ baseName: 'compile.service', - inputPath: `${parent}/services/compile.service.ts`, - outputPath: `${parent}/dist/compile.service.js` + inputPath: join(parent, 'services/compile.service.ts'), + outputPath: join(parent, 'dist/compile.service.js') }); }); @@ -47,7 +45,7 @@ describe('listFiles', () => { expect(file).toStrictEqual({ baseName: 'foobar', inputPath: 'foobar.ts', - outputPath: `${thisFolder}/dist/foobar.js` + outputPath: join(thisFolder, 'dist/foobar.js') }); }); }); diff --git a/packages/cli/lib/services/config.service.ts b/packages/cli/lib/services/config.service.ts index df32033e282..6e75aae6066 100644 --- a/packages/cli/lib/services/config.service.ts +++ b/packages/cli/lib/services/config.service.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import path from 'path/posix'; +import path from 'path'; import Ajv from 'ajv'; import addErrors from 'ajv-errors'; import chalk from 'chalk'; @@ -101,8 +101,7 @@ export function validateYaml(yaml: any): ValidationMessage[] { const version = determineVersion(yaml); const validationFile = version === 'v1' ? 'nango.yaml.schema.v1.json' : 'nango.yaml.schema.v2.json'; - // const schema = fs.readFileSync(`${getNangoRootPath()}/lib/${validationFile}`, 'utf8'); - const schema = fs.readFileSync(path.join(getNangoRootPath() || '', `lib/${validationFile}`), 'utf8'); + const schema = fs.readFileSync(path.join(getNangoRootPath(), `lib/${validationFile}`), 'utf8'); const validate = ajv.compile(JSON.parse(schema)); if (validate(yaml)) { diff --git a/packages/cli/lib/services/config.service.unit.test.ts b/packages/cli/lib/services/config.service.unit.test.ts index cea404abb2e..a4e562f8a9c 100644 --- a/packages/cli/lib/services/config.service.unit.test.ts +++ b/packages/cli/lib/services/config.service.unit.test.ts @@ -1,4 +1,4 @@ -import path from 'node:path/posix'; +import path from 'node:path'; import yaml from 'js-yaml'; import stripAnsi from 'strip-ansi'; import { afterEach, describe, expect, it, vi } from 'vitest'; @@ -8,6 +8,7 @@ import { NangoError } from '@nangohq/shared'; function cleanLog(log: any) { return typeof log === 'string' ? stripAnsi(log) : log; } + describe('load', () => { // Not the best but until we have a logger it will work const consoleMock = vi.spyOn(console, 'log').mockImplementation(() => undefined); diff --git a/packages/cli/lib/services/deploy.service.ts b/packages/cli/lib/services/deploy.service.ts index b5376f87bb7..0f7f0552b27 100644 --- a/packages/cli/lib/services/deploy.service.ts +++ b/packages/cli/lib/services/deploy.service.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import path from 'node:path/posix'; +import path from 'node:path'; import chalk from 'chalk'; import promptly from 'promptly'; import type { AxiosResponse } from 'axios'; diff --git a/packages/cli/lib/services/migration.service.ts b/packages/cli/lib/services/migration.service.ts index e07f597c16c..56312816f7b 100644 --- a/packages/cli/lib/services/migration.service.ts +++ b/packages/cli/lib/services/migration.service.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import path from 'path/posix'; +import path from 'path'; import chalk from 'chalk'; import { exec } from 'child_process'; @@ -22,6 +22,7 @@ export const v1toV2Migration = (loadLocation: string): void => { return; } + //. fix exec(`node ${getNangoRootPath()}/scripts/v1-v2.js ./${nangoConfigFile}`, (error) => { if (error) { console.log(chalk.red(`There was an issue migrating your nango.yaml to v2.`)); @@ -87,7 +88,7 @@ export const directoryMigration = async (loadLocation: string, debug?: boolean): } for (const [providerConfigKey, integration] of Object.entries(response.parsed.integrations)) { - const integrationPath = `${loadLocation}/${providerConfigKey}`; + const integrationPath = path.join(loadLocation, providerConfigKey); await createDirectory(integrationPath, debug); if (integration.syncs) { diff --git a/packages/cli/lib/services/model.service.ts b/packages/cli/lib/services/model.service.ts index b3a5b36d421..1207d9beda9 100644 --- a/packages/cli/lib/services/model.service.ts +++ b/packages/cli/lib/services/model.service.ts @@ -1,6 +1,5 @@ import fs from 'node:fs'; -// import path from 'node:path/posix'; -import path from '../ourpath.js'; +import path from 'node:path'; import { resolve } from 'import-meta-resolve'; import chalk from 'chalk'; import type { JSONSchema7 } from 'json-schema'; diff --git a/packages/cli/lib/services/model.service.unit.test.ts b/packages/cli/lib/services/model.service.unit.test.ts index 017263cc427..5f65cfce9ac 100644 --- a/packages/cli/lib/services/model.service.unit.test.ts +++ b/packages/cli/lib/services/model.service.unit.test.ts @@ -1,6 +1,6 @@ +import os from 'node:os'; import fs from 'node:fs'; -import path from 'node:path/posix'; -import { resolve } from 'node:path'; +import path, { join } from 'node:path'; import { describe, expect, it } from 'vitest'; import { buildModelsTS, fieldToTypescript, fieldsToTypescript, getExportToJSON } from './model.service.js'; import type { NangoModel } from '@nangohq/types'; @@ -69,7 +69,7 @@ describe('buildModelTs', () => { }); it('should support all advanced syntax', () => { - const { response } = parse(resolve(__dirname, `../../fixtures/nango-yaml/v2/advanced-syntax`)); + const { response } = parse(path.resolve(__dirname, `../../fixtures/nango-yaml/v2/advanced-syntax`)); const res = buildModelsTS({ parsed: response!.parsed! }); const acc = []; for (const line of res.split('\n')) { @@ -173,10 +173,12 @@ describe('fieldToTypescript', () => { describe('generate exports', () => { describe('json', () => { it('should export to JSON', () => { - const folderTS = `/tmp/cli-exports-json`; + // const folderTS = `/tmp/cli-exports-json`; + const folderTS = join(os.tmpdir(), 'cli-exports-json'); fs.rmSync(folderTS, { recursive: true, force: true }); fs.mkdirSync(folderTS, { recursive: true }); - const pathTS = path.join(`/tmp/cli-exports-json`, 'schema.ts'); + // const pathTS = path.join(`/tmp/cli-exports-json`, 'schema.ts'); + const pathTS = join(folderTS, 'schema.ts'); fs.writeFileSync(pathTS, `export interface Test { id: string; name: number[]; }`); const res = getExportToJSON({ pathTS }); diff --git a/packages/cli/lib/services/verification.service.ts b/packages/cli/lib/services/verification.service.ts index 14059ff0b32..db0636e098f 100644 --- a/packages/cli/lib/services/verification.service.ts +++ b/packages/cli/lib/services/verification.service.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import chalk from 'chalk'; import promptly from 'promptly'; -import path from 'path/posix'; +import path from 'path'; import { nangoConfigFile } from '@nangohq/nango-yaml'; import { parse } from './config.service.js'; diff --git a/packages/cli/lib/sync.unit.cli-test.ts b/packages/cli/lib/sync.unit.cli-test.ts index 63728706861..c94b51efb29 100644 --- a/packages/cli/lib/sync.unit.cli-test.ts +++ b/packages/cli/lib/sync.unit.cli-test.ts @@ -1,6 +1,4 @@ import { expect, describe, it, afterEach, vi } from 'vitest'; -// import path from 'node:path/posix'; -// import path, { join } from './ourpath.js'; import path, { join } from 'node:path'; import os from 'node:os'; import fs from 'fs'; @@ -13,20 +11,24 @@ import { getNangoRootPath } from './utils.js'; import parserService from './services/parser.service.js'; import { copyDirectoryAndContents, removeVersion } from './tests/helpers.js'; import { parse } from './services/config.service.js'; -// import slash from 'slash'; -//. this returns a platpath - ie windows or posix +//. this returns an absolute platform path - ie windows or posix // eg 'C:\\Users\\bburns\\AppData\\Local\\Temp\\foo\\nango-integrations' function getTestDirectory(name: string): string { const tmpdir = os.tmpdir(); // eg 'c:\\users\\...' - const dir = join(tmpdir, name, 'nango-integrations'); // eg 'c:/users/...' + const dir = join(tmpdir, name, 'nango-integrations'); fs.mkdirSync(dir, { recursive: true }); fs.rmSync(dir, { recursive: true, force: true }); return dir; } -describe('generate function tests', () => { +// returns a relative platform path +function getFixturePath(s: string): string { const fixturesPath = './packages/cli/fixtures'; + return join(fixturesPath, s); +} + +describe('generate function tests', () => { // Not the best but until we have a logger it will work const consoleMock = vi.spyOn(console, 'log').mockImplementation(() => undefined); @@ -48,7 +50,7 @@ describe('generate function tests', () => { it('should not overwrite existing integration files', async () => { const dir = getTestDirectory('overwrite'); init({ absolutePath: dir, debug: false }); - await fs.promises.writeFile(join(dir, '${exampleSyncName}.ts'), 'dummy fake content', 'utf8'); + await fs.promises.writeFile(join(dir, `${exampleSyncName}.ts`), 'dummy fake content', 'utf8'); const dummyContent = 'This is dummy content. Do not overwrite!'; const exampleFilePath = join(dir, `${exampleSyncName}.ts`); @@ -397,52 +399,52 @@ describe('generate function tests', () => { }); it('should not complain of try catch not being awaited', () => { - const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/sync.ts`, 'sync', ['GithubIssue']); + const awaiting = parserService.callsAreUsedCorrectly(getFixturePath('sync.ts'), 'sync', ['GithubIssue']); expect(awaiting).toBe(true); }); it('should complain when a return statement is used', () => { - const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/return-sync.ts`, 'sync', ['GithubIssue']); + const noReturnUsed = parserService.callsAreUsedCorrectly(getFixturePath('return-sync.ts'), 'sync', ['GithubIssue']); expect(noReturnUsed).toBe(false); }); it('should not complain when a return statement is used but does not return anything', () => { - const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/void-return-sync.ts`, 'sync', ['GithubIssue']); + const noReturnUsed = parserService.callsAreUsedCorrectly(getFixturePath('void-return-sync.ts'), 'sync', ['GithubIssue']); expect(noReturnUsed).toBe(true); }); it('should not complain when a return statement is used in a nested function', () => { - const noReturnUsed = parserService.callsAreUsedCorrectly(`${fixturesPath}/nested-return-sync.ts`, 'sync', ['GreenhouseEeoc']); + const noReturnUsed = parserService.callsAreUsedCorrectly(getFixturePath('nested-return-sync.ts'), 'sync', ['GreenhouseEeoc']); expect(noReturnUsed).toBe(true); }); it('should complain of a non try catch not being awaited', () => { - const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/failing-sync.ts`, 'sync', ['GithubIssue']); + const awaiting = parserService.callsAreUsedCorrectly(getFixturePath('failing-sync.ts'), 'sync', ['GithubIssue']); expect(awaiting).toBe(false); }); it('should not complain about a correct model', () => { - const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`, 'sync', ['SomeBadModel']); + const usedCorrectly = parserService.callsAreUsedCorrectly(getFixturePath('bad-model.ts'), 'sync', ['SomeBadModel']); expect(usedCorrectly).toBe(true); }); it('should not complain about awaiting when it is returned for an action', () => { - const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/no-async-return.ts`, 'action', ['SomeModel']); + const awaiting = parserService.callsAreUsedCorrectly(getFixturePath('no-async-return.ts'), 'action', ['SomeModel']); expect(awaiting).toBe(true); }); it('should complain about an incorrect model', () => { - const awaiting = parserService.callsAreUsedCorrectly(`${fixturesPath}/bad-model.ts`, 'sync', ['GithubIssue']); + const awaiting = parserService.callsAreUsedCorrectly(getFixturePath('bad-model.ts'), 'sync', ['GithubIssue']); expect(awaiting).toBe(false); }); it('should complain if retryOn is used without retries', () => { - const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-bad.ts`, 'sync', ['GithubIssue']); + const usedCorrectly = parserService.callsAreUsedCorrectly(getFixturePath('retry-on-bad.ts'), 'sync', ['GithubIssue']); expect(usedCorrectly).toBe(false); }); it('should not complain if retryOn is used with retries', () => { - const usedCorrectly = parserService.callsAreUsedCorrectly(`${fixturesPath}/retry-on-good.ts`, 'sync', ['GithubIssue']); + const usedCorrectly = parserService.callsAreUsedCorrectly(getFixturePath('retry-on-good.ts'), 'sync', ['GithubIssue']); expect(usedCorrectly).toBe(false); }); @@ -450,9 +452,9 @@ describe('generate function tests', () => { const dir = getTestDirectory('nested'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/hubspot`, join(dir, 'hubspot')); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/nested-integrations/github`, join(dir, 'github')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/nested-integrations/nango.yaml`, join(dir, 'nango.yaml')); + await copyDirectoryAndContents(getFixturePath('nango-yaml/v2/nested-integrations/hubspot'), join(dir, 'hubspot')); + await copyDirectoryAndContents(getFixturePath('nango-yaml/v2/nested-integrations/github'), join(dir, 'github')); + await fs.promises.copyFile(getFixturePath('nango-yaml/v2/nested-integrations/nango.yaml'), join(dir, 'nango.yaml')); const success = await compileAllFiles({ fullPath: dir, debug: true }); @@ -469,7 +471,7 @@ describe('generate function tests', () => { const dir = getTestDirectory('old-directory'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/non-nested-integrations`, dir); + await copyDirectoryAndContents(getFixturePath('nango-yaml/v2/non-nested-integrations'), dir); const success = await compileAllFiles({ fullPath: dir, debug: false }); @@ -483,8 +485,8 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/relative-imports/github`, join(dir, 'github')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/relative-imports/nango.yaml`, join(dir, 'nango.yaml')); + await copyDirectoryAndContents(getFixturePath('nango-yaml/v2/relative-imports/github'), join(dir, 'github')); + await fs.promises.copyFile(getFixturePath('nango-yaml/v2/relative-imports/nango.yaml'), join(dir, 'nango.yaml')); const success = await compileAllFiles({ fullPath: dir, debug: false }); @@ -501,11 +503,11 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-error'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); + await copyDirectoryAndContents(getFixturePath(`nango-yaml/v2/${name}/github`), join(dir, 'github')); + await fs.promises.copyFile(getFixturePath(`nango-yaml/v2/${name}/nango.yaml`), join(dir, 'nango.yaml')); const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(path.resolve(fixturesPath, `nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(getFixturePath(`nango-yaml/v2/${name}`))); expect(response?.parsed).not.toBeNull(); const result = await compileSingleFile({ @@ -523,11 +525,11 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-nango-misuse'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); + await copyDirectoryAndContents(getFixturePath(`nango-yaml/v2/${name}/github`), join(dir, 'github')); + await fs.promises.copyFile(getFixturePath(`nango-yaml/v2/${name}/nango.yaml`), join(dir, 'nango.yaml')); const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(getFixturePath(`nango-yaml/v2/${name}`))); expect(response).not.toBeNull(); const result = await compileSingleFile({ @@ -545,12 +547,12 @@ describe('generate function tests', () => { const dir = getTestDirectory('relative-imports-with-higher-import'); init({ absolutePath: dir }); - await copyDirectoryAndContents(`${fixturesPath}/nango-yaml/v2/${name}/github`, join(dir, 'github')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/nango.yaml`, join(dir, 'nango.yaml')); - await fs.promises.copyFile(`${fixturesPath}/nango-yaml/v2/${name}/github/actions/welcomer.ts`, join(dir, 'welcomer.ts')); + await copyDirectoryAndContents(getFixturePath(`nango-yaml/v2/${name}/github`), join(dir, 'github')); + await fs.promises.copyFile(getFixturePath(`nango-yaml/v2/${name}/nango.yaml`), join(dir, 'nango.yaml')); + await fs.promises.copyFile(getFixturePath(`nango-yaml/v2/${name}/github/actions/welcomer.ts`), join(dir, 'welcomer.ts')); const tsconfig = fs.readFileSync(join(getNangoRootPath(), 'tsconfig.dev.json'), 'utf8'); - const { response } = parse(path.resolve(`${fixturesPath}/nango-yaml/v2/${name}`)); + const { response } = parse(path.resolve(getFixturePath(`nango-yaml/v2/${name}`))); expect(response).not.toBeNull(); const result = await compileSingleFile({ diff --git a/packages/cli/lib/tests/helpers.ts b/packages/cli/lib/tests/helpers.ts index 9c14a7ca58f..6f216a47cdc 100644 --- a/packages/cli/lib/tests/helpers.ts +++ b/packages/cli/lib/tests/helpers.ts @@ -1,4 +1,4 @@ -import path from 'path/posix'; +import path from 'path'; import fs from 'fs/promises'; export const copyDirectoryAndContents = async (source: string, destination: string) => { diff --git a/packages/cli/lib/utils.ts b/packages/cli/lib/utils.ts index a30a8c0ce1a..a4b55e506a4 100644 --- a/packages/cli/lib/utils.ts +++ b/packages/cli/lib/utils.ts @@ -1,10 +1,9 @@ import axios, { AxiosError } from 'axios'; import fs from 'fs'; import os from 'os'; +import path from 'path'; import npa from 'npm-package-arg'; import Module from 'node:module'; -// import path, { dirname } from 'path/posix'; -import path from './ourpath.js'; import { fileURLToPath } from 'url'; import semver from 'semver'; import util from 'util'; @@ -273,7 +272,7 @@ export function getUserAgent(): string { return `nango-cli/${clientVersion} (${osName}/${osVersion}; node.js/${nodeVersion})`; } -//. returns a platpath - so use with path.join - wrap in slash() if needed +//. returns an absolute platformpath export function getNangoRootPath(debug = false): string { const packagePath = getPackagePath(debug); if (!packagePath) { @@ -294,7 +293,7 @@ export function getNangoRootPath(debug = false): string { return rootPath; } -//. returns a platpath +//. returns an absolute platformpath function getPackagePath(debug = false): string { if (process.env['CI'] || process.env['VITEST']) { return path.join(__dirname); diff --git a/packages/cli/lib/utils/layoutMode.ts b/packages/cli/lib/utils/layoutMode.ts index a7a00fab192..c599b5c7490 100644 --- a/packages/cli/lib/utils/layoutMode.ts +++ b/packages/cli/lib/utils/layoutMode.ts @@ -1,6 +1,6 @@ import type { LayoutMode } from '@nangohq/types'; import fs from 'node:fs'; -import path from 'node:path/posix'; +import path from 'node:path'; /* * Get Layout Mode From 3822d7e15287a7b7d9113e9a50165702a1b45b94 Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Fri, 5 Jul 2024 03:36:40 -0500 Subject: [PATCH 09/10] cleanup --- packages/cli/lib/services/compile.service.ts | 46 ++++--------------- .../lib/services/compile.service.unit.test.ts | 8 +++- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index a88b3d9fa6f..d0b9587a5e0 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -262,6 +262,8 @@ export interface ListedFile { baseName: string; } +// inputPath - absolute platform path +// outputPath - absolute platform path export function getFileToCompile({ fullPath, filePath }: { fullPath: string; filePath: string }): ListedFile { const baseName = path.basename(filePath, '.ts'); return { @@ -349,43 +351,13 @@ export function listFilesToCompile({ }); } -// get array of file paths that match the given path parts. -// last part is treated as a file extension. -// eg getMatchingFiles('foo', 'ts') -> glob.sync('foo/*.ts') +// get absolute platform file paths that match the given path parts, +// with last part treated as a file extension. +// eg getMatchingFiles('/foo', 'bar', 'ts') -> glob.sync('/foo/bar/*.ts') +// returns ['/foo/bar/baz.ts', '/foo/bar/pok.ts', ...] function getMatchingFiles(...args: string[]): string[] { args.splice(-1, 1, `*.${args.slice(-1)[0]}`); - // console.log('args', args); - const pattern = args.join('/'); - // console.log('pattern', pattern); - // return glob.sync(pattern, { posix: true }); - return glob.sync(pattern); - - // const pattern = path.join(...args); - // console.log('pattern', pattern); - - // windowsPathsNoEscape - // Use \\ as a path separator only, and never as an escape - // character. - // If set, all \\ characters are replaced with / in the - // pattern. Note that this makes it impossible to match - // against paths containing literal glob pattern characters, - // but allows matching with patterns constructed using - // path.join() and path.resolve() on Windows platforms, - // mimicking the (buggy!) behavior of Glob v7 and before on - // Windows. - - // absolute - // Set to false to always return relative paths. When - // this option is not set, absolute paths are returned for - // patterns that are absolute, and otherwise paths are - // returned that are relative to the cwd setting. - - // posix - // Return / delimited paths, even on Windows. - // On posix systems, this has no effect. But, on Windows, it - // means that paths will be / delimited, and absolute paths - // will be their full resolved UNC forms, eg instead of - // 'C:\\foo\\bar', it would return '//?/C:/foo/bar' - - // return glob.sync(pattern, { windowsPathsNoEscape: true, absolute: false, posix: true }); + // glob prefers posix paths as input + const pattern = args.join('/'); // eg '/foo/bar/*.ts' + return glob.sync(pattern, { absolute: true }); } diff --git a/packages/cli/lib/services/compile.service.unit.test.ts b/packages/cli/lib/services/compile.service.unit.test.ts index e030d2a9c07..8df6133f5b2 100644 --- a/packages/cli/lib/services/compile.service.unit.test.ts +++ b/packages/cli/lib/services/compile.service.unit.test.ts @@ -4,7 +4,7 @@ import { getFileToCompile, listFilesToCompile } from './compile.service'; import { fileURLToPath } from 'node:url'; import type { NangoYamlParsed } from '@nangohq/types'; -// eg "C:\Users\bburns\Workspace\test\various\src" +// eg "C:\\Users\bburns\\Workspace\\forks\\nango\\packages\\cli\\lib\\services" const thisFolder = path.dirname(fileURLToPath(import.meta.url)); describe('listFiles', () => { @@ -14,6 +14,12 @@ describe('listFiles', () => { //. why should this be the first entry? expect(files[0]).toStrictEqual({ baseName: 'verification.service', + //. but listFiles gives + // 'packages\\cli\\lib\\services\\verification.service.ts' + // why? + // that's relative to curdir, not fullpath + // oh, that's what glob does - wew + // path.relative(join..., '') inputPath: join(thisFolder, 'verification.service.ts'), outputPath: join(thisFolder, 'dist/verification.service.js') }); From 2359abfdf7388014e610f326ac7a34b644569c0c Mon Sep 17 00:00:00 2001 From: Brian Burns Date: Fri, 5 Jul 2024 12:17:54 -0500 Subject: [PATCH 10/10] wip --- packages/cli/lib/cli.ts | 11 ++++------- packages/cli/lib/services/compile.service.ts | 2 ++ packages/nango-yaml/lib/helpers.ts | 4 +++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index e570888d790..e0e2b570057 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -7,7 +7,6 @@ import ejs from 'ejs'; import * as dotenv from 'dotenv'; import { spawn } from 'child_process'; import type { ChildProcess } from 'node:child_process'; -import slash from 'slash'; import { NANGO_INTEGRATIONS_NAME, getNangoRootPath, getPkgVersion, printDebug } from './utils.js'; import { loadYamlAndGenerate } from './services/model.service.js'; @@ -238,9 +237,9 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? fs.mkdirSync(distDir); } + // filePath is a relative platform path, eg '.nango\\schema.ts' watcher.on('add', async (filePath: string) => { - // filePath = filePath.replace(/\\/g, '/'); - filePath = slash(filePath); + console.log('watcher add', filePath); if (filePath === nangoConfigFile) { return; } @@ -248,8 +247,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('unlink', (filePath: string) => { - // filePath = filePath.replace(/\\/g, '/'); - // filePath = slash(filePath); + console.log('watcher unlink', filePath); if (filePath === nangoConfigFile) { return; } @@ -266,8 +264,7 @@ export function tscWatch({ fullPath, debug = false }: { fullPath: string; debug? }); watcher.on('change', async (filePath: string) => { - // filePath = filePath.replace(/\\/g, '/'); - // filePath = slash(filePath); + console.log('watcher change', filePath); if (filePath === nangoConfigFile) { await compileAllFiles({ fullPath, debug }); return; diff --git a/packages/cli/lib/services/compile.service.ts b/packages/cli/lib/services/compile.service.ts index d0b9587a5e0..f26da253832 100644 --- a/packages/cli/lib/services/compile.service.ts +++ b/packages/cli/lib/services/compile.service.ts @@ -262,6 +262,8 @@ export interface ListedFile { baseName: string; } +// fullPath - +// filePath - abs or relative platform path // inputPath - absolute platform path // outputPath - absolute platform path export function getFileToCompile({ fullPath, filePath }: { fullPath: string; filePath: string }): ListedFile { diff --git a/packages/nango-yaml/lib/helpers.ts b/packages/nango-yaml/lib/helpers.ts index ac019a9147e..564fa575133 100644 --- a/packages/nango-yaml/lib/helpers.ts +++ b/packages/nango-yaml/lib/helpers.ts @@ -183,9 +183,11 @@ export function shouldQuote(name: string) { // return filepath.split(path.sep); // } +//. filePath is a platform path - relative is okay export function getProviderConfigurationFromPath({ filePath, parsed }: { filePath: string; parsed: NangoYamlParsed }): NangoYamlParsedIntegration | null { - // const pathSegments = filePath.split('/'); + console.log('getProviderConfigurationFromPath', filePath); const pathSegments = filePath.split(path.sep); + console.log('pathSegments', pathSegments); const scriptType = pathSegments.length > 1 ? pathSegments[pathSegments.length - 2] : null; const isNested = scriptType === 'syncs' || scriptType === 'actions' || scriptType === 'post-connection-scripts';