From 67dea7d602ec01ac36b6ca5db003b9c07f162b03 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Tue, 11 Jul 2023 12:14:22 +0000 Subject: [PATCH 01/22] chore: release v4.0.0-beta.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41bbf31f..87b6a5d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.8", + "version": "4.0.0-beta.9", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git", From e4a23e2c9bc4387ab0ce3fc77aa66799289d554d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Tue, 11 Jul 2023 14:44:12 +0200 Subject: [PATCH 02/22] chore(ci/cd): attempt to wait for release asset --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3453b26b..57117b7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,6 +122,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Wait for GH assets to be downloadable + - name: Wait for assets (10s) + run: sleep 10s + shell: bash + # Update Homebrew formula to the new version # TODO: !!! Run only on stable releases - name: Update Homebrew Formula From f097b7b49984459c59b2706eb6e67915648ae166 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Tue, 11 Jul 2023 12:54:37 +0000 Subject: [PATCH 03/22] chore: release v4.0.0-beta.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87b6a5d5..74a43ca8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.9", + "version": "4.0.0-beta.10", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git", From 90d5c855d4c80de4776c3b7a519f9be09535af7c Mon Sep 17 00:00:00 2001 From: Jakub Vacek Date: Wed, 12 Jul 2023 10:42:23 +0200 Subject: [PATCH 04/22] chore: update js boiler plate (#323) --- .../application-code/js/application-code.test.ts | 10 ++++++++-- src/logic/application-code/js/application-code.ts | 11 ++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/logic/application-code/js/application-code.test.ts b/src/logic/application-code/js/application-code.test.ts index 0427132c..143cb03c 100644 --- a/src/logic/application-code/js/application-code.test.ts +++ b/src/logic/application-code/js/application-code.test.ts @@ -29,7 +29,7 @@ describe('jsApplicationCode', () => { expect(result).toEqual({ code: `import { config } from 'dotenv'; // Load OneClient from SDK -import { OneClient } from '@superfaceai/one-sdk/node/index.js'; +import { OneClient, PerformError, UnexpectedError } from '@superfaceai/one-sdk/node/index.js'; // Load environment variables from .env file config(); @@ -61,7 +61,13 @@ async function main() { console.log("RESULT:", JSON.stringify(result, null, 2)); } catch (e) { - console.log("ERROR:", JSON.stringify(e, null, 2)); + if (e instanceof PerformError) { + console.log('ERROR RESULT:', e.errorResult); + } else if (e instanceof UnexpectedError) { + console.error('ERROR:', e); + } else { + throw e; + } } } diff --git a/src/logic/application-code/js/application-code.ts b/src/logic/application-code/js/application-code.ts index ffb8df61..8db37745 100644 --- a/src/logic/application-code/js/application-code.ts +++ b/src/logic/application-code/js/application-code.ts @@ -25,7 +25,6 @@ export const jsApplicationCode: ApplicationCodeWriter = ({ parameters?: IntegrationParameter[]; security?: SecurityScheme[]; }) => { - // TODO: revisit this const pathToSdk = '@superfaceai/one-sdk/node/index.js'; const profileId = ProfileId.fromScopeName(profile.scope, profile.name).id; @@ -35,7 +34,7 @@ export const jsApplicationCode: ApplicationCodeWriter = ({ const code = `import { config } from 'dotenv'; // Load OneClient from SDK -import { OneClient } from '${pathToSdk}'; +import { OneClient, PerformError, UnexpectedError } from '${pathToSdk}'; // Load environment variables from .env file config(); @@ -67,7 +66,13 @@ async function main() { console.log("RESULT:", JSON.stringify(result, null, 2)); } catch (e) { - console.log("ERROR:", JSON.stringify(e, null, 2)); + if (e instanceof PerformError) { + console.log('ERROR RESULT:', e.errorResult); + } else if (e instanceof UnexpectedError) { + console.error('ERROR:', e); + } else { + throw e; + } } } From 9e1f6f78e2191b334d1b1d7911bb9cce0e08db81 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Wed, 12 Jul 2023 08:47:53 +0000 Subject: [PATCH 05/22] chore: release v4.0.0-beta.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74a43ca8..96fdaee4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.10", + "version": "4.0.0-beta.11", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git", From 025b3c9449289aa88fe61baf76d5319e9290ac2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Wed, 12 Jul 2023 13:44:50 +0200 Subject: [PATCH 06/22] feat(boilerplate): Using `beta` tag for JS OneSDK dependency (#325) --- src/logic/project/js/js.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/logic/project/js/js.ts b/src/logic/project/js/js.ts index f543b9f0..5fb5df3c 100644 --- a/src/logic/project/js/js.ts +++ b/src/logic/project/js/js.ts @@ -4,7 +4,8 @@ import { OutputStream } from '../../../common/output-stream'; import { SupportedLanguages } from '../../application-code'; export async function prepareJsProject( - sdkVerion = '3.0.0-alpha.12', + // https://www.npmjs.com/package/@superfaceai/one-sdk?activeTab=versions + sdkVerion = 'beta', // get latest beta using the `beta` tag dotenvVersion = '^16.0.3' ): Promise<{ saved: boolean; From 422aa7c78a4cfbf7045454f1d34c6ea568059adc Mon Sep 17 00:00:00 2001 From: Jakub Vacek Date: Wed, 12 Jul 2023 14:29:03 +0200 Subject: [PATCH 07/22] Feat/update python sdk (#312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: update python sdk * fix: use correct helpers * feat: python bolierplate * feat: execute python boilerplate * feat: error handling * fix: tests * chore: use tags * fixed(project): Python source code indentation * Revert "fixed(project): Python source code indentation" This reverts commit 3e83ce4425d07f90c46ce05955e12522d21f6be1. * fixed(project): Python source code indentation * feat(project): Python installation guide prompts for Py 3.8 * feat(project): Python OneSDK dep uses `1b` version --------- Co-authored-by: Radek Kyselý --- src/commands/execute.ts | 3 +- .../application-code/application-code.ts | 2 +- .../input/prepare-usecase-input.test.ts | 115 ++++++++++++++++++ .../input/prepare-usecase-input.ts | 15 ++- .../application-code/input/templates/array.ts | 2 +- .../input/templates/boolean.ts | 2 +- .../application-code/input/templates/input.ts | 2 +- .../input/templates/object.ts | 2 +- .../templates/template-renderer/helpers.ts | 22 ++++ .../python/application-code.test.ts | 12 +- .../python/application-code.ts | 16 ++- src/logic/execution/execute.ts | 18 ++- src/logic/project/python/python.test.ts | 4 +- src/logic/project/python/python.ts | 13 +- 14 files changed, 201 insertions(+), 27 deletions(-) create mode 100644 src/logic/application-code/input/prepare-usecase-input.test.ts diff --git a/src/commands/execute.ts b/src/commands/execute.ts index 0c4f9f17..972e9621 100644 --- a/src/commands/execute.ts +++ b/src/commands/execute.ts @@ -40,10 +40,9 @@ export default class Execute extends Command { // TODO: add language support name: 'language', description: 'Language which will use generated code. Default is `js`.', - // TODO: this will be required when we support more languages required: false, default: 'js', - options: Object.keys(SupportedLanguages), + options: Object.values(SupportedLanguages), // Hidden because we support only js for now hidden: true, }, diff --git a/src/logic/application-code/application-code.ts b/src/logic/application-code/application-code.ts index e9a27ae0..cf4e1aea 100644 --- a/src/logic/application-code/application-code.ts +++ b/src/logic/application-code/application-code.ts @@ -98,7 +98,7 @@ export async function writeApplicationCode( // TODO: this should be language independent and also take use case name as input let inputExample: string; try { - inputExample = prepareUseCaseInput(profileAst); + inputExample = prepareUseCaseInput(profileAst, language); } catch (error) { // TODO: fallback to empty object? throw userError( diff --git a/src/logic/application-code/input/prepare-usecase-input.test.ts b/src/logic/application-code/input/prepare-usecase-input.test.ts new file mode 100644 index 00000000..4851d1c6 --- /dev/null +++ b/src/logic/application-code/input/prepare-usecase-input.test.ts @@ -0,0 +1,115 @@ +import { parseProfile, Source } from '@superfaceai/parser'; + +import { SupportedLanguages } from '../application-code'; +import { prepareUseCaseInput } from './prepare-usecase-input'; + +describe('prepareUseCaseInput', () => { + const mockProfileSource = `name = "test" +version = "0.0.0" + +usecase Test safe { + + example InputExample { + input { + a = 'Luke', + b = 1.2, + c = true, + d = [1], + e = ['a', 'b'], + f = [true, false], + g = { a = 1, b = 2 }, + h = { a = 'a', b = 'b' }, + i = { a = true, b = false }, + k = { a = [{ b = [ true]}] }, + } + } +}`; + + const ast = parseProfile(new Source(mockProfileSource, 'test.supr')); + + describe('for js', () => { + it('should prepare input for use case', () => { + const input = prepareUseCaseInput(ast, SupportedLanguages.JS); + expect(input).toEqual(`{ + a : 'Luke', + b: 1.2, + c: true, + d: [ + 1, + ], + e: [ + 'a', + 'b', + ], + f: [ + true, + false, + ], + g: { + a: 1, + b: 2, + }, + h: { + a : 'a', + b : 'b', + }, + i: { + a: true, + b: false, + }, + k: { + a: [ + { + b: [ + true, + ], + }, + ], + }, + }`); + }); + }); + + describe('for python', () => { + it('should prepare input for use case', () => { + const input = prepareUseCaseInput(ast, SupportedLanguages.PYTHON); + expect(input).toEqual(`{ + "a" : 'Luke', + "b": 1.2, + "c": True, + "d": [ + 1, + ], + "e": [ + 'a', + 'b', + ], + "f": [ + True, + False, + ], + "g": { + "a": 1, + "b": 2, + }, + "h": { + "a" : 'a', + "b" : 'b', + }, + "i": { + "a": True, + "b": False, + }, + "k": { + "a": [ + { + "b": [ + True, + ], + }, + ], + }, + }`); + }); + }); +}); diff --git a/src/logic/application-code/input/prepare-usecase-input.ts b/src/logic/application-code/input/prepare-usecase-input.ts index e4531bae..50ea4694 100644 --- a/src/logic/application-code/input/prepare-usecase-input.ts +++ b/src/logic/application-code/input/prepare-usecase-input.ts @@ -5,12 +5,16 @@ import type { UseCaseDefinitionNode, } from '@superfaceai/ast'; +import type { SupportedLanguages } from '../application-code'; import { buildUseCaseExamples } from './example/build'; import type { UseCaseExample } from './example/usecase-example'; import INPUT_TEMPLATE from './templates'; import { makeRenderer } from './templates/template-renderer'; -export function prepareUseCaseInput(ast: ProfileDocumentNode): string { +export function prepareUseCaseInput( + ast: ProfileDocumentNode, + language: SupportedLanguages +): string { const namedModelDefinitionsCache: { [key: string]: NamedModelDefinitionNode; } = {}; @@ -55,9 +59,16 @@ export function prepareUseCaseInput(ast: ProfileDocumentNode): string { successExamples.push(...successExamplesForUseCase); }); + // const QUOTES_MAP: { + // [key in SupportedLanguages]: string; + // } = { + // js: '', + // python: '"', + // }; + const inputExample = successExamples.find(e => e.input !== undefined)?.input; const render = makeRenderer(INPUT_TEMPLATE, 'Input'); - return render({ input: inputExample }); + return render({ input: inputExample, language }); } diff --git a/src/logic/application-code/input/templates/array.ts b/src/logic/application-code/input/templates/array.ts index da372a31..9384191b 100644 --- a/src/logic/application-code/input/templates/array.ts +++ b/src/logic/application-code/input/templates/array.ts @@ -1 +1 @@ -export default '[{{#each items}}{{newLine (inc ../indent 2) }}{{#ifeq kind "string"}}{{>String }},{{/ifeq}}{{#ifeq kind "number"}}{{>Number }},{{/ifeq}}{{#ifeq kind "boolean"}}{{>Boolean }},{{/ifeq}}{{#ifeq kind "object"}}{{>Object use=":" indent=(inc ../indent 2) }},{{/ifeq}}{{#ifeq kind "array"}}{{>Array use=":" indent= (inc ../indent 2) }},{{/ifeq}}{{/each}}{{newLine indent}}]'; +export default '[{{#each items}}{{newLine (inc ../indent 2) }}{{#ifeq kind "string"}}{{>String }},{{/ifeq}}{{#ifeq kind "number"}}{{>Number }},{{/ifeq}}{{#ifeq kind "boolean"}}{{>Boolean language=../language }},{{/ifeq}}{{#ifeq kind "object"}}{{>Object use=":" indent=(inc ../indent 2) language=../language }},{{/ifeq}}{{#ifeq kind "array"}}{{>Array use=":" indent= (inc ../indent 2) language=../language }},{{/ifeq}}{{/each}}{{newLine indent}}]'; diff --git a/src/logic/application-code/input/templates/boolean.ts b/src/logic/application-code/input/templates/boolean.ts index 8630650f..110f902d 100644 --- a/src/logic/application-code/input/templates/boolean.ts +++ b/src/logic/application-code/input/templates/boolean.ts @@ -1 +1 @@ -export default '{{value}}'; +export default '{{booleanValue language value}}'; diff --git a/src/logic/application-code/input/templates/input.ts b/src/logic/application-code/input/templates/input.ts index 6fd2e3c7..d0f8b419 100644 --- a/src/logic/application-code/input/templates/input.ts +++ b/src/logic/application-code/input/templates/input.ts @@ -1 +1 @@ -export default '{{#if input}}{{#ifeq input.kind "object"}}{{>Object input use=":" indent=6}}{{/ifeq}}{{#ifeq input.kind "array"}}{{>Array input use=":" indent=6}}{{/ifeq}}{{/if}}'; +export default '{{#if input}}{{#ifeq input.kind "object"}}{{>Object input use=":" indent=6 language=language}}{{/ifeq}}{{#ifeq input.kind "array"}}{{>Array input use=":" indent=6 language=language}}{{/ifeq}}{{/if}}'; diff --git a/src/logic/application-code/input/templates/object.ts b/src/logic/application-code/input/templates/object.ts index b8539acb..bd6362b4 100644 --- a/src/logic/application-code/input/templates/object.ts +++ b/src/logic/application-code/input/templates/object.ts @@ -1 +1 @@ -export default '{{openObject}}{{#each properties}}{{#ifeq kind "string"}}{{newLine (inc ../indent 2) }}{{name}} {{../use}} {{>String }},{{/ifeq}}{{#ifeq kind "number"}}{{newLine (inc ../indent 2) }}{{name}}{{../use}} {{>Number }},{{/ifeq}}{{#ifeq kind "boolean"}}{{newLine (inc ../indent 2) }}{{name}}{{../use}} {{>Boolean }},{{/ifeq}}{{#ifeq kind "object"}}{{newLine (inc ../indent 2) }}{{name}}{{../use}} {{>Object use=":" indent= (inc ../indent 2) }},{{/ifeq}}{{#ifeq kind "array"}}{{newLine (inc ../indent 2) }}{{name}}{{../use}} {{>Array use=":" indent= (inc ../indent 2) }},{{/ifeq}}{{/each}}{{newLine indent}}{{closeObject}}'; +export default '{{openObject}}{{#each properties}}{{#ifeq kind "string"}}{{newLine (inc ../indent 2) }}{{quotes ../language}}{{name}}{{quotes ../language}} {{../use}} {{>String }},{{/ifeq}}{{#ifeq kind "number"}}{{newLine (inc ../indent 2) }}{{quotes ../language}}{{name}}{{quotes ../language}}{{../use}} {{>Number }},{{/ifeq}}{{#ifeq kind "boolean"}}{{newLine (inc ../indent 2) }}{{quotes ../language}}{{name}}{{quotes ../language}}{{../use}} {{>Boolean language=../language }},{{/ifeq}}{{#ifeq kind "object"}}{{newLine (inc ../indent 2) }}{{quotes ../language}}{{name}}{{quotes ../language}}{{../use}} {{>Object use=":" indent= (inc ../indent 2) language=../language }},{{/ifeq}}{{#ifeq kind "array"}}{{newLine (inc ../indent 2) }}{{quotes ../language}}{{name}}{{quotes ../language}}{{../use}} {{>Array use=":" indent= (inc ../indent 2) language=../language}},{{/ifeq}}{{/each}}{{newLine indent}}{{closeObject}}'; diff --git a/src/logic/application-code/input/templates/template-renderer/helpers.ts b/src/logic/application-code/input/templates/template-renderer/helpers.ts index e39f852b..39076cc8 100644 --- a/src/logic/application-code/input/templates/template-renderer/helpers.ts +++ b/src/logic/application-code/input/templates/template-renderer/helpers.ts @@ -1,4 +1,7 @@ /* eslint-disable */ + +import { SupportedLanguages } from '../../../application-code'; + //TODO: add types export const HELPERS = [ { @@ -86,6 +89,25 @@ export const HELPERS = [ return parseInt(value) + amount; }, }, + { + name: 'quotes', + helper: function (language: string) { + if (language === SupportedLanguages.PYTHON) { + return `"`; + } + return ''; + }, + }, + + { + name: 'booleanValue', + helper: function (language: string, value: boolean) { + if (language === SupportedLanguages.PYTHON) { + return value ? 'True' : 'False'; + } + return value; + }, + }, { name: 'openObject', diff --git a/src/logic/application-code/python/application-code.test.ts b/src/logic/application-code/python/application-code.test.ts index 242f9424..c6b23807 100644 --- a/src/logic/application-code/python/application-code.test.ts +++ b/src/logic/application-code/python/application-code.test.ts @@ -29,7 +29,8 @@ describe('pythonApplicationCode', () => { expect(result).toEqual({ code: `import os from dotenv import load_dotenv -from superfaceai.one_sdk import OneClient +import sys +from one_sdk import OneClient, PerformError, UnexpectedError load_dotenv() @@ -51,7 +52,14 @@ try: ) print(f"RESULT: {result}") except Exception as e: - print(f"ERROR: {e}")`, + if isinstance(e, PerformError): + print(f"ERROR RESULT: {e.error_result}") + elif isinstance(e, UnexpectedError): + print(f"ERROR:", e, file=sys.stderr) + else: + raise e +finally: + client.send_metrics_to_superface()`, requiredParameters: [], requiredSecurity: [], }); diff --git a/src/logic/application-code/python/application-code.ts b/src/logic/application-code/python/application-code.ts index 9e0b2254..3539d007 100644 --- a/src/logic/application-code/python/application-code.ts +++ b/src/logic/application-code/python/application-code.ts @@ -3,8 +3,8 @@ import type { IntegrationParameter, SecurityScheme } from '@superfaceai/ast'; import { buildSuperfaceDirPath } from '../../../common/file-structure'; import { ProfileId } from '../../../common/profile'; import type { ApplicationCodeWriter } from '../application-code'; -import { prepareParameters } from '../js/parameters'; -import { prepareSecurity } from '../js/security'; +import { prepareParameters } from './parameters'; +import { prepareSecurity } from './security'; export const pythonApplicationCode: ApplicationCodeWriter = ({ profile, @@ -31,7 +31,8 @@ export const pythonApplicationCode: ApplicationCodeWriter = ({ const code = `import os from dotenv import load_dotenv -from superfaceai.one_sdk import OneClient +import sys +from one_sdk import OneClient, PerformError, UnexpectedError load_dotenv() @@ -53,7 +54,14 @@ try: ) print(f"RESULT: {result}") except Exception as e: - print(f"ERROR: {e}")`; + if isinstance(e, PerformError): + print(f"ERROR RESULT: {e.error_result}") + elif isinstance(e, UnexpectedError): + print(f"ERROR:", e, file=sys.stderr) + else: + raise e +finally: + client.send_metrics_to_superface()`; return { code, diff --git a/src/logic/execution/execute.ts b/src/logic/execution/execute.ts index c73b2a62..84c67c3f 100644 --- a/src/logic/execution/execute.ts +++ b/src/logic/execution/execute.ts @@ -29,10 +29,20 @@ export async function execute( function prepareCommand( file: string, - _language: SupportedLanguages + language: SupportedLanguages ): { command: string; args: string[] } { - return { - command: 'node', - args: ['--experimental-wasi-unstable-preview1', file], + const COMMAND_MAP: { + [key in SupportedLanguages]: { command: string; args: string[] }; + } = { + js: { + command: 'node', + args: ['--experimental-wasi-unstable-preview1', file], + }, + python: { + command: 'python3', + args: [file], + }, }; + + return COMMAND_MAP[language]; } diff --git a/src/logic/project/python/python.test.ts b/src/logic/project/python/python.test.ts index 841fe1ce..eb5d8812 100644 --- a/src/logic/project/python/python.test.ts +++ b/src/logic/project/python/python.test.ts @@ -30,7 +30,7 @@ describe('preparePythonProject', () => { it('creates package.json if it does not exist', async () => { jest.mocked(exists).mockResolvedValueOnce(false); - await expect(preparePythonProject('3.0.0-alpha.12')).resolves.toEqual({ + await expect(preparePythonProject('1.0.0b1')).resolves.toEqual({ saved: true, installationGuide: expect.any(String), path: expect.stringContaining('superface/requirements.txt'), @@ -45,7 +45,7 @@ describe('preparePythonProject', () => { it('does not create package.json if it exists', async () => { jest.mocked(exists).mockResolvedValueOnce(true); - await expect(preparePythonProject('3.0.0-alpha.12')).resolves.toEqual({ + await expect(preparePythonProject('1.0.0b1')).resolves.toEqual({ saved: false, installationGuide: expect.any(String), path: expect.stringContaining('superface/requirements.txt'), diff --git a/src/logic/project/python/python.ts b/src/logic/project/python/python.ts index 8bb2d37d..56791c65 100644 --- a/src/logic/project/python/python.ts +++ b/src/logic/project/python/python.ts @@ -4,26 +4,27 @@ import { OutputStream } from '../../../common/output-stream'; import { SupportedLanguages } from '../../application-code'; export async function preparePythonProject( - sdkVerion = '3.0.0-alpha.12' + sdkVersion = '1b' // beta on major 1 ): Promise<{ saved: boolean; installationGuide: string; path: string; }> { - // TODO: revisit when SDK supports python - const requirements = `Brotli==1.0.9 + const requirements = ` +one-sdk>=${sdkVersion} +python-dotenv==1.0.0 +Brotli==1.0.9 certifi==2023.5.7 charset-normalizer==3.1.0 -@superfaceai/one-sdk==${sdkVerion} idna==3.4 urllib3==2.0.3 -wasmtime==9.0.0`; +wasmtime==10.0.0`; const requirementsPath = buildProjectDefinitionFilePath( SupportedLanguages.PYTHON ); - const installationGuide = `You need to have Python version 3.11 or higher installed to run the integration. You can check used dependencies in: ${requirementsPath}\nYou can install defined dependencies by running \`python3 -m pip install -r requirements.txt\` in \`superface\` directory.`; + const installationGuide = `You need to have Python version 3.8 or higher installed to run the integration. You can check used dependencies in: ${requirementsPath}\nYou can install defined dependencies by running \`python3 -m pip install -r requirements.txt\` in \`superface\` directory.`; if (!(await exists(requirementsPath))) { await OutputStream.writeOnce(requirementsPath, requirements); From b9dc8e728b90f2d5dcdabab43ac0aa57d077de83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Wed, 12 Jul 2023 14:31:30 +0200 Subject: [PATCH 08/22] chore(project): Fix typo --- src/logic/project/js/js.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/project/js/js.ts b/src/logic/project/js/js.ts index 5fb5df3c..2dc266d3 100644 --- a/src/logic/project/js/js.ts +++ b/src/logic/project/js/js.ts @@ -5,7 +5,7 @@ import { SupportedLanguages } from '../../application-code'; export async function prepareJsProject( // https://www.npmjs.com/package/@superfaceai/one-sdk?activeTab=versions - sdkVerion = 'beta', // get latest beta using the `beta` tag + sdkVersion = 'beta', // get latest beta using the `beta` tag dotenvVersion = '^16.0.3' ): Promise<{ saved: boolean; @@ -24,7 +24,7 @@ export async function prepareJsProject( "author": "", "license": "ISC", "dependencies": { - "@superfaceai/one-sdk": "${sdkVerion}", + "@superfaceai/one-sdk": "${sdkVersion}", "dotenv": "${dotenvVersion}" } }`; From 4328a01bf660d9ac188c0070fbd71ee08a733f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Thu, 13 Jul 2023 08:42:09 +0200 Subject: [PATCH 09/22] feat: Boilerplate code inits `.env` file (#326) --- src/commands/map.test.ts | 17 +- src/commands/map.ts | 48 ++++-- src/common/file-structure.test.ts | 9 ++ src/common/file-structure.ts | 4 + .../application-code/dotenv/dotenv.test.ts | 151 ++++++++++++++++++ src/logic/application-code/dotenv/dotenv.ts | 112 +++++++++++++ src/logic/application-code/dotenv/index.ts | 1 + src/logic/application-code/index.ts | 1 + 8 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 src/logic/application-code/dotenv/dotenv.test.ts create mode 100644 src/logic/application-code/dotenv/dotenv.ts create mode 100644 src/logic/application-code/dotenv/index.ts diff --git a/src/commands/map.test.ts b/src/commands/map.test.ts index 59943f27..c2439022 100644 --- a/src/commands/map.test.ts +++ b/src/commands/map.test.ts @@ -5,10 +5,12 @@ import { createUserError } from '../common/error'; import { exists, readFile } from '../common/io'; import { OutputStream } from '../common/output-stream'; import { UX } from '../common/ux'; +import type { NewDotenv } from '../logic'; import { + createNewDotenv, SupportedLanguages, writeApplicationCode, -} from '../logic/application-code/application-code'; +} from '../logic/application-code'; import { mapProviderToProfile } from '../logic/map'; import { prepareProject } from '../logic/project'; import { mockProviderJson } from '../test/provider-json'; @@ -19,6 +21,7 @@ jest.mock('../common/io'); jest.mock('../common/output-stream'); jest.mock('../logic/map'); jest.mock('../logic/application-code/application-code'); +jest.mock('../logic/application-code/dotenv'); jest.mock('../logic/project'); describe('MapCLI command', () => { @@ -44,6 +47,10 @@ describe('MapCLI command', () => { requiredParameters: ['TEST_PARAMETER'], requiredSecurity: ['TEST_SECURITY'], }; + const mockDotenv: NewDotenv = { + content: 'TEST_PARAMETER=\nTEST_SECURITY=', + addedEnvVariables: ['TEST_PARAMETER', 'TEST_SECURITY'], + }; const providerJson = mockProviderJson({ name: providerName }); const userError = createUserError(false); const ux = UX.create(); @@ -255,6 +262,8 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); + jest.mocked(mapProviderToProfile).mockResolvedValueOnce(mapSource); await instance.execute({ @@ -310,6 +319,8 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); + jest.mocked(mapProviderToProfile).mockResolvedValueOnce(mapSource); await instance.execute({ @@ -387,6 +398,8 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); + await instance.execute({ logger, userError, @@ -460,6 +473,8 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); + await instance.execute({ logger, userError, diff --git a/src/commands/map.ts b/src/commands/map.ts index 19c7a5e6..78ba2db8 100644 --- a/src/commands/map.ts +++ b/src/commands/map.ts @@ -8,15 +8,17 @@ import { stringifyError } from '../common/error'; import { buildMapPath, buildProfilePath, + buildProjectDotenvFilePath, buildRunFilePath, } from '../common/file-structure'; import { SuperfaceClient } from '../common/http'; -import { exists, readFile } from '../common/io'; +import { exists, readFile, readFileQuiet } from '../common/io'; import type { ILogger } from '../common/log'; import { OutputStream } from '../common/output-stream'; import { ProfileId } from '../common/profile'; import { resolveProviderJson } from '../common/provider'; import { UX } from '../common/ux'; +import { createNewDotenv } from '../logic'; import { getLanguageName, SupportedLanguages, @@ -132,9 +134,11 @@ export default class Map extends Command { )} already exists at ${boilerplate.path}.` ); - if (boilerplate.envVariables !== undefined) { + const dotenv = await saveDotenv(resolvedProviderJson.providerJson); + + if (dotenv.newEnvVariables.length > 0) { ux.warn( - `Please set the following environment variables before running the integration:\n${boilerplate.envVariables}` + `${dotenv.newEnvVariables.length} new environment variables were added to ${dotenv.dotenvPath}. Please set their values before running the integration` ); } @@ -190,7 +194,7 @@ async function saveBoilerplateCode( profileAst: ProfileDocumentNode, language: SupportedLanguages, { userError, logger }: { userError: UserError; logger: ILogger } -): Promise<{ saved: boolean; path: string; envVariables: string | undefined }> { +): Promise<{ saved: boolean; path: string }> { const path = buildRunFilePath({ profileName: profileAst.header.name, providerName: providerJson.name, @@ -202,7 +206,6 @@ async function saveBoilerplateCode( return { saved: false, path, - envVariables: undefined, }; } @@ -218,22 +221,35 @@ async function saveBoilerplateCode( } ); - let envVariables: string | undefined; - if (code.requiredParameters.length > 0 || code.requiredSecurity.length > 0) { - envVariables = code.requiredParameters - .map(p => `Integration parameter ${p}`) - .join('\n'); - envVariables += - '\n' + - code.requiredSecurity.map(s => `Security variable ${s}`).join('\n'); - } - await OutputStream.writeOnce(path, code.code); return { saved: true, path, - envVariables, + }; +} + +async function saveDotenv( + providerJson: ProviderJson +): Promise<{ dotenvPath: string; newEnvVariables: string[] }> { + const dotenvPath = buildProjectDotenvFilePath(); + + const existingDotenv = await readFileQuiet(dotenvPath); + + const newDotenv = createNewDotenv({ + previousDotenv: existingDotenv, + providerName: providerJson.name, + parameters: providerJson.parameters, + security: providerJson.securitySchemes, + }); + + if (newDotenv.content) { + await OutputStream.writeOnce(dotenvPath, newDotenv.content); + } + + return { + dotenvPath, + newEnvVariables: newDotenv.addedEnvVariables, }; } diff --git a/src/common/file-structure.test.ts b/src/common/file-structure.test.ts index 61bcd303..2c042a59 100644 --- a/src/common/file-structure.test.ts +++ b/src/common/file-structure.test.ts @@ -3,6 +3,7 @@ import { buildMapPath, buildProfilePath, buildProjectDefinitionFilePath, + buildProjectDotenvFilePath, buildProviderPath, buildRunFilePath, buildSuperfaceDirPath, @@ -122,4 +123,12 @@ describe('fileStructure', () => { ); }); }); + + describe('buildProjectDotenvFilePath', () => { + it('builds project .env file path', () => { + expect(buildProjectDotenvFilePath()).toEqual( + expect.stringContaining(`/superface/.env`) + ); + }); + }); }); diff --git a/src/common/file-structure.ts b/src/common/file-structure.ts index f867fad9..36ec53c4 100644 --- a/src/common/file-structure.ts +++ b/src/common/file-structure.ts @@ -89,3 +89,7 @@ export function buildProjectDefinitionFilePath( return join(buildSuperfaceDirPath(), FILENAME_MAP[language]); } + +export function buildProjectDotenvFilePath(): string { + return join(buildSuperfaceDirPath(), '.env'); +} diff --git a/src/logic/application-code/dotenv/dotenv.test.ts b/src/logic/application-code/dotenv/dotenv.test.ts new file mode 100644 index 00000000..aba1b60f --- /dev/null +++ b/src/logic/application-code/dotenv/dotenv.test.ts @@ -0,0 +1,151 @@ +import type { IntegrationParameter, SecurityScheme } from '@superfaceai/ast'; +import { HttpScheme, SecurityType } from '@superfaceai/ast'; + +import { createNewDotenv } from './dotenv'; + +const PROVIDER_NAME = 'my-provider'; +const PARAMETER: IntegrationParameter = { + name: 'param-one', + description: 'Parameter description', +}; +const PARAMETER_WITH_DEFAULT: IntegrationParameter = { + name: 'param-two', + default: 'us-west-1', + description: 'Deployment zone\nfor AWS', +}; +const BASIC_AUTH: SecurityScheme = { + id: 'basic_auth', + type: SecurityType.HTTP, + scheme: HttpScheme.BASIC, +}; +const BEARER_AUTH: SecurityScheme = { + id: 'bearer_auth', + type: SecurityType.HTTP, + scheme: HttpScheme.BEARER, +}; + +const EXISTING_DOTENV = `# Deployment zone +# for AWS +MY_PROVIDER_PARAM_TWO=us-west-1 +MY_PROVIDER_TOKEN= +`; + +describe('createNewDotenv', () => { + describe('when there is no previous .env', () => { + it('creates valid .env when no parameters or security schemes are given', () => { + const result = createNewDotenv({ providerName: PROVIDER_NAME }); + + expect(result).toStrictEqual({ + content: '', + addedEnvVariables: [], + }); + }); + + it('creates valid .env when 2 parameters but no security schemes are given', () => { + const result = createNewDotenv({ + providerName: PROVIDER_NAME, + parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], + }); + + expect(result).toStrictEqual({ + content: `# Parameter description +MY_PROVIDER_PARAM_ONE= + +# Deployment zone +# for AWS +MY_PROVIDER_PARAM_TWO=us-west-1 +`, + addedEnvVariables: ['MY_PROVIDER_PARAM_ONE', 'MY_PROVIDER_PARAM_TWO'], + }); + }); + + it('creates valid .env when 2 parameters and 2 security schemes are given', () => { + const result = createNewDotenv({ + providerName: PROVIDER_NAME, + parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], + security: [BASIC_AUTH, BEARER_AUTH], + }); + + expect(result).toStrictEqual({ + content: `# Parameter description +MY_PROVIDER_PARAM_ONE= + +# Deployment zone +# for AWS +MY_PROVIDER_PARAM_TWO=us-west-1 +MY_PROVIDER_USERNAME= +MY_PROVIDER_PASSWORD= +MY_PROVIDER_TOKEN= +`, + addedEnvVariables: [ + 'MY_PROVIDER_PARAM_ONE', + 'MY_PROVIDER_PARAM_TWO', + 'MY_PROVIDER_USERNAME', + 'MY_PROVIDER_PASSWORD', + 'MY_PROVIDER_TOKEN', + ], + }); + }); + }); + + describe('when there is a previous existing .env', () => { + it('creates valid .env when no parameters or security schemes are given', () => { + const result = createNewDotenv({ + previousDotenv: EXISTING_DOTENV, + providerName: PROVIDER_NAME, + }); + + expect(result).toStrictEqual({ + content: EXISTING_DOTENV, + addedEnvVariables: [], + }); + }); + + it('creates valid .env when 2 parameters but no security schemes are given', () => { + const result = createNewDotenv({ + previousDotenv: EXISTING_DOTENV, + providerName: PROVIDER_NAME, + parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], + }); + + expect(result).toStrictEqual({ + content: `# Deployment zone +# for AWS +MY_PROVIDER_PARAM_TWO=us-west-1 +MY_PROVIDER_TOKEN= + +# Parameter description +MY_PROVIDER_PARAM_ONE= +`, + addedEnvVariables: ['MY_PROVIDER_PARAM_ONE'], + }); + }); + + it('creates valid .env when 2 parameters and 2 security schemes are given', () => { + const result = createNewDotenv({ + previousDotenv: EXISTING_DOTENV, + providerName: PROVIDER_NAME, + parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], + security: [BASIC_AUTH, BEARER_AUTH], + }); + + expect(result).toStrictEqual({ + content: `# Deployment zone +# for AWS +MY_PROVIDER_PARAM_TWO=us-west-1 +MY_PROVIDER_TOKEN= + +# Parameter description +MY_PROVIDER_PARAM_ONE= +MY_PROVIDER_USERNAME= +MY_PROVIDER_PASSWORD= +`, + addedEnvVariables: [ + 'MY_PROVIDER_PARAM_ONE', + 'MY_PROVIDER_USERNAME', + 'MY_PROVIDER_PASSWORD', + ], + }); + }); + }); +}); diff --git a/src/logic/application-code/dotenv/dotenv.ts b/src/logic/application-code/dotenv/dotenv.ts new file mode 100644 index 00000000..a8cf8bff --- /dev/null +++ b/src/logic/application-code/dotenv/dotenv.ts @@ -0,0 +1,112 @@ +import type { IntegrationParameter, SecurityScheme } from '@superfaceai/ast'; +import { + prepareProviderParameters, + prepareSecurityValues, +} from '@superfaceai/ast'; + +export type NewDotenv = { + content: string; + addedEnvVariables: string[]; +}; + +type EnvVar = { + name: string; + value: string | undefined; + comment: string | undefined; +}; + +export function createNewDotenv({ + previousDotenv, + providerName, + parameters, + security, +}: { + previousDotenv?: string; + providerName: string; + parameters?: IntegrationParameter[]; + security?: SecurityScheme[]; +}): NewDotenv { + const previousContent = previousDotenv ?? ''; + + const parameterEnvs = getParameterEnvs(providerName, parameters); + const securityEnvs = getSecurityEnvs(providerName, security); + const allProviderEnvVariables = [...parameterEnvs, ...securityEnvs]; + + const newEnvsOnly = makeFilterForNewEnvs(previousContent); + + const newEnvVariables = allProviderEnvVariables.filter(newEnvsOnly); + + return { + content: serializeContent(previousContent, newEnvVariables), + addedEnvVariables: newEnvVariables.map(e => e.name), + }; +} + +function makeFilterForNewEnvs(content: string): (e: EnvVar) => boolean { + const existingEnvs = new Set( + content + .split('\n') + .map(line => line.match(/^(\w+)=/)?.[1]) + .filter((s: string | undefined): s is string => Boolean(s)) + .map(t => t.toLowerCase()) + ); + + // returns true for envs that are NOT present in the `content` + return env => { + return !existingEnvs.has(env.name.toLowerCase()); + }; +} + +function serializeContent(previousContent: string, newEnvs: EnvVar[]): string { + const newEnvContent = newEnvs.map(serializeEnvVar).join('\n').trim(); + + const newContent = [previousContent, newEnvContent] + .filter(Boolean) + .join('\n'); + + return newEnvContent ? newContent + '\n' : newContent; +} + +function serializeEnvVar(env: EnvVar): string { + const comment = + env.comment !== undefined + ? '\n' + + env.comment + .split('\n') + .map(commentLine => `# ${commentLine}`) + .join('\n') + : ''; + + return `${comment ? comment + '\n' : ''}${env.name}=${env.value ?? ''}`; +} + +function getParameterEnvs( + providerName: string, + parameters?: IntegrationParameter[] +): EnvVar[] { + const params = parameters || []; + + const parameterEnvs = prepareProviderParameters(providerName, params); + + return params.map(param => ({ + name: removeDollarSign(parameterEnvs[param.name]), + value: param.default ?? undefined, + comment: param.description ?? undefined, + })); +} + +function getSecurityEnvs( + providerName: string, + security?: SecurityScheme[] +): EnvVar[] { + const securityValues = prepareSecurityValues(providerName, security || []); + + return securityValues + .map(({ id: _, ...securityValue }) => securityValue) + .flatMap(securityValue => Object.values(securityValue) as string[]) + .map(removeDollarSign) + .map(name => ({ name, value: undefined, comment: undefined })); +} + +const removeDollarSign = (text: string): string => + text.startsWith('$') ? text.slice(1) : text; diff --git a/src/logic/application-code/dotenv/index.ts b/src/logic/application-code/dotenv/index.ts new file mode 100644 index 00000000..a5d5c0c3 --- /dev/null +++ b/src/logic/application-code/dotenv/index.ts @@ -0,0 +1 @@ +export * from './dotenv' \ No newline at end of file diff --git a/src/logic/application-code/index.ts b/src/logic/application-code/index.ts index 2136386c..f8062870 100644 --- a/src/logic/application-code/index.ts +++ b/src/logic/application-code/index.ts @@ -1 +1,2 @@ export * from './application-code'; +export * from './dotenv'; From b076b2df6b4673459b777b1b189036efb46c98fa Mon Sep 17 00:00:00 2001 From: Ondrej Musil Date: Thu, 13 Jul 2023 11:04:51 +0200 Subject: [PATCH 10/22] fix: js boilerplate doesn't need main main function (#328) --- .../js/application-code.test.ts | 63 +++++++++---------- .../application-code/js/application-code.ts | 63 +++++++++---------- 2 files changed, 60 insertions(+), 66 deletions(-) diff --git a/src/logic/application-code/js/application-code.test.ts b/src/logic/application-code/js/application-code.test.ts index 143cb03c..40a3f7f8 100644 --- a/src/logic/application-code/js/application-code.test.ts +++ b/src/logic/application-code/js/application-code.test.ts @@ -33,45 +33,42 @@ import { OneClient, PerformError, UnexpectedError } from '@superfaceai/one-sdk/n // Load environment variables from .env file config(); -async function main() { - const client = new OneClient({ - // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - // token: - // Specify path to assets folder - assetsPath: '${buildSuperfaceDirPath()}' - }); - - // Load profile and use case - const profile = await client.getProfile('${scope}/${name}'); - const useCase = profile.getUseCase('${useCaseName}') - try { - // Execute use case - const result = await useCase.perform( - // Use case input - {}, - { - provider: '${provider}', - parameters: {}, - // Security values for provider - security: {} - } - ); +const client = new OneClient({ + // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app + // token: + // Specify path to assets folder + assetsPath: '${buildSuperfaceDirPath()}' +}); - console.log("RESULT:", JSON.stringify(result, null, 2)); +// Load profile and use case +const profile = await client.getProfile('${scope}/${name}'); +const useCase = profile.getUseCase('${useCaseName}') - } catch (e) { - if (e instanceof PerformError) { - console.log('ERROR RESULT:', e.errorResult); - } else if (e instanceof UnexpectedError) { - console.error('ERROR:', e); - } else { - throw e; +try { + // Execute use case + const result = await useCase.perform( + // Use case input + {}, + { + provider: '${provider}', + parameters: {}, + // Security values for provider + security: {} } + ); + + console.log("RESULT:", JSON.stringify(result, null, 2)); +} catch (e) { + if (e instanceof PerformError) { + console.log('ERROR RESULT:', e.errorResult); + } else if (e instanceof UnexpectedError) { + console.error('ERROR:', e); + } else { + throw e; } } - -void main();`, +`, requiredParameters: [], requiredSecurity: [], }); diff --git a/src/logic/application-code/js/application-code.ts b/src/logic/application-code/js/application-code.ts index 8db37745..3a10b924 100644 --- a/src/logic/application-code/js/application-code.ts +++ b/src/logic/application-code/js/application-code.ts @@ -38,45 +38,42 @@ import { OneClient, PerformError, UnexpectedError } from '${pathToSdk}'; // Load environment variables from .env file config(); -async function main() { - const client = new OneClient({ - // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - // token: - // Specify path to assets folder - assetsPath: '${buildSuperfaceDirPath()}' - }); - // Load profile and use case - const profile = await client.getProfile('${profileId}'); - const useCase = profile.getUseCase('${useCaseName}') +const client = new OneClient({ + // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app + // token: + // Specify path to assets folder + assetsPath: '${buildSuperfaceDirPath()}' +}); - try { - // Execute use case - const result = await useCase.perform( - // Use case input - ${input}, - { - provider: '${provider}', - parameters: ${preparedParameters.parametersString}, - // Security values for provider - security: ${preparedSecurity.securityString} - } - ); +// Load profile and use case +const profile = await client.getProfile('${profileId}'); +const useCase = profile.getUseCase('${useCaseName}') - console.log("RESULT:", JSON.stringify(result, null, 2)); - - } catch (e) { - if (e instanceof PerformError) { - console.log('ERROR RESULT:', e.errorResult); - } else if (e instanceof UnexpectedError) { - console.error('ERROR:', e); - } else { - throw e; +try { + // Execute use case + const result = await useCase.perform( + // Use case input + ${input}, + { + provider: '${provider}', + parameters: ${preparedParameters.parametersString}, + // Security values for provider + security: ${preparedSecurity.securityString} } + ); + + console.log("RESULT:", JSON.stringify(result, null, 2)); +} catch (e) { + if (e instanceof PerformError) { + console.log('ERROR RESULT:', e.errorResult); + } else if (e instanceof UnexpectedError) { + console.error('ERROR:', e); + } else { + throw e; } } - -void main();`; +`; return { code, From c0a0f1c4506451a6e5dcf21d12b662d5afb03111 Mon Sep 17 00:00:00 2001 From: Ondrej Musil Date: Thu, 13 Jul 2023 12:10:27 +0200 Subject: [PATCH 11/22] feat/mute_nodejs_warnings (#329) --- src/logic/execution/execute.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/execution/execute.ts b/src/logic/execution/execute.ts index 84c67c3f..ddecf0af 100644 --- a/src/logic/execution/execute.ts +++ b/src/logic/execution/execute.ts @@ -36,7 +36,7 @@ function prepareCommand( } = { js: { command: 'node', - args: ['--experimental-wasi-unstable-preview1', file], + args: ['--no-warnings', '--experimental-wasi-unstable-preview1', file], }, python: { command: 'python3', From e600e701b5adac41286c03525487114bafd305aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Thu, 13 Jul 2023 12:47:37 +0200 Subject: [PATCH 12/22] feat: Use OneSDK token in the boilerplate code (#327) * feat(http): `fetchSDKToken` for obtaining default token * feat(boilerplate): Adding OneSDK token constants * feat(boilerplate): Dotenv utility takes optional token * feat(boilerplate): JS code uses token env * feat(boilerplate): Python code uses token env * feat(commands): Map commands fetches and passes token * chore(boilerplate): Python code test uses direct text * chore(boilerplate): Fixing typo in SDK comment * fix(boilerplate): Python code was missing comma --- src/commands/map.test.ts | 7 ++ src/commands/map.ts | 4 +- src/common/http.test.ts | 117 ++++++++++++++++++ src/common/http.ts | 19 +++ .../application-code/dotenv/dotenv.test.ts | 53 ++++++-- src/logic/application-code/dotenv/dotenv.ts | 25 +++- src/logic/application-code/dotenv/index.ts | 3 +- .../application-code/dotenv/onesdk-token.ts | 3 + .../js/application-code.test.ts | 4 +- .../application-code/js/application-code.ts | 5 +- .../python/application-code.test.ts | 4 +- .../python/application-code.ts | 5 +- 12 files changed, 227 insertions(+), 22 deletions(-) create mode 100644 src/logic/application-code/dotenv/onesdk-token.ts diff --git a/src/commands/map.test.ts b/src/commands/map.test.ts index c2439022..6c4ac1e8 100644 --- a/src/commands/map.test.ts +++ b/src/commands/map.test.ts @@ -2,6 +2,7 @@ import { parseProfile, Source } from '@superfaceai/parser'; import { MockLogger } from '../common'; import { createUserError } from '../common/error'; +import { fetchSDKToken } from '../common/http'; import { exists, readFile } from '../common/io'; import { OutputStream } from '../common/output-stream'; import { UX } from '../common/ux'; @@ -19,6 +20,7 @@ import Map from './map'; jest.mock('../common/io'); jest.mock('../common/output-stream'); +jest.mock('../common/http'); jest.mock('../logic/map'); jest.mock('../logic/application-code/application-code'); jest.mock('../logic/application-code/dotenv'); @@ -51,6 +53,7 @@ describe('MapCLI command', () => { content: 'TEST_PARAMETER=\nTEST_SECURITY=', addedEnvVariables: ['TEST_PARAMETER', 'TEST_SECURITY'], }; + const mockToken = { token: 'sfs_b31314b7fc8...8ec1930e' }; const providerJson = mockProviderJson({ name: providerName }); const userError = createUserError(false); const ux = UX.create(); @@ -262,6 +265,7 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(fetchSDKToken).mockResolvedValueOnce(mockToken); jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); jest.mocked(mapProviderToProfile).mockResolvedValueOnce(mapSource); @@ -319,6 +323,7 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(fetchSDKToken).mockResolvedValueOnce(mockToken); jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); jest.mocked(mapProviderToProfile).mockResolvedValueOnce(mapSource); @@ -398,6 +403,7 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(fetchSDKToken).mockResolvedValueOnce(mockToken); jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); await instance.execute({ @@ -473,6 +479,7 @@ describe('MapCLI command', () => { .mocked(writeApplicationCode) .mockResolvedValueOnce(mockApplicationCode); + jest.mocked(fetchSDKToken).mockResolvedValueOnce(mockToken); jest.mocked(createNewDotenv).mockReturnValueOnce(mockDotenv); await instance.execute({ diff --git a/src/commands/map.ts b/src/commands/map.ts index 78ba2db8..f2b80522 100644 --- a/src/commands/map.ts +++ b/src/commands/map.ts @@ -11,7 +11,7 @@ import { buildProjectDotenvFilePath, buildRunFilePath, } from '../common/file-structure'; -import { SuperfaceClient } from '../common/http'; +import { fetchSDKToken, SuperfaceClient } from '../common/http'; import { exists, readFile, readFileQuiet } from '../common/io'; import type { ILogger } from '../common/log'; import { OutputStream } from '../common/output-stream'; @@ -234,6 +234,7 @@ async function saveDotenv( ): Promise<{ dotenvPath: string; newEnvVariables: string[] }> { const dotenvPath = buildProjectDotenvFilePath(); + const { token } = await fetchSDKToken(); const existingDotenv = await readFileQuiet(dotenvPath); const newDotenv = createNewDotenv({ @@ -241,6 +242,7 @@ async function saveDotenv( providerName: providerJson.name, parameters: providerJson.parameters, security: providerJson.securitySchemes, + token, }); if (newDotenv.content) { diff --git a/src/common/http.test.ts b/src/common/http.test.ts index c3228620..baef48fb 100644 --- a/src/common/http.test.ts +++ b/src/common/http.test.ts @@ -1,6 +1,7 @@ import type { AstMetadata, ProviderJson } from '@superfaceai/ast'; import { ApiKeyPlacement, HttpScheme, SecurityType } from '@superfaceai/ast'; import { ServiceApiError, ServiceClient } from '@superfaceai/service-client'; +import { UserAccountType } from '@superfaceai/service-client/dist/interfaces/identity_api_response'; import type { SuperfaceClient } from '../common/http'; import { @@ -11,6 +12,7 @@ import { fetchProfileInfo, fetchProviderInfo, fetchProviders, + fetchSDKToken, getServicesUrl, } from '../common/http'; import { mockResponse } from '../test/utils'; @@ -802,4 +804,119 @@ describe('HTTP functions', () => { ); }, 10000); }); + + describe('when fetching default OneSDK token', () => { + const ACCNT_HANDLE = 'testuser'; + const DEFAULT_PROJECT = 'default-project'; + const TOKEN = 'sfs_b31314b7fc8...8ec1930e'; + + const mockUserResponse = { + name: 'test.user', + email: 'test.user@superface.test', + accounts: [ + { + handle: ACCNT_HANDLE, + type: UserAccountType.PERSONAL, + }, + ], + }; + + const mockGetProjectResponse = { + url: `https://superface.test/projects/${ACCNT_HANDLE}/${DEFAULT_PROJECT}`, + name: DEFAULT_PROJECT, + sdk_auth_tokens: [ + { + token: TOKEN, + created_at: '2023-07-03T13:58:08.235Z', + }, + ], + settings: { + email_notifications: true, + }, + created_at: '2023-07-03T13:58:08.231Z', + }; + + const mockUserError = new ServiceApiError({ + status: 401, + title: 'Unauthorized', + detail: '', + instance: '/id/user', + }); + + const mockGetProjectError = new ServiceApiError({ + status: 404, + instance: `/projects/${ACCNT_HANDLE}/default-projec`, + title: 'Project not found', + detail: `Project ${ACCNT_HANDLE}/default-projec doesn't exist`, + }); + + let getUserInfoSpy: jest.SpyInstance; + let getProjectSpy: jest.SpyInstance; + + beforeEach(async () => { + jest.resetAllMocks(); + + getUserInfoSpy = jest + .spyOn(ServiceClient.prototype, 'getUserInfo') + .mockResolvedValue(mockUserResponse); + + getProjectSpy = jest + .spyOn(ServiceClient.prototype, 'getProject') + .mockResolvedValue(mockGetProjectResponse); + }); + + it('returns token (obtains account handle, then fetches project by handle and name)', async () => { + const result = await fetchSDKToken(); + + expect(getUserInfoSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledWith(ACCNT_HANDLE, DEFAULT_PROJECT); + + expect(result).toStrictEqual({ token: TOKEN }); + }); + + it('returns null as a token when obtaining account handle fails', async () => { + getUserInfoSpy = jest + .spyOn(ServiceClient.prototype, 'getUserInfo') + .mockRejectedValue(mockUserError); + + const result = await fetchSDKToken(); + + expect(getUserInfoSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledTimes(0); + + expect(result).toStrictEqual({ token: null }); + }); + + it('returns null as a token when fetching the project fails', async () => { + getProjectSpy = jest + .spyOn(ServiceClient.prototype, 'getProject') + .mockRejectedValue(mockGetProjectError); + + const result = await fetchSDKToken(); + + expect(getUserInfoSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledWith(ACCNT_HANDLE, DEFAULT_PROJECT); + + expect(result).toStrictEqual({ token: null }); + }); + + it('returns null as a token when the project fetched lacks tokens', async () => { + getProjectSpy = jest + .spyOn(ServiceClient.prototype, 'getProject') + .mockResolvedValue({ + ...mockGetProjectResponse, + sdk_auth_tokens: [], + }); + + const result = await fetchSDKToken(); + + expect(getUserInfoSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledTimes(1); + expect(getProjectSpy).toHaveBeenCalledWith(ACCNT_HANDLE, DEFAULT_PROJECT); + + expect(result).toStrictEqual({ token: null }); + }); + }); }); diff --git a/src/common/http.ts b/src/common/http.ts index ef65be83..0527dcde 100644 --- a/src/common/http.ts +++ b/src/common/http.ts @@ -165,3 +165,22 @@ export async function fetchMapAST(id: { return assertMapDocumentNode(JSON.parse(response)); } + +export async function fetchSDKToken( + defaultProjectName = 'default-project' +): Promise<{ token: string | null }> { + const client = SuperfaceClient.getClient(); + + try { + const userInfo = await client.getUserInfo(); + const accountHandle = userInfo.accounts[0].handle; + + const project = await client.getProject(accountHandle, defaultProjectName); + + const token = project.sdk_auth_tokens?.[0].token ?? null; + + return { token }; + } catch (_) { + return { token: null }; + } +} diff --git a/src/logic/application-code/dotenv/dotenv.test.ts b/src/logic/application-code/dotenv/dotenv.test.ts index aba1b60f..22f7e780 100644 --- a/src/logic/application-code/dotenv/dotenv.test.ts +++ b/src/logic/application-code/dotenv/dotenv.test.ts @@ -23,8 +23,10 @@ const BEARER_AUTH: SecurityScheme = { type: SecurityType.HTTP, scheme: HttpScheme.BEARER, }; +const TOKEN = 'sfs_b31314b7fc8...8ec1930e'; -const EXISTING_DOTENV = `# Deployment zone +const EXISTING_DOTENV = `SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e +# Deployment zone # for AWS MY_PROVIDER_PARAM_TWO=us-west-1 MY_PROVIDER_TOKEN= @@ -32,12 +34,28 @@ MY_PROVIDER_TOKEN= describe('createNewDotenv', () => { describe('when there is no previous .env', () => { - it('creates valid .env when no parameters or security schemes are given', () => { + it('creates valid .env when no token, no parameters or security schemes are given', () => { const result = createNewDotenv({ providerName: PROVIDER_NAME }); expect(result).toStrictEqual({ - content: '', - addedEnvVariables: [], + content: `# Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai/app +SUPERFACE_ONESDK_TOKEN= +`, + addedEnvVariables: ['SUPERFACE_ONESDK_TOKEN'], + }); + }); + + it('creates valid .env when valid token but no parameters or security schemes are given', () => { + const result = createNewDotenv({ + providerName: PROVIDER_NAME, + token: TOKEN, + }); + + expect(result).toStrictEqual({ + content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app +SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e +`, + addedEnvVariables: ['SUPERFACE_ONESDK_TOKEN'], }); }); @@ -45,17 +63,25 @@ describe('createNewDotenv', () => { const result = createNewDotenv({ providerName: PROVIDER_NAME, parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], + token: TOKEN, }); expect(result).toStrictEqual({ - content: `# Parameter description + content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app +SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e + +# Parameter description MY_PROVIDER_PARAM_ONE= # Deployment zone # for AWS MY_PROVIDER_PARAM_TWO=us-west-1 `, - addedEnvVariables: ['MY_PROVIDER_PARAM_ONE', 'MY_PROVIDER_PARAM_TWO'], + addedEnvVariables: [ + 'SUPERFACE_ONESDK_TOKEN', + 'MY_PROVIDER_PARAM_ONE', + 'MY_PROVIDER_PARAM_TWO', + ], }); }); @@ -64,10 +90,14 @@ MY_PROVIDER_PARAM_TWO=us-west-1 providerName: PROVIDER_NAME, parameters: [PARAMETER, PARAMETER_WITH_DEFAULT], security: [BASIC_AUTH, BEARER_AUTH], + token: TOKEN, }); expect(result).toStrictEqual({ - content: `# Parameter description + content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app +SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e + +# Parameter description MY_PROVIDER_PARAM_ONE= # Deployment zone @@ -78,6 +108,7 @@ MY_PROVIDER_PASSWORD= MY_PROVIDER_TOKEN= `, addedEnvVariables: [ + 'SUPERFACE_ONESDK_TOKEN', 'MY_PROVIDER_PARAM_ONE', 'MY_PROVIDER_PARAM_TWO', 'MY_PROVIDER_USERNAME', @@ -89,7 +120,7 @@ MY_PROVIDER_TOKEN= }); describe('when there is a previous existing .env', () => { - it('creates valid .env when no parameters or security schemes are given', () => { + it('creates valid .env when no token, no parameters or security schemes are given', () => { const result = createNewDotenv({ previousDotenv: EXISTING_DOTENV, providerName: PROVIDER_NAME, @@ -109,7 +140,8 @@ MY_PROVIDER_TOKEN= }); expect(result).toStrictEqual({ - content: `# Deployment zone + content: `SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e +# Deployment zone # for AWS MY_PROVIDER_PARAM_TWO=us-west-1 MY_PROVIDER_TOKEN= @@ -130,7 +162,8 @@ MY_PROVIDER_PARAM_ONE= }); expect(result).toStrictEqual({ - content: `# Deployment zone + content: `SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e +# Deployment zone # for AWS MY_PROVIDER_PARAM_TWO=us-west-1 MY_PROVIDER_TOKEN= diff --git a/src/logic/application-code/dotenv/dotenv.ts b/src/logic/application-code/dotenv/dotenv.ts index a8cf8bff..2da7cac8 100644 --- a/src/logic/application-code/dotenv/dotenv.ts +++ b/src/logic/application-code/dotenv/dotenv.ts @@ -4,6 +4,12 @@ import { prepareSecurityValues, } from '@superfaceai/ast'; +import { + ONESDK_TOKEN_COMMENT, + ONESDK_TOKEN_ENV, + ONESDK_TOKEN_UNAVAILABLE_COMMENT, +} from './onesdk-token'; + export type NewDotenv = { content: string; addedEnvVariables: string[]; @@ -20,21 +26,25 @@ export function createNewDotenv({ providerName, parameters, security, + token, }: { previousDotenv?: string; providerName: string; parameters?: IntegrationParameter[]; security?: SecurityScheme[]; + token?: string | null; }): NewDotenv { const previousContent = previousDotenv ?? ''; const parameterEnvs = getParameterEnvs(providerName, parameters); const securityEnvs = getSecurityEnvs(providerName, security); - const allProviderEnvVariables = [...parameterEnvs, ...securityEnvs]; + const tokenEnv = makeTokenEnv(token); + + const allEnvVariables = [tokenEnv, ...parameterEnvs, ...securityEnvs]; const newEnvsOnly = makeFilterForNewEnvs(previousContent); - const newEnvVariables = allProviderEnvVariables.filter(newEnvsOnly); + const newEnvVariables = allEnvVariables.filter(newEnvsOnly); return { content: serializeContent(previousContent, newEnvVariables), @@ -42,6 +52,17 @@ export function createNewDotenv({ }; } +function makeTokenEnv(token?: string | null): EnvVar { + return { + name: ONESDK_TOKEN_ENV, + value: token ?? undefined, + comment: + token !== undefined && token !== null + ? ONESDK_TOKEN_COMMENT + : ONESDK_TOKEN_UNAVAILABLE_COMMENT, + }; +} + function makeFilterForNewEnvs(content: string): (e: EnvVar) => boolean { const existingEnvs = new Set( content diff --git a/src/logic/application-code/dotenv/index.ts b/src/logic/application-code/dotenv/index.ts index a5d5c0c3..2b87a942 100644 --- a/src/logic/application-code/dotenv/index.ts +++ b/src/logic/application-code/dotenv/index.ts @@ -1 +1,2 @@ -export * from './dotenv' \ No newline at end of file +export * from './dotenv'; +export * from './onesdk-token'; diff --git a/src/logic/application-code/dotenv/onesdk-token.ts b/src/logic/application-code/dotenv/onesdk-token.ts new file mode 100644 index 00000000..bfd28f02 --- /dev/null +++ b/src/logic/application-code/dotenv/onesdk-token.ts @@ -0,0 +1,3 @@ +export const ONESDK_TOKEN_ENV = 'SUPERFACE_ONESDK_TOKEN'; +export const ONESDK_TOKEN_COMMENT = 'OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app' +export const ONESDK_TOKEN_UNAVAILABLE_COMMENT = 'Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai/app' \ No newline at end of file diff --git a/src/logic/application-code/js/application-code.test.ts b/src/logic/application-code/js/application-code.test.ts index 40a3f7f8..54ced4ea 100644 --- a/src/logic/application-code/js/application-code.test.ts +++ b/src/logic/application-code/js/application-code.test.ts @@ -35,8 +35,8 @@ import { OneClient, PerformError, UnexpectedError } from '@superfaceai/one-sdk/n config(); const client = new OneClient({ - // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - // token: + // OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + token: process.env.SUPERFACE_ONESDK_TOKEN, // Specify path to assets folder assetsPath: '${buildSuperfaceDirPath()}' }); diff --git a/src/logic/application-code/js/application-code.ts b/src/logic/application-code/js/application-code.ts index 3a10b924..05c54f90 100644 --- a/src/logic/application-code/js/application-code.ts +++ b/src/logic/application-code/js/application-code.ts @@ -3,6 +3,7 @@ import type { IntegrationParameter, SecurityScheme } from '@superfaceai/ast'; import { buildSuperfaceDirPath } from '../../../common/file-structure'; import { ProfileId } from '../../../common/profile'; import type { ApplicationCodeWriter } from '../application-code'; +import { ONESDK_TOKEN_COMMENT, ONESDK_TOKEN_ENV } from '../dotenv'; import { prepareParameters } from './parameters'; import { prepareSecurity } from './security'; @@ -40,8 +41,8 @@ import { OneClient, PerformError, UnexpectedError } from '${pathToSdk}'; config(); const client = new OneClient({ - // Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - // token: + // ${ONESDK_TOKEN_COMMENT} + token: process.env.${ONESDK_TOKEN_ENV}, // Specify path to assets folder assetsPath: '${buildSuperfaceDirPath()}' }); diff --git a/src/logic/application-code/python/application-code.test.ts b/src/logic/application-code/python/application-code.test.ts index c6b23807..a5bb8351 100644 --- a/src/logic/application-code/python/application-code.test.ts +++ b/src/logic/application-code/python/application-code.test.ts @@ -35,8 +35,8 @@ from one_sdk import OneClient, PerformError, UnexpectedError load_dotenv() client = OneClient( - # Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - # token = + # OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + token = os.getenv("SUPERFACE_ONESDK_TOKEN"), # Specify path to assets folder assets_path = "${buildSuperfaceDirPath()}" ) diff --git a/src/logic/application-code/python/application-code.ts b/src/logic/application-code/python/application-code.ts index 3539d007..e3fef146 100644 --- a/src/logic/application-code/python/application-code.ts +++ b/src/logic/application-code/python/application-code.ts @@ -3,6 +3,7 @@ import type { IntegrationParameter, SecurityScheme } from '@superfaceai/ast'; import { buildSuperfaceDirPath } from '../../../common/file-structure'; import { ProfileId } from '../../../common/profile'; import type { ApplicationCodeWriter } from '../application-code'; +import { ONESDK_TOKEN_COMMENT, ONESDK_TOKEN_ENV } from '../dotenv'; import { prepareParameters } from './parameters'; import { prepareSecurity } from './security'; @@ -37,8 +38,8 @@ from one_sdk import OneClient, PerformError, UnexpectedError load_dotenv() client = OneClient( - # Optionally you can use your OneSDK token to monitor your usage. Get one at https://superface.ai/app - # token = + # ${ONESDK_TOKEN_COMMENT} + token = os.getenv("${ONESDK_TOKEN_ENV}"), # Specify path to assets folder assets_path = "${buildSuperfaceDirPath()}" ) From 32df42a75de441ee31c711b836c78b7270221759 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Thu, 13 Jul 2023 10:59:18 +0000 Subject: [PATCH 13/22] chore: release v4.0.0-beta.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 96fdaee4..24cad961 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.11", + "version": "4.0.0-beta.12", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git", From 450a18d0781fb40123687a9ff98f0190d93290ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Thu, 13 Jul 2023 14:02:04 +0200 Subject: [PATCH 14/22] chore: Remove userAgent extension in init hook (#330) --- package.json | 3 --- src/hooks/init.ts | 7 ------- 2 files changed, 10 deletions(-) delete mode 100644 src/hooks/init.ts diff --git a/package.json b/package.json index 24cad961..ceafa337 100644 --- a/package.json +++ b/package.json @@ -74,9 +74,6 @@ "oclif": { "commands": "dist/commands", "bin": "superface", - "hooks": { - "init": "dist/hooks/init" - }, "plugins": [ "@oclif/plugin-warn-if-update-available" ], diff --git a/src/hooks/init.ts b/src/hooks/init.ts deleted file mode 100644 index c5722226..00000000 --- a/src/hooks/init.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Hook } from '@oclif/config'; -import { VERSION as SDK_VERSION } from '@superfaceai/one-sdk'; -import { VERSION as PARSER_VERSION } from '@superfaceai/parser'; - -export const hook: Hook<'init'> = async function (_options) { - this.config.userAgent += ` (with @superfaceai/one-sdk@${SDK_VERSION}, @superfaceai/parser@${PARSER_VERSION})`; -}; From fac20583c8b26885cfc3b9ffe3d114d33b48cc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Thu, 13 Jul 2023 14:34:14 +0200 Subject: [PATCH 15/22] chore: Add superface/ to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 36717acd..07dd04a4 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,6 @@ yalc.lock testground /test/ + +# Superface Comlink artifacts +superface/ \ No newline at end of file From 56d196e35b7d3f265d19ff38fec608fe5557244e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Thu, 13 Jul 2023 15:14:34 +0200 Subject: [PATCH 16/22] chore(map): Guide for `execute` respects selected language (#331) --- src/commands/execute.ts | 3 +-- src/commands/map.ts | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/commands/execute.ts b/src/commands/execute.ts index 972e9621..3dba81cf 100644 --- a/src/commands/execute.ts +++ b/src/commands/execute.ts @@ -37,13 +37,12 @@ export default class Execute extends Command { required: true, }, { - // TODO: add language support name: 'language', description: 'Language which will use generated code. Default is `js`.', required: false, default: 'js', options: Object.values(SupportedLanguages), - // Hidden because we support only js for now + // Hidden until we figure better language select DX hidden: true, }, ]; diff --git a/src/commands/map.ts b/src/commands/map.ts index f2b80522..0a0e8c33 100644 --- a/src/commands/map.ts +++ b/src/commands/map.ts @@ -50,9 +50,8 @@ export default class Map extends Command { name: 'language', description: 'Language which will use generated code. Default is `js`.', required: false, - default: 'js', options: Object.values(SupportedLanguages), - // Hidden because we support only js for now + // Hidden until we figure better language select DX hidden: true, }, ]; @@ -87,6 +86,7 @@ export default class Map extends Command { const { providerName, profileId, language } = args; const resolvedLanguage = resolveLanguage(language, { userError }); + const hasExplicitLanguageSelect = language !== undefined; ux.start('Loading profile'); const profile = await resolveProfileSource(profileId, { userError }); @@ -157,12 +157,15 @@ export default class Map extends Command { ux.warn(project.installationGuide); + const executeCommand = makeExecuteCommand({ + providerName: resolvedProviderJson.providerJson.name, + profileScope: profile.scope, + profileName: profile.name, + resolvedLanguage, + hasExplicitLanguageSelect, + }); ux.succeed( - `Local project set up. You can now install defined dependencies and run \`superface execute ${ - resolvedProviderJson.providerJson.name - } ${ - ProfileId.fromScopeName(profile.scope, profile.name).id - }\` to execute your integration.` + `Local project set up. You can now install defined dependencies and run \`${executeCommand}\` to execute your integration.` ); } } @@ -341,3 +344,25 @@ async function saveMap({ return mapPath; } + +function makeExecuteCommand({ + providerName, + profileScope, + profileName, + resolvedLanguage, + hasExplicitLanguageSelect, +}: { + providerName: string; + profileScope: string | undefined; + profileName: string; + resolvedLanguage: SupportedLanguages; + hasExplicitLanguageSelect: boolean; +}): string { + const sfExecute = `superface execute ${providerName} ${ + ProfileId.fromScopeName(profileScope, profileName).id + }`; + + return hasExplicitLanguageSelect + ? `${sfExecute} ${resolvedLanguage}` + : sfExecute; +} From bb4cc5fde6abeb80e2c5a34273a8cd45b041cda5 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Thu, 13 Jul 2023 13:27:36 +0000 Subject: [PATCH 17/22] chore: release v4.0.0-beta.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ceafa337..b5d43b53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.12", + "version": "4.0.0-beta.13", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git", From ad5c8a9946a142c93e2a449fc7866e93795544ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Fri, 14 Jul 2023 09:33:40 +0200 Subject: [PATCH 18/22] chore: Remove dist/ before build --- package.json | 5 +- yarn.lock | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 163 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b5d43b53..b6ee7930 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dist/" ], "scripts": { + "prebuild": "rimraf dist", "build": "tsc -p tsconfig.release.json --outDir dist", "test": "yarn test:fast && yarn test:integration", "test:clean": "jest --clear-cache && jest", @@ -68,7 +69,7 @@ "nanospinner": "^1.1.0", "netrc-parser": "^3.1.6", "open": "^8.2.1", - "rimraf": "^3.0.2", + "rimraf": "^5.0.1", "typescript": "4.3.4" }, "oclif": { @@ -82,4 +83,4 @@ "message": "<%= config.name %> update available from <%= chalk.greenBright(config.version) %> to <%= chalk.greenBright(latest) %>." } } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0090f55c..5df5675b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -390,6 +390,18 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" @@ -716,6 +728,11 @@ lodash "^4.17.21" semver "^7.3.2" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@pkgr/utils@^2.3.1": version "2.3.1" resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz" @@ -1172,6 +1189,11 @@ ansi-regex@^5.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" @@ -1191,6 +1213,11 @@ ansi-styles@^5.0.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@^3.0.3: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" @@ -1368,6 +1395,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -1651,7 +1685,7 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1830,6 +1864,11 @@ duplexify@^3.5.1: readable-stream "^2.0.0" stream-shift "^1.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -1850,6 +1889,11 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" @@ -2401,6 +2445,14 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + form-data@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" @@ -2557,6 +2609,17 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob@^10.2.5: + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" @@ -3104,6 +3167,15 @@ iterall@^1.2.1, iterall@^1.3.0: resolved "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== +jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jest-changed-files@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz" @@ -3678,6 +3750,11 @@ lru-cache@^7.14.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz" integrity sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + make-dir@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" @@ -3759,11 +3836,23 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.7" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== + mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" @@ -4144,6 +4233,14 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -4421,6 +4518,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" + integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== + dependencies: + glob "^10.2.5" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" @@ -4567,6 +4671,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" @@ -4675,6 +4784,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -4684,6 +4802,15 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2 is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.trimend@^1.0.5: version "1.0.6" resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" @@ -4721,6 +4848,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -4728,6 +4862,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" @@ -5241,6 +5382,15 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" @@ -5259,6 +5409,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" From c68eb9a0f45ea7044d2384d6bb80330be0854cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Fri, 14 Jul 2023 10:26:48 +0200 Subject: [PATCH 19/22] Revert "chore: Remove dist/ before build" This reverts commit ad5c8a9946a142c93e2a449fc7866e93795544ad. --- package.json | 5 +- yarn.lock | 161 +-------------------------------------------------- 2 files changed, 3 insertions(+), 163 deletions(-) diff --git a/package.json b/package.json index b6ee7930..b5d43b53 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "dist/" ], "scripts": { - "prebuild": "rimraf dist", "build": "tsc -p tsconfig.release.json --outDir dist", "test": "yarn test:fast && yarn test:integration", "test:clean": "jest --clear-cache && jest", @@ -69,7 +68,7 @@ "nanospinner": "^1.1.0", "netrc-parser": "^3.1.6", "open": "^8.2.1", - "rimraf": "^5.0.1", + "rimraf": "^3.0.2", "typescript": "4.3.4" }, "oclif": { @@ -83,4 +82,4 @@ "message": "<%= config.name %> update available from <%= chalk.greenBright(config.version) %> to <%= chalk.greenBright(latest) %>." } } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 5df5675b..0090f55c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -390,18 +390,6 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" @@ -728,11 +716,6 @@ lodash "^4.17.21" semver "^7.3.2" -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - "@pkgr/utils@^2.3.1": version "2.3.1" resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz" @@ -1189,11 +1172,6 @@ ansi-regex@^5.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" @@ -1213,11 +1191,6 @@ ansi-styles@^5.0.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - anymatch@^3.0.3: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" @@ -1395,13 +1368,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - braces@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -1685,7 +1651,7 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1864,11 +1830,6 @@ duplexify@^3.5.1: readable-stream "^2.0.0" stream-shift "^1.0.0" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -1889,11 +1850,6 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" @@ -2445,14 +2401,6 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - form-data@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" @@ -2609,17 +2557,6 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" -glob@^10.2.5: - version "10.3.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" - integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" @@ -3167,15 +3104,6 @@ iterall@^1.2.1, iterall@^1.3.0: resolved "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== -jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - jest-changed-files@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz" @@ -3750,11 +3678,6 @@ lru-cache@^7.14.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz" integrity sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" - integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== - make-dir@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" @@ -3836,23 +3759,11 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.7" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" - integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== - mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" @@ -4233,14 +4144,6 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -4518,13 +4421,6 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - run-async@^2.4.0: version "2.4.1" resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" @@ -4671,11 +4567,6 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" @@ -4784,15 +4675,6 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -4802,15 +4684,6 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2 is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - string.prototype.trimend@^1.0.5: version "1.0.6" resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" @@ -4848,13 +4721,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -4862,13 +4728,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" @@ -5382,15 +5241,6 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" @@ -5409,15 +5259,6 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" From 925cb25f9280102ce58c89aad377ffd72d746994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Fri, 14 Jul 2023 10:34:00 +0200 Subject: [PATCH 20/22] chore: Build first removes dist/ --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b5d43b53..4c3090de 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dist/" ], "scripts": { + "prebuild": "rimraf dist", "build": "tsc -p tsconfig.release.json --outDir dist", "test": "yarn test:fast && yarn test:integration", "test:clean": "jest --clear-cache && jest", From 577aff14a14120796f4fceaa2ea12d299a797022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Kysel=C3=BD?= Date: Fri, 14 Jul 2023 12:39:10 +0200 Subject: [PATCH 21/22] feat: Updating copy of the commands (#332) * feat(common): Add utility for formatting absolute paths * feat: New `prepare` output message * feat: New `new` output message * feat: New `map` output message * feat(boilerplate): Dotenv utility returns only new EMPTY vars * feat(boilerplate): Minor comment changes in application code --- src/commands/map.test.ts | 14 +-- src/commands/map.ts | 90 +++++++++++++------ src/commands/new.ts | 10 ++- src/commands/prepare.ts | 16 ++-- src/common/format.test.ts | 35 +++++++- src/common/format.ts | 9 ++ .../application-code/dotenv/dotenv.test.ts | 28 +++--- src/logic/application-code/dotenv/dotenv.ts | 6 +- .../application-code/dotenv/onesdk-token.ts | 4 +- .../js/application-code.test.ts | 6 +- .../application-code/js/application-code.ts | 4 +- .../python/application-code.test.ts | 6 +- .../python/application-code.ts | 4 +- src/logic/project/js/js.test.ts | 6 +- src/logic/project/js/js.ts | 20 ++++- src/logic/project/prepare-project.ts | 6 +- src/logic/project/python/python.test.ts | 6 +- src/logic/project/python/python.ts | 23 +++-- 18 files changed, 208 insertions(+), 85 deletions(-) diff --git a/src/commands/map.test.ts b/src/commands/map.test.ts index 6c4ac1e8..f0bc7c0d 100644 --- a/src/commands/map.test.ts +++ b/src/commands/map.test.ts @@ -51,7 +51,7 @@ describe('MapCLI command', () => { }; const mockDotenv: NewDotenv = { content: 'TEST_PARAMETER=\nTEST_SECURITY=', - addedEnvVariables: ['TEST_PARAMETER', 'TEST_SECURITY'], + newEmptyEnvVariables: ['TEST_PARAMETER', 'TEST_SECURITY'], }; const mockToken = { token: 'sfs_b31314b7fc8...8ec1930e' }; const providerJson = mockProviderJson({ name: providerName }); @@ -247,7 +247,8 @@ describe('MapCLI command', () => { jest.mocked(prepareProject).mockResolvedValueOnce({ saved: true, - installationGuide: 'test', + dependencyInstallCommand: 'make install', + languageDependency: 'TestLang > 18', path: 'test', }); @@ -305,7 +306,8 @@ describe('MapCLI command', () => { jest.mocked(prepareProject).mockResolvedValueOnce({ saved: true, - installationGuide: 'test', + dependencyInstallCommand: 'make install', + languageDependency: 'TestLang > 18', path: 'test', }); @@ -383,7 +385,8 @@ describe('MapCLI command', () => { jest.mocked(prepareProject).mockResolvedValueOnce({ saved: true, - installationGuide: 'test', + dependencyInstallCommand: 'make install', + languageDependency: 'TestLang > 18', path: 'test', }); @@ -459,7 +462,8 @@ describe('MapCLI command', () => { jest.mocked(prepareProject).mockResolvedValueOnce({ saved: true, - installationGuide: 'test', + dependencyInstallCommand: 'make install', + languageDependency: 'TestLang > 18', path: 'test', }); diff --git a/src/commands/map.ts b/src/commands/map.ts index 0a0e8c33..4b39b43f 100644 --- a/src/commands/map.ts +++ b/src/commands/map.ts @@ -11,6 +11,7 @@ import { buildProjectDotenvFilePath, buildRunFilePath, } from '../common/file-structure'; +import { formatPath } from '../common/format'; import { fetchSDKToken, SuperfaceClient } from '../common/http'; import { exists, readFile, readFileQuiet } from '../common/io'; import type { ILogger } from '../common/log'; @@ -20,13 +21,25 @@ import { resolveProviderJson } from '../common/provider'; import { UX } from '../common/ux'; import { createNewDotenv } from '../logic'; import { - getLanguageName, SupportedLanguages, writeApplicationCode, } from '../logic/application-code/application-code'; import { mapProviderToProfile } from '../logic/map'; import { prepareProject } from '../logic/project'; +type Status = { + filesCreated: string[]; + dotenv?: { + path: string; + newVars: string[]; + }; + execution?: { + languageDependency: string; + dependencyInstallCommand: string; + executeCommand: string; + }; +}; + export default class Map extends Command { // TODO: add description public static description = @@ -97,6 +110,10 @@ export default class Map extends Command { client: SuperfaceClient.getClient(), }); + const status: Status = { + filesCreated: [], + }; + ux.start('Preparing integration code for your use case'); // TODO: load old map? const map = await mapProviderToProfile( @@ -113,7 +130,8 @@ export default class Map extends Command { providerName: resolvedProviderJson.providerJson.name, profileScope: profile.ast.header.scope, }); - ux.succeed(`Integration code saved to ${mapPath}`); + + status.filesCreated.push(mapPath); ux.start(`Preparing boilerplate code for ${resolvedLanguage}`); @@ -126,20 +144,17 @@ export default class Map extends Command { userError, } ); - ux.succeed( - boilerplate.saved - ? `Boilerplate code prepared for ${resolvedLanguage} at ${boilerplate.path}` - : `Boilerplate for ${getLanguageName( - resolvedLanguage - )} already exists at ${boilerplate.path}.` - ); + if (boilerplate.saved) { + status.filesCreated.push(boilerplate.path); + } const dotenv = await saveDotenv(resolvedProviderJson.providerJson); if (dotenv.newEnvVariables.length > 0) { - ux.warn( - `${dotenv.newEnvVariables.length} new environment variables were added to ${dotenv.dotenvPath}. Please set their values before running the integration` - ); + status.dotenv = { + path: dotenv.dotenvPath, + newVars: dotenv.newEnvVariables, + }; } ux.start(`Setting up local project in ${resolvedLanguage}`); @@ -147,16 +162,6 @@ export default class Map extends Command { // TODO: install dependencies const project = await prepareProject(resolvedLanguage); - if (project.saved) { - ux.succeed( - `Dependency definition prepared for ${getLanguageName( - resolvedLanguage - )} at ${project.path}.` - ); - } - - ux.warn(project.installationGuide); - const executeCommand = makeExecuteCommand({ providerName: resolvedProviderJson.providerJson.name, profileScope: profile.scope, @@ -164,9 +169,14 @@ export default class Map extends Command { resolvedLanguage, hasExplicitLanguageSelect, }); - ux.succeed( - `Local project set up. You can now install defined dependencies and run \`${executeCommand}\` to execute your integration.` - ); + + status.execution = { + languageDependency: project.languageDependency, + dependencyInstallCommand: project.dependencyInstallCommand, + executeCommand: executeCommand, + }; + + ux.succeed(makeMessage(status)); } } @@ -254,7 +264,7 @@ async function saveDotenv( return { dotenvPath, - newEnvVariables: newDotenv.addedEnvVariables, + newEnvVariables: newDotenv.newEmptyEnvVariables, }; } @@ -366,3 +376,31 @@ function makeExecuteCommand({ ? `${sfExecute} ${resolvedLanguage}` : sfExecute; } + +function makeMessage(status: Status): string { + let message = `📡 Comlink established!`; + + if (status.filesCreated.length > 0) { + message += ` + +Files created: +${status.filesCreated.map(file => `- ${formatPath(file)}`).join('\n')}`; + } + + if (status.dotenv) { + message += ` + +Set the following environment variables in '${formatPath(status.dotenv.path)}': +${status.dotenv.newVars.map(env => `- $${env}`).join('\n')}`; + } + + if (status.execution) { + message += ` + +Run (${status.execution.languageDependency}): +cd superface && ${status.execution.dependencyInstallCommand} +${status.execution.executeCommand}`; + } + + return message; +} diff --git a/src/commands/new.ts b/src/commands/new.ts index 9dc8e025..0e047a0f 100644 --- a/src/commands/new.ts +++ b/src/commands/new.ts @@ -4,6 +4,7 @@ import type { Flags } from '../common/command.abstract'; import { Command } from '../common/command.abstract'; import type { UserError } from '../common/error'; import { buildProfilePath } from '../common/file-structure'; +import { formatPath } from '../common/format'; import { SuperfaceClient } from '../common/http'; import { exists } from '../common/io'; import { OutputStream } from '../common/output-stream'; @@ -88,9 +89,12 @@ export default class New extends Command { const profilePath = await saveProfile(profile, { userError }); ux.succeed( - `Profile saved to ${profilePath}. You can use it to generate integration code for your use case by running 'superface map ${ - resolvedProviderJson.providerJson.name - } ${ProfileId.fromScopeName(profile.scope, profile.name).id}'` + `New Comlink profile saved to '${formatPath(profilePath)}'. + +Create your use case code by running: +superface map ${resolvedProviderJson.providerJson.name} ${ + ProfileId.fromScopeName(profile.scope, profile.name).id + }` ); } } diff --git a/src/commands/prepare.ts b/src/commands/prepare.ts index c80ec87b..49bc713c 100644 --- a/src/commands/prepare.ts +++ b/src/commands/prepare.ts @@ -9,6 +9,7 @@ import { buildProviderPath, buildSuperfaceDirPath, } from '../common/file-structure'; +import { formatPath } from '../common/format'; import { exists, mkdir, readFile } from '../common/io'; import type { ILogger } from '../common/log'; import { OutputStream } from '../common/output-stream'; @@ -129,13 +130,18 @@ This command prepares a Provider JSON metadata definition that can be used to ge (providerJson.services.length === 1 && providerJson.services[0].baseUrl.includes('TODO')) ) { - // TODO: provide more info - url to REAL docs - ux.warn( - `[ACTION REQUIRED]: Provider definition is incomplete. Please fill in the details at ${providerJsonPath}. Documentation Guide:\nhttps://sfc.is/editing-providers\nYou can then create a new profile using 'superface new ${providerJson.name} ""'.` - ); + ux.warn(`[ACTION REQUIRED]: Provider definition requires attention. Please check and edit '${formatPath( + providerJsonPath + )}' (reference: https://sfc.is/editing-providers). + +Create a new Comlink profile using: +superface new ${providerJson.name} "use case description"`); } else { ux.succeed( - `Provider definition saved to ${providerJsonPath}.\nYou can now create a new profile using 'superface new ${providerJson.name} ""'.` + `Provider definition saved to '${formatPath(providerJsonPath)}'. + +Create a new Comlink profile using: +superface new ${providerJson.name} "use case description"` ); } } diff --git a/src/common/format.test.ts b/src/common/format.test.ts index 9c807d3b..44ed27ff 100644 --- a/src/common/format.test.ts +++ b/src/common/format.test.ts @@ -1,4 +1,6 @@ -import { capitalize, startCase } from './format'; +import { join } from 'path'; + +import { capitalize, formatPath, startCase } from './format'; describe('Format utils', () => { describe('when calling startCase', () => { @@ -20,4 +22,35 @@ describe('Format utils', () => { expect(capitalize('getUser')).toEqual('GetUser'); }); }); + + describe('formatPath', () => { + const HOME_PATH = '/Users/admin'; + const APP_PATH = join(HOME_PATH, 'Documents/my-app'); + const SUPERFACE_DIR_PATH = join(APP_PATH, 'superface'); + const PROFILE_PATH = join(SUPERFACE_DIR_PATH, 'scope.name.profile'); + + it('formats path to Profile from ~/', () => { + expect(formatPath(PROFILE_PATH, HOME_PATH)).toEqual( + 'Documents/my-app/superface/scope.name.profile' + ); + }); + + it('formats path to Profile from app root', () => { + expect(formatPath(PROFILE_PATH, APP_PATH)).toEqual( + 'superface/scope.name.profile' + ); + }); + + it('formats path to Profile from Superface directory', () => { + expect(formatPath(PROFILE_PATH, SUPERFACE_DIR_PATH)).toEqual( + 'scope.name.profile' + ); + }); + + it('formats path to app root from Superface directory', () => { + expect(formatPath(APP_PATH, SUPERFACE_DIR_PATH)).toEqual( + '..' + ); + }); + }); }); diff --git a/src/common/format.ts b/src/common/format.ts index d332da6e..32d2f18c 100644 --- a/src/common/format.ts +++ b/src/common/format.ts @@ -1,3 +1,5 @@ +import { relative } from 'path'; + export function formatWordPlurality(num: number, word: string): string { if (num === 1) { return `${num} ${word}`; @@ -22,3 +24,10 @@ export function startCase(input: string, delimiter = ' '): string { '' ); } + +export function formatPath( + absolutePath: string, + relativeTo = process.cwd() +): string { + return relative(relativeTo, absolutePath); +} diff --git a/src/logic/application-code/dotenv/dotenv.test.ts b/src/logic/application-code/dotenv/dotenv.test.ts index 22f7e780..7e4bad21 100644 --- a/src/logic/application-code/dotenv/dotenv.test.ts +++ b/src/logic/application-code/dotenv/dotenv.test.ts @@ -38,10 +38,10 @@ describe('createNewDotenv', () => { const result = createNewDotenv({ providerName: PROVIDER_NAME }); expect(result).toStrictEqual({ - content: `# Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai/app + content: `# Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai SUPERFACE_ONESDK_TOKEN= `, - addedEnvVariables: ['SUPERFACE_ONESDK_TOKEN'], + newEmptyEnvVariables: ['SUPERFACE_ONESDK_TOKEN'], }); }); @@ -52,10 +52,10 @@ SUPERFACE_ONESDK_TOKEN= }); expect(result).toStrictEqual({ - content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + content: `# The token for monitoring your Comlinks at https://superface.ai SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e `, - addedEnvVariables: ['SUPERFACE_ONESDK_TOKEN'], + newEmptyEnvVariables: [], }); }); @@ -67,7 +67,7 @@ SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e }); expect(result).toStrictEqual({ - content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + content: `# The token for monitoring your Comlinks at https://superface.ai SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e # Parameter description @@ -77,11 +77,7 @@ MY_PROVIDER_PARAM_ONE= # for AWS MY_PROVIDER_PARAM_TWO=us-west-1 `, - addedEnvVariables: [ - 'SUPERFACE_ONESDK_TOKEN', - 'MY_PROVIDER_PARAM_ONE', - 'MY_PROVIDER_PARAM_TWO', - ], + newEmptyEnvVariables: ['MY_PROVIDER_PARAM_ONE'], }); }); @@ -94,7 +90,7 @@ MY_PROVIDER_PARAM_TWO=us-west-1 }); expect(result).toStrictEqual({ - content: `# OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + content: `# The token for monitoring your Comlinks at https://superface.ai SUPERFACE_ONESDK_TOKEN=sfs_b31314b7fc8...8ec1930e # Parameter description @@ -107,10 +103,8 @@ MY_PROVIDER_USERNAME= MY_PROVIDER_PASSWORD= MY_PROVIDER_TOKEN= `, - addedEnvVariables: [ - 'SUPERFACE_ONESDK_TOKEN', + newEmptyEnvVariables: [ 'MY_PROVIDER_PARAM_ONE', - 'MY_PROVIDER_PARAM_TWO', 'MY_PROVIDER_USERNAME', 'MY_PROVIDER_PASSWORD', 'MY_PROVIDER_TOKEN', @@ -128,7 +122,7 @@ MY_PROVIDER_TOKEN= expect(result).toStrictEqual({ content: EXISTING_DOTENV, - addedEnvVariables: [], + newEmptyEnvVariables: [], }); }); @@ -149,7 +143,7 @@ MY_PROVIDER_TOKEN= # Parameter description MY_PROVIDER_PARAM_ONE= `, - addedEnvVariables: ['MY_PROVIDER_PARAM_ONE'], + newEmptyEnvVariables: ['MY_PROVIDER_PARAM_ONE'], }); }); @@ -173,7 +167,7 @@ MY_PROVIDER_PARAM_ONE= MY_PROVIDER_USERNAME= MY_PROVIDER_PASSWORD= `, - addedEnvVariables: [ + newEmptyEnvVariables: [ 'MY_PROVIDER_PARAM_ONE', 'MY_PROVIDER_USERNAME', 'MY_PROVIDER_PASSWORD', diff --git a/src/logic/application-code/dotenv/dotenv.ts b/src/logic/application-code/dotenv/dotenv.ts index 2da7cac8..01864bca 100644 --- a/src/logic/application-code/dotenv/dotenv.ts +++ b/src/logic/application-code/dotenv/dotenv.ts @@ -12,7 +12,7 @@ import { export type NewDotenv = { content: string; - addedEnvVariables: string[]; + newEmptyEnvVariables: string[]; }; type EnvVar = { @@ -48,7 +48,9 @@ export function createNewDotenv({ return { content: serializeContent(previousContent, newEnvVariables), - addedEnvVariables: newEnvVariables.map(e => e.name), + newEmptyEnvVariables: newEnvVariables + .filter(e => e.value === undefined) + .map(e => e.name), }; } diff --git a/src/logic/application-code/dotenv/onesdk-token.ts b/src/logic/application-code/dotenv/onesdk-token.ts index bfd28f02..3babd854 100644 --- a/src/logic/application-code/dotenv/onesdk-token.ts +++ b/src/logic/application-code/dotenv/onesdk-token.ts @@ -1,3 +1,3 @@ export const ONESDK_TOKEN_ENV = 'SUPERFACE_ONESDK_TOKEN'; -export const ONESDK_TOKEN_COMMENT = 'OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app' -export const ONESDK_TOKEN_UNAVAILABLE_COMMENT = 'Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai/app' \ No newline at end of file +export const ONESDK_TOKEN_COMMENT = 'The token for monitoring your Comlinks at https://superface.ai' +export const ONESDK_TOKEN_UNAVAILABLE_COMMENT = 'Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai' \ No newline at end of file diff --git a/src/logic/application-code/js/application-code.test.ts b/src/logic/application-code/js/application-code.test.ts index 54ced4ea..6b8567e8 100644 --- a/src/logic/application-code/js/application-code.test.ts +++ b/src/logic/application-code/js/application-code.test.ts @@ -35,13 +35,13 @@ import { OneClient, PerformError, UnexpectedError } from '@superfaceai/one-sdk/n config(); const client = new OneClient({ - // OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + // The token for monitoring your Comlinks at https://superface.ai token: process.env.SUPERFACE_ONESDK_TOKEN, - // Specify path to assets folder + // Path to Comlinks within your project assetsPath: '${buildSuperfaceDirPath()}' }); -// Load profile and use case +// Load Comlink profile and use case const profile = await client.getProfile('${scope}/${name}'); const useCase = profile.getUseCase('${useCaseName}') diff --git a/src/logic/application-code/js/application-code.ts b/src/logic/application-code/js/application-code.ts index 05c54f90..a0757374 100644 --- a/src/logic/application-code/js/application-code.ts +++ b/src/logic/application-code/js/application-code.ts @@ -43,11 +43,11 @@ config(); const client = new OneClient({ // ${ONESDK_TOKEN_COMMENT} token: process.env.${ONESDK_TOKEN_ENV}, - // Specify path to assets folder + // Path to Comlinks within your project assetsPath: '${buildSuperfaceDirPath()}' }); -// Load profile and use case +// Load Comlink profile and use case const profile = await client.getProfile('${profileId}'); const useCase = profile.getUseCase('${useCaseName}') diff --git a/src/logic/application-code/python/application-code.test.ts b/src/logic/application-code/python/application-code.test.ts index a5bb8351..063c30d6 100644 --- a/src/logic/application-code/python/application-code.test.ts +++ b/src/logic/application-code/python/application-code.test.ts @@ -35,14 +35,16 @@ from one_sdk import OneClient, PerformError, UnexpectedError load_dotenv() client = OneClient( - # OneSDK token lets you monitor your usage out-of-the-box at https://superface.ai/app + # The token for monitoring your Comlinks at https://superface.ai token = os.getenv("SUPERFACE_ONESDK_TOKEN"), - # Specify path to assets folder + # Path to Comlinks within your project assets_path = "${buildSuperfaceDirPath()}" ) +# Load Comlink profile and use case profile = client.get_profile("${scope}/${name}") use_case = profile.get_usecase("${useCaseName}") + try: result = use_case.perform( {}, diff --git a/src/logic/application-code/python/application-code.ts b/src/logic/application-code/python/application-code.ts index e3fef146..d9dcda83 100644 --- a/src/logic/application-code/python/application-code.ts +++ b/src/logic/application-code/python/application-code.ts @@ -40,12 +40,14 @@ load_dotenv() client = OneClient( # ${ONESDK_TOKEN_COMMENT} token = os.getenv("${ONESDK_TOKEN_ENV}"), - # Specify path to assets folder + # Path to Comlinks within your project assets_path = "${buildSuperfaceDirPath()}" ) +# Load Comlink profile and use case profile = client.get_profile("${profileId}") use_case = profile.get_usecase("${useCaseName}") + try: result = use_case.perform( ${input}, diff --git a/src/logic/project/js/js.test.ts b/src/logic/project/js/js.test.ts index dbb788ef..b235cb15 100644 --- a/src/logic/project/js/js.test.ts +++ b/src/logic/project/js/js.test.ts @@ -34,7 +34,8 @@ describe('prepareJsProject', () => { prepareJsProject('3.0.0-alpha.12', '^16.0.3') ).resolves.toEqual({ saved: true, - installationGuide: expect.any(String), + dependencyInstallCommand: expect.any(String), + languageDependency: expect.any(String), path: expect.stringContaining('superface/package.json'), }); @@ -51,7 +52,8 @@ describe('prepareJsProject', () => { prepareJsProject('3.0.0-alpha.12', '^16.0.3') ).resolves.toEqual({ saved: false, - installationGuide: expect.any(String), + dependencyInstallCommand: expect.any(String), + languageDependency: expect.any(String), path: expect.stringContaining('superface/package.json'), }); diff --git a/src/logic/project/js/js.ts b/src/logic/project/js/js.ts index 2dc266d3..391a52af 100644 --- a/src/logic/project/js/js.ts +++ b/src/logic/project/js/js.ts @@ -9,7 +9,8 @@ export async function prepareJsProject( dotenvVersion = '^16.0.3' ): Promise<{ saved: boolean; - installationGuide: string; + dependencyInstallCommand: string; + languageDependency: string; path: string; }> { const packageJson = `{ @@ -31,13 +32,24 @@ export async function prepareJsProject( const packageJsonPath = buildProjectDefinitionFilePath(SupportedLanguages.JS); - const installationGuide = `You need to have Node version 18.0.0 or higher installed to run the integration.\nYou can install defined dependencies by running \`npm install\` in \`superface\` directory.`; + const languageDependency = 'Node.js > 18.0.0'; + const dependencyInstallCommand = 'npm install'; if (!(await exists(packageJsonPath))) { await OutputStream.writeOnce(packageJsonPath, packageJson); - return { saved: true, installationGuide, path: packageJsonPath }; + return { + saved: true, + dependencyInstallCommand, + languageDependency, + path: packageJsonPath, + }; } - return { saved: false, installationGuide, path: packageJsonPath }; + return { + saved: false, + dependencyInstallCommand, + languageDependency, + path: packageJsonPath, + }; } diff --git a/src/logic/project/prepare-project.ts b/src/logic/project/prepare-project.ts index a738428e..9159a519 100644 --- a/src/logic/project/prepare-project.ts +++ b/src/logic/project/prepare-project.ts @@ -4,13 +4,15 @@ import { preparePythonProject } from './python'; export async function prepareProject(language: SupportedLanguages): Promise<{ saved: boolean; - installationGuide: string; + dependencyInstallCommand: string; + languageDependency: string; path: string; }> { const PROJECT_PREPARATION_MAP: { [key in SupportedLanguages]: () => Promise<{ saved: boolean; - installationGuide: string; + dependencyInstallCommand: string; + languageDependency: string; path: string; }>; } = { diff --git a/src/logic/project/python/python.test.ts b/src/logic/project/python/python.test.ts index eb5d8812..a63b4ca3 100644 --- a/src/logic/project/python/python.test.ts +++ b/src/logic/project/python/python.test.ts @@ -32,7 +32,8 @@ describe('preparePythonProject', () => { await expect(preparePythonProject('1.0.0b1')).resolves.toEqual({ saved: true, - installationGuide: expect.any(String), + dependencyInstallCommand: expect.any(String), + languageDependency: expect.any(String), path: expect.stringContaining('superface/requirements.txt'), }); @@ -47,7 +48,8 @@ describe('preparePythonProject', () => { await expect(preparePythonProject('1.0.0b1')).resolves.toEqual({ saved: false, - installationGuide: expect.any(String), + dependencyInstallCommand: expect.any(String), + languageDependency: expect.any(String), path: expect.stringContaining('superface/requirements.txt'), }); diff --git a/src/logic/project/python/python.ts b/src/logic/project/python/python.ts index 56791c65..77a4cbb4 100644 --- a/src/logic/project/python/python.ts +++ b/src/logic/project/python/python.ts @@ -7,11 +7,11 @@ export async function preparePythonProject( sdkVersion = '1b' // beta on major 1 ): Promise<{ saved: boolean; - installationGuide: string; + dependencyInstallCommand: string; + languageDependency: string; path: string; }> { - const requirements = ` -one-sdk>=${sdkVersion} + const requirements = `one-sdk>=${sdkVersion} python-dotenv==1.0.0 Brotli==1.0.9 certifi==2023.5.7 @@ -24,13 +24,24 @@ wasmtime==10.0.0`; SupportedLanguages.PYTHON ); - const installationGuide = `You need to have Python version 3.8 or higher installed to run the integration. You can check used dependencies in: ${requirementsPath}\nYou can install defined dependencies by running \`python3 -m pip install -r requirements.txt\` in \`superface\` directory.`; + const languageDependency = 'Python >= 3.8'; + const dependencyInstallCommand = 'python3 -m pip install -r requirements.txt'; if (!(await exists(requirementsPath))) { await OutputStream.writeOnce(requirementsPath, requirements); - return { saved: true, installationGuide, path: requirementsPath }; + return { + saved: true, + languageDependency, + dependencyInstallCommand, + path: requirementsPath, + }; } - return { saved: false, installationGuide, path: requirementsPath }; + return { + saved: false, + languageDependency, + dependencyInstallCommand, + path: requirementsPath, + }; } From b3113ef6135d40002bc197b74094214bfc7adad3 Mon Sep 17 00:00:00 2001 From: GitHub Actions release workflow Date: Fri, 14 Jul 2023 10:44:51 +0000 Subject: [PATCH 22/22] chore: release v4.0.0-beta.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c3090de..1fa527fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@superfaceai/cli", - "version": "4.0.0-beta.13", + "version": "4.0.0-beta.14", "description": "Superface CLI utility", "main": "dist/index.js", "repository": "https://github.com/superfaceai/cli.git",