diff --git a/packages/insomnia-cli/package-lock.json b/packages/insomnia-cli/package-lock.json
index 930f337667..73fde0768b 100644
--- a/packages/insomnia-cli/package-lock.json
+++ b/packages/insomnia-cli/package-lock.json
@@ -1879,7 +1879,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
@@ -2265,6 +2264,11 @@
"unset-value": "^1.0.0"
}
},
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms="
+ },
"caller-callsite": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
@@ -2757,8 +2761,7 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"estraverse": {
"version": "4.3.0",
@@ -5286,7 +5289,6 @@
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
- "dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -5350,6 +5352,16 @@
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"dev": true
},
+ "json-schema-ref-parser": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-7.1.4.tgz",
+ "integrity": "sha512-AD7bvav0vak1/63w3jH8F7eHId/4E4EPdMAEZhGxtjktteUv9dnNB/cJy6nVnMyoTPBJnLwFK6tiQPSTeleCtQ==",
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^3.13.1",
+ "ono": "^6.0.0"
+ }
+ },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -5441,6 +5453,16 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -5794,6 +5816,32 @@
"mimic-fn": "^2.1.0"
}
},
+ "ono": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ono/-/ono-6.0.1.tgz",
+ "integrity": "sha512-5rdYW/106kHqLeG22GE2MHKq+FlsxMERZev9DCzQX1zwkxnFwBivSn5i17a5O/rDmOJOdf4Wyt80UZljzx9+DA=="
+ },
+ "openapi-2-kong": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/openapi-2-kong/-/openapi-2-kong-2.2.6.tgz",
+ "integrity": "sha512-GggreyB+ZbkjO9MqDIZOm/M9mrSdVdsSyYYx0uglz1S7EhC0YAN+RNIFJWD1aZ9xkEXmzpjaIT12/KjyHb7Svw==",
+ "requires": {
+ "slugify": "^1.3.6",
+ "swagger-parser": "^8.0.3",
+ "url-join": "^4.0.1",
+ "yaml": "^1.7.2"
+ }
+ },
+ "openapi-schemas": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/openapi-schemas/-/openapi-schemas-1.0.3.tgz",
+ "integrity": "sha512-KtMWcK2VtOS+nD8RKSIyScJsj8JrmVWcIX7Kjx4xEHijFYuvMTDON8WfeKOgeSb4uNG6UsqLj5Na7nKbSav9RQ=="
+ },
+ "openapi-types": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.5.tgz",
+ "integrity": "sha512-11oi4zYorsgvg5yBarZplAqbpev5HkuVNPlZaPTknPDzAynq+lnJdXAmruGWP0s+dNYZS7bjM+xrTpJw7184Fg=="
+ },
"opencollective-postinstall": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
@@ -6652,6 +6700,11 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
+ "slugify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.0.tgz",
+ "integrity": "sha512-FtLNsMGBSRB/0JOE2A0fxlqjI6fJsgHGS13iTuVT28kViI4JjUiNqp/vyis0ZXYcMnpR3fzGNkv+6vRlI2GwdQ=="
+ },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -6861,8 +6914,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.16.1",
@@ -7019,6 +7071,25 @@
}
}
},
+ "swagger-methods": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/swagger-methods/-/swagger-methods-2.0.2.tgz",
+ "integrity": "sha512-/RNqvBZkH8+3S/FqBPejHxJxZenaYq3MrpeXnzi06aDIS39Mqf5YCUNb/ZBjsvFFt8h9FxfKs8EXPtcYdfLiRg=="
+ },
+ "swagger-parser": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-8.0.4.tgz",
+ "integrity": "sha512-KGRdAaMJogSEB7sPKI31ptKIWX8lydEDAwWgB4pBMU7zys5cd54XNhoPSVlTxG/A3LphjX47EBn9j0dOGyzWbA==",
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "json-schema-ref-parser": "^7.1.3",
+ "ono": "^6.0.0",
+ "openapi-schemas": "^1.0.2",
+ "openapi-types": "^1.3.5",
+ "swagger-methods": "^2.0.1",
+ "z-schema": "^4.2.2"
+ }
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -7273,6 +7344,11 @@
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
"dev": true
},
+ "url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
+ },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -7322,6 +7398,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "validator": {
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz",
+ "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ=="
+ },
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@@ -7534,6 +7615,25 @@
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
+ },
+ "z-schema": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.3.tgz",
+ "integrity": "sha512-zkvK/9TC6p38IwcrbnT3ul9in1UX4cm1y/VZSs4GHKIiDCrlafc+YQBgQBUdDXLAoZHf2qvQ7gJJOo6yT1LH6A==",
+ "requires": {
+ "commander": "^2.7.1",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "validator": "^12.0.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "optional": true
+ }
+ }
}
}
}
diff --git a/packages/insomnia-cli/src/__tests__/__snapshots__/inso-snapshot.test.js.snap b/packages/insomnia-cli/src/__tests__/__snapshots__/inso-snapshot.test.js.snap
index e96fc8aa8b..4d79340dab 100644
--- a/packages/insomnia-cli/src/__tests__/__snapshots__/inso-snapshot.test.js.snap
+++ b/packages/insomnia-cli/src/__tests__/__snapshots__/inso-snapshot.test.js.snap
@@ -6,12 +6,13 @@ exports[`Snapshot for "inso --help" 1`] = `
A CLI for Insomnia!
Options:
- -v, --version output the version number
- -h, --help display help for command
+ -v, --version output the version number
+ --workingDir
Working directory
+ -h, --help display help for command
Commands:
- generate Code generation utilities
- help [command] display help for command"
+ generate Code generation utilities
+ help [command] display help for command"
`;
exports[`Snapshot for "inso -h" 1`] = `
@@ -20,12 +21,13 @@ exports[`Snapshot for "inso -h" 1`] = `
A CLI for Insomnia!
Options:
- -v, --version output the version number
- -h, --help display help for command
+ -v, --version output the version number
+ --workingDir Working directory
+ -h, --help display help for command
Commands:
- generate Code generation utilities
- help [command] display help for command"
+ generate Code generation utilities
+ help [command] display help for command"
`;
exports[`Snapshot for "inso generate -h" 1`] = `
@@ -34,15 +36,15 @@ exports[`Snapshot for "inso generate -h" 1`] = `
Code generation utilities
Options:
- -h, --help display help for command
+ -h, --help display help for command
Commands:
- config [options] Generate configuration from an api spec
- help [command] display help for command"
+ config [options] Generate configuration from an api spec
+ help [command] display help for command"
`;
exports[`Snapshot for "inso generate config -h" 1`] = `
-"Usage: inso generate config [options]
+"Usage: inso generate config [options]
Generate configuration from an api spec
@@ -59,10 +61,11 @@ exports[`Snapshot for "inso help" 1`] = `
A CLI for Insomnia!
Options:
- -v, --version output the version number
- -h, --help display help for command
+ -v, --version output the version number
+ --workingDir Working directory
+ -h, --help display help for command
Commands:
- generate Code generation utilities
- help [command] display help for command"
+ generate Code generation utilities
+ help [command] display help for command"
`;
diff --git a/packages/insomnia-cli/src/__tests__/cli.test.js b/packages/insomnia-cli/src/__tests__/cli.test.js
index 185e6b785f..34ef491b34 100644
--- a/packages/insomnia-cli/src/__tests__/cli.test.js
+++ b/packages/insomnia-cli/src/__tests__/cli.test.js
@@ -36,19 +36,30 @@ describe('cli', () => {
it('should call generateConfig with undefined output argument', () => {
inso('generate config -t declarative file.yaml');
- expect(generateConfig).toHaveBeenCalledWith({
- filePath: 'file.yaml',
+ expect(generateConfig).toHaveBeenCalledWith('file.yaml', {
type: 'declarative',
- output: undefined,
});
});
it('should call generateConfig with all expected arguments', () => {
inso('generate config -t kubernetes -o output.yaml file.yaml');
- expect(generateConfig).toHaveBeenCalledWith({
- filePath: 'file.yaml',
- type: 'kubernetes',
- output: 'output.yaml',
- });
+ expect(generateConfig).toHaveBeenCalledWith(
+ 'file.yaml',
+ expect.objectContaining({
+ type: 'kubernetes',
+ output: 'output.yaml',
+ }),
+ );
+ });
+
+ it('should call generateConfig with global option', () => {
+ inso('generate config -t kubernetes --workingDir testing/dir file.yaml');
+ expect(generateConfig).toHaveBeenCalledWith(
+ 'file.yaml',
+ expect.objectContaining({
+ type: 'kubernetes',
+ workingDir: 'testing/dir',
+ }),
+ );
});
});
diff --git a/packages/insomnia-cli/src/__tests__/util.test.js b/packages/insomnia-cli/src/__tests__/util.test.js
new file mode 100644
index 0000000000..41ecbf08d4
--- /dev/null
+++ b/packages/insomnia-cli/src/__tests__/util.test.js
@@ -0,0 +1,23 @@
+// @flow
+import commander from 'commander';
+import { getAllOptions } from '../util';
+
+describe('getAllOptions()', () => {
+ it('should combine options from all commands into one object', () => {
+ const command = new commander.Command('command');
+
+ command
+ .command('subCommand')
+ .option('-s, --subCmd')
+ .action(cmd => {
+ expect(getAllOptions(cmd)).toEqual({
+ global: true,
+ subCmd: true,
+ });
+ });
+
+ const parent = new commander.Command().option('-g, --global').addCommand(command);
+
+ parent.parse('node test command subCommand --global --subCmd'.split(' '));
+ });
+});
diff --git a/packages/insomnia-cli/src/cli.js b/packages/insomnia-cli/src/cli.js
index d7fbe24e95..62f3575c09 100755
--- a/packages/insomnia-cli/src/cli.js
+++ b/packages/insomnia-cli/src/cli.js
@@ -1,6 +1,6 @@
// @flow
import { ConversionTypeMap, generateConfig } from './commands/generate';
-import { getVersion, createCommand } from './util';
+import { getVersion, createCommand, getAllOptions } from './util';
function makeGenerateCommand(exitOverride: boolean) {
// inso generate
@@ -10,14 +10,14 @@ function makeGenerateCommand(exitOverride: boolean) {
// inso generate config -t kubernetes config.yaml
generate
- .command('config ')
+ .command('config ')
.description('Generate configuration from an api spec')
.requiredOption(
'-t, --type ',
`the type of configuration to generate, options are [${conversionTypes}]`,
)
.option('-o, --output ', 'the output path')
- .action((filePath, opts) => generateConfig({ filePath, ...opts }));
+ .action((identifier, cmd) => generateConfig(identifier, getAllOptions(cmd)));
return generate;
}
@@ -31,6 +31,8 @@ export function go(args?: Array, exitOverride?: boolean): void {
createCommand(!!exitOverride)
.version(getVersion(), '-v, --version')
.description('A CLI for Insomnia!')
+ .option('--workingDir ', 'Working directory')
.addCommand(makeGenerateCommand(!!exitOverride))
- .parse(args);
+ .parseAsync(args)
+ .catch(err => console.log('An error occurred', err));
}
diff --git a/packages/insomnia-cli/src/commands/__tests__/generate.test.js b/packages/insomnia-cli/src/commands/__tests__/generate.test.js
index 2fc9728ce4..d22c220928 100644
--- a/packages/insomnia-cli/src/commands/__tests__/generate.test.js
+++ b/packages/insomnia-cli/src/commands/__tests__/generate.test.js
@@ -6,13 +6,6 @@ import fs from 'fs';
import path from 'path';
jest.mock('openapi-2-kong');
-jest.mock('fs');
-
-const base: GenerateConfigOptions = {
- filePath: 'file.yaml',
- type: 'kubernetes',
- output: undefined,
-};
describe('generateConfig()', () => {
// make flow happy
@@ -20,10 +13,18 @@ describe('generateConfig()', () => {
afterEach(() => {
jest.restoreAllMocks();
});
+
+ const base: GenerateConfigOptions = {
+ type: 'kubernetes',
+ output: undefined,
+ };
+
+ const filePath = 'file.yaml';
+
it('should should not generate if type arg is invalid', async () => {
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
- await generateConfig({ ...base, type: 'invalid' });
+ await generateConfig(filePath, { ...base, type: 'invalid' });
expect(o2k.generate).not.toHaveBeenCalled();
expect(consoleSpy).toHaveBeenCalledWith(
@@ -35,20 +36,34 @@ describe('generateConfig()', () => {
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
mock(o2k.generate).mockResolvedValue({ documents: ['a', 'b'] });
- await generateConfig(base);
+ await generateConfig(filePath, base);
- expect(o2k.generate).toHaveBeenCalledWith(base.filePath, ConversionTypeMap[base.type]);
+ expect(o2k.generate).toHaveBeenCalledWith(filePath, ConversionTypeMap[base.type]);
+ expect(consoleSpy).toHaveBeenCalledWith('a\n---\nb\n');
+ });
+
+ it('should load identifier from database', async () => {
+ const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
+ mock(o2k.generateFromString).mockResolvedValue({ documents: ['a', 'b'] });
+
+ await generateConfig('spc_46c5a4a40e83445a9bd9d9758b86c16c', {
+ ...base,
+ workingDir: 'src/db/__fixtures__/git-repo',
+ });
+
+ expect(o2k.generateFromString).toHaveBeenCalled();
expect(consoleSpy).toHaveBeenCalledWith('a\n---\nb\n');
});
it('should write converted documents to file system', async () => {
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
+ const writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {});
mock(o2k.generate).mockResolvedValue({ documents: ['a', 'b'] });
- await generateConfig({ ...base, output: 'output.yaml' });
+ await generateConfig(filePath, { ...base, output: 'output.yaml' });
- expect(o2k.generate).toHaveBeenCalledWith(base.filePath, ConversionTypeMap[base.type]);
- expect(fs.writeFileSync).toHaveBeenCalledWith(path.resolve('output.yaml'), 'a\n---\nb\n');
+ expect(o2k.generate).toHaveBeenCalledWith(filePath, ConversionTypeMap[base.type]);
+ expect(writeFileSpy).toHaveBeenCalledWith(path.resolve('output.yaml'), 'a\n---\nb\n');
expect(consoleSpy).not.toHaveBeenCalled();
});
});
diff --git a/packages/insomnia-cli/src/commands/generate.js b/packages/insomnia-cli/src/commands/generate.js
index f5b7f84300..da663cfbb0 100644
--- a/packages/insomnia-cli/src/commands/generate.js
+++ b/packages/insomnia-cli/src/commands/generate.js
@@ -1,19 +1,20 @@
// @flow
-import o2k from 'openapi-2-kong';
+import * as o2k from 'openapi-2-kong';
import YAML from 'yaml';
import path from 'path';
import fs from 'fs';
+import type { GlobalOptions } from '../util';
+import { gitDataDirDb } from '../db/mem-db';
export const ConversionTypeMap: { [string]: ConversionResultType } = {
kubernetes: 'kong-for-kubernetes',
declarative: 'kong-declarative-config',
};
-export type GenerateConfigOptions = {|
- filePath: string,
+export type GenerateConfigOptions = GlobalOptions<{|
type: $Keys,
output?: string,
-|};
+|}>;
function validateOptions({ type }: GenerateConfigOptions): boolean {
if (!ConversionTypeMap[type]) {
@@ -25,14 +26,31 @@ function validateOptions({ type }: GenerateConfigOptions): boolean {
return true;
}
-export async function generateConfig(options: GenerateConfigOptions): Promise {
+export async function generateConfig(
+ identifier: string,
+ options: GenerateConfigOptions,
+): Promise {
if (!validateOptions(options)) {
return;
}
- const { type, output, filePath } = options;
+ const { type, output, workingDir } = options;
- const result = await o2k.generate(filePath, ConversionTypeMap[type]);
+ const db = await gitDataDirDb({ dir: workingDir, filterTypes: ['ApiSpec'] });
+
+ let result: ConversionResult;
+
+ const specFromDb = db.ApiSpec.get(identifier);
+ try {
+ if (specFromDb?.contents) {
+ result = await o2k.generateFromString(specFromDb.contents, ConversionTypeMap[type]);
+ } else {
+ result = await o2k.generate(identifier, ConversionTypeMap[type]);
+ }
+ } catch (err) {
+ console.log('Config failed to generate', err);
+ return;
+ }
const yamlDocs = result.documents.map(d => YAML.stringify(d));
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Malformed/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Malformed/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml
new file mode 100755
index 0000000000..2c4b7f6474
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Malformed/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml
@@ -0,0 +1,32 @@
+_id: spc_46c5a4a40e83445a9bd9d9758b86c16c
+contentType: yaml
+contents: |
+ openapi: '3.0.2'
+ info:
+ title: Global Security
+ version: '1.2'
+ servers:
+ - url: https://api.server.test/v1
+ tags:
+ - name: Folder
+
+ paths:
+ /global:
+ get:
+ tags:
+ - Folder
+ responses:
+ '200':
+ description: OK
+ /override:
+ get:
+ security:
+ - Key-Query: []
+ responses:
+ '200':
+ description: OK
+created: 1589851906273
+fileName: Global Security
+modified: 1592254074772
+parentId: wrk_012d4860c7da418a85ffea7406e1292a
+type: ApiSpec
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml
new file mode 100755
index 0000000000..b54ee1cd5f
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo-malformed-insomnia/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml
@@ -0,0 +1,8 @@
+_id: wrk_012d4860c7da418a85ffea7406e1292a
+created: 1589851906270
+description: ""
+modified: 1592254074771
+name: Global Security 1.2
+parentId: null
+scope: spec
+type: Workspace
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo-without-insomnia/blank.js b/packages/insomnia-cli/src/db/__fixtures__/git-repo-without-insomnia/blank.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/ApiSpec/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/ApiSpec/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml
new file mode 100755
index 0000000000..2c4b7f6474
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/ApiSpec/spc_46c5a4a40e83445a9bd9d9758b86c16c.yml
@@ -0,0 +1,32 @@
+_id: spc_46c5a4a40e83445a9bd9d9758b86c16c
+contentType: yaml
+contents: |
+ openapi: '3.0.2'
+ info:
+ title: Global Security
+ version: '1.2'
+ servers:
+ - url: https://api.server.test/v1
+ tags:
+ - name: Folder
+
+ paths:
+ /global:
+ get:
+ tags:
+ - Folder
+ responses:
+ '200':
+ description: OK
+ /override:
+ get:
+ security:
+ - Key-Query: []
+ responses:
+ '200':
+ description: OK
+created: 1589851906273
+fileName: Global Security
+modified: 1592254074772
+parentId: wrk_012d4860c7da418a85ffea7406e1292a
+type: ApiSpec
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_ca046a738f001eb3090261a537b1b78f86c2094c.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_ca046a738f001eb3090261a537b1b78f86c2094c.yml
new file mode 100755
index 0000000000..8eced02ede
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_ca046a738f001eb3090261a537b1b78f86c2094c.yml
@@ -0,0 +1,14 @@
+_id: env_ca046a738f001eb3090261a537b1b78f86c2094c
+color: null
+created: 1589851906358
+data:
+ base_url: "{{ scheme }}://{{ host }}{{ base_path }}"
+dataPropertyOrder:
+ "&":
+ - base_url
+isPrivate: false
+metaSortKey: 1589851906358
+modified: 1592254074769
+name: Base environment
+parentId: wrk_012d4860c7da418a85ffea7406e1292a
+type: Environment
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_env_ca046a738f001eb3090261a537b1b78f86c2094c_sub.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_env_ca046a738f001eb3090261a537b1b78f86c2094c_sub.yml
new file mode 100755
index 0000000000..354252fb22
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Environment/env_env_ca046a738f001eb3090261a537b1b78f86c2094c_sub.yml
@@ -0,0 +1,14 @@
+_id: env_env_ca046a738f001eb3090261a537b1b78f86c2094c_sub
+color: null
+created: 1592252904087
+data:
+ base_path: /v1
+ host: api.server.test
+ scheme: https
+dataPropertyOrder: null
+isPrivate: false
+metaSortKey: 1592252904087
+modified: 1592254074767
+name: OpenAPI env
+parentId: env_ca046a738f001eb3090261a537b1b78f86c2094c
+type: Environment
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292a21946b60.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292a21946b60.yml
new file mode 100755
index 0000000000..b5e8dd00ea
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292a21946b60.yml
@@ -0,0 +1,21 @@
+_id: req_wrk_012d4860c7da418a85ffea7406e1292a21946b60
+authentication: {}
+body: {}
+created: 1592254074764
+description: ""
+headers: []
+isPrivate: false
+metaSortKey: -1592254074764
+method: GET
+modified: 1592254074764
+name: /global
+parameters: []
+parentId: fld_wrk_012d4860c7da418a85ffea7406e1292a30baa249
+settingDisableRenderRequestBody: false
+settingEncodeUrl: true
+settingFollowRedirects: global
+settingRebuildPath: true
+settingSendCookies: true
+settingStoreCookies: true
+type: Request
+url: "{{ base_url }}/global"
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292ab410454b.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292ab410454b.yml
new file mode 100755
index 0000000000..f36b742a8a
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Request/req_wrk_012d4860c7da418a85ffea7406e1292ab410454b.yml
@@ -0,0 +1,21 @@
+_id: req_wrk_012d4860c7da418a85ffea7406e1292ab410454b
+authentication: {}
+body: {}
+created: 1592254074762
+description: ""
+headers: []
+isPrivate: false
+metaSortKey: -1592254074762
+method: GET
+modified: 1592254074762
+name: /override
+parameters: []
+parentId: wrk_012d4860c7da418a85ffea7406e1292a
+settingDisableRenderRequestBody: false
+settingEncodeUrl: true
+settingFollowRedirects: global
+settingRebuildPath: true
+settingSendCookies: true
+settingStoreCookies: true
+type: Request
+url: "{{ base_url }}/override"
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/RequestGroup/fld_wrk_012d4860c7da418a85ffea7406e1292a30baa249.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/RequestGroup/fld_wrk_012d4860c7da418a85ffea7406e1292a30baa249.yml
new file mode 100755
index 0000000000..672cb2da92
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/RequestGroup/fld_wrk_012d4860c7da418a85ffea7406e1292a30baa249.yml
@@ -0,0 +1,10 @@
+_id: fld_wrk_012d4860c7da418a85ffea7406e1292a30baa249
+created: 1592254074765
+description: ""
+environment: {}
+environmentPropertyOrder: null
+metaSortKey: -1592254074765
+modified: 1592254074765
+name: Folder
+parentId: wrk_012d4860c7da418a85ffea7406e1292a
+type: RequestGroup
diff --git a/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml
new file mode 100755
index 0000000000..b54ee1cd5f
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__fixtures__/git-repo/.insomnia/Workspace/wrk_012d4860c7da418a85ffea7406e1292a.yml
@@ -0,0 +1,8 @@
+_id: wrk_012d4860c7da418a85ffea7406e1292a
+created: 1589851906270
+description: ""
+modified: 1592254074771
+name: Global Security 1.2
+parentId: null
+scope: spec
+type: Workspace
diff --git a/packages/insomnia-cli/src/db/__tests__/mem-db.test.js b/packages/insomnia-cli/src/db/__tests__/mem-db.test.js
new file mode 100644
index 0000000000..4e14332318
--- /dev/null
+++ b/packages/insomnia-cli/src/db/__tests__/mem-db.test.js
@@ -0,0 +1,44 @@
+// @flow
+import path from 'path';
+import { gitDataDirDb } from '../mem-db';
+
+describe('mem-db', () => {
+ describe('seedGitDataDir()', () => {
+ const fixturesPath = 'src/db/__fixtures__';
+
+ it('should seed with git-repo directory', async () => {
+ const dir = path.join(fixturesPath, 'git-repo');
+ const db = await gitDataDirDb({ dir });
+
+ expect(db.ApiSpec.size).toBe(1);
+ expect(db.Environment.size).toBe(2);
+ expect(db.Request.size).toBe(2);
+ expect(db.RequestGroup.size).toBe(1);
+ expect(db.Workspace.size).toBe(1);
+ });
+
+ it('should seed with git-repo directory with filter', async () => {
+ const dir = path.join(fixturesPath, 'git-repo');
+ const db = await gitDataDirDb({ dir, filterTypes: ['Environment'] });
+
+ expect(db.ApiSpec.size).toBe(0);
+ expect(db.Environment.size).toBe(2);
+ expect(db.Request.size).toBe(0);
+ expect(db.RequestGroup.size).toBe(0);
+ expect(db.Workspace.size).toBe(0);
+ });
+
+ it('should safely continue if data directory not found', async () => {
+ const dir = path.join(fixturesPath, 'git-repo-without-insomnia');
+ const db = await gitDataDirDb({ dir });
+ expect(db.ApiSpec.size).toBe(0);
+ });
+
+ it('should ignore unexpected type directories', async () => {
+ const dir = path.join(fixturesPath, 'git-repo-malformed-insomnia');
+ const db = await gitDataDirDb({ dir });
+
+ expect(db.Workspace.size).toBe(1);
+ });
+ });
+});
diff --git a/packages/insomnia-cli/src/db/mem-db.js b/packages/insomnia-cli/src/db/mem-db.js
new file mode 100644
index 0000000000..afdb8f7749
--- /dev/null
+++ b/packages/insomnia-cli/src/db/mem-db.js
@@ -0,0 +1,65 @@
+// @flow
+import fs from 'fs';
+import path from 'path';
+import YAML from 'yaml';
+import type { ApiSpec } from './types';
+
+type Database = {|
+ ApiSpec: Map,
+ Environment: Map,
+ Request: Map,
+ RequestGroup: Map,
+ Workspace: Map,
+|};
+
+export const emptyDb = (): Database => ({
+ ApiSpec: new Map(),
+ Environment: new Map(),
+ Request: new Map(),
+ RequestGroup: new Map(),
+ Workspace: new Map(),
+});
+
+type Options = {
+ dir?: string,
+ filterTypes?: Array<$Keys>,
+};
+
+export const gitDataDirDb = async ({ dir, filterTypes }: Options): Promise => {
+ const db = emptyDb();
+ const insomniaDir = path.normalize(path.join(dir || '.', '.insomnia'));
+
+ if (!fs.existsSync(insomniaDir)) {
+ // TODO: control logging with verbose flag
+ // console.log(`Directory not found: ${insomniaDir}`);
+ return db;
+ }
+
+ const readAndInsertDoc = async (type: $Keys, fileName: string): Promise => {
+ // Get contents of each file in type dir and insert into data
+ const contents = await fs.promises.readFile(fileName);
+ const obj = YAML.parse(contents.toString());
+
+ db[type].set(obj._id, obj);
+ };
+
+ const types = filterTypes?.length ? filterTypes : Object.keys(db);
+
+ await Promise.all(
+ types.map(async type => {
+ // Get all files in type dir
+ const typeDir = path.join(insomniaDir, type);
+ if (!fs.existsSync(typeDir)) {
+ return;
+ }
+
+ const files = await fs.promises.readdir(typeDir);
+ return Promise.all(
+ // Insert each file from each type
+ files.map(file => readAndInsertDoc(type, path.join(insomniaDir, type, file))),
+ );
+ }),
+ );
+
+ return db;
+};
diff --git a/packages/insomnia-cli/src/db/types.js b/packages/insomnia-cli/src/db/types.js
new file mode 100644
index 0000000000..325eb0491f
--- /dev/null
+++ b/packages/insomnia-cli/src/db/types.js
@@ -0,0 +1,23 @@
+// @flow
+
+// These types should come from a shared location (maybe insomnia-importers?)
+// They represent the models that are read from an Insomnia data source
+// eg. git data directory, insomnia export format, etc
+
+export type BaseModel = {
+ _id: string,
+ type: string,
+ parentId: string,
+ modified: number,
+ created: number,
+};
+
+type BaseApiSpec = {
+ fileName: string,
+ contentType: 'json' | 'yaml',
+ contents: string,
+};
+
+export const SpecName = 'ApiSpec';
+
+export type ApiSpec = BaseModel & BaseApiSpec;
diff --git a/packages/insomnia-cli/src/util.js b/packages/insomnia-cli/src/util.js
index 2911b712a7..37b63bc012 100644
--- a/packages/insomnia-cli/src/util.js
+++ b/packages/insomnia-cli/src/util.js
@@ -2,10 +2,13 @@
import commander from 'commander';
import * as packageJson from '../package.json';
+export type GlobalOptions = {|
+ workingDir?: string,
+ ...T,
+|};
+
export function createCommand(exitOverride: boolean, cmd?: string) {
- const command = new commander.Command(cmd)
- .storeOptionsAsProperties(false)
- .passCommandToAction(false);
+ const command = new commander.Command(cmd).storeOptionsAsProperties(false);
if (exitOverride) {
return command.exitOverride();
@@ -17,3 +20,16 @@ export function createCommand(exitOverride: boolean, cmd?: string) {
export function getVersion() {
return packageJson.version;
}
+
+export function getAllOptions(cmd: Object): T {
+ let opts = {};
+ let command = cmd;
+
+ do {
+ // overwrite options with more specific ones
+ opts = { ...command.opts(), ...opts };
+ command = command.parent;
+ } while (command);
+
+ return opts;
+}