From b8ed5079c87ab407815e1cb9c32dac43be44a066 Mon Sep 17 00:00:00 2001 From: Dominik Kundel Date: Fri, 7 Aug 2020 16:58:05 -0700 Subject: [PATCH 1/4] chore(release): 2.8.0 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d3c5f57..1de2068e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [2.8.0](https://github.com/twilio-labs/twilio-run/compare/v2.8.0-beta.0...v2.8.0) (2020-08-07) + + +### Bug Fixes + +* **env:** catch dotenv parsing error ([c8e327b](https://github.com/twilio-labs/twilio-run/commit/c8e327b9b6bed6573726e19e18e7ee8091b98cb5)) +* upgrade type-fest from 0.6.0 to 0.15.1 ([d682b2d](https://github.com/twilio-labs/twilio-run/commit/d682b2dbd00d725578251f1efef66109fcd208f5)) + ## [2.8.0-beta.1](https://github.com/twilio-labs/twilio-run/compare/v2.7.0...v2.8.0-beta.1) (2020-07-08) diff --git a/package.json b/package.json index 0e9e2dee..064cbf04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "twilio-run", - "version": "2.8.0-beta.1", + "version": "2.8.0", "bin": { "twilio-functions": "./bin/twilio-run.js", "twilio-run": "./bin/twilio-run.js" From 0d846983b6e3935afc2c18baf180638b7bc57f68 Mon Sep 17 00:00:00 2001 From: Dominik Kundel Date: Fri, 7 Aug 2020 17:42:56 -0700 Subject: [PATCH 2/4] refactor: create monorepo w/ lerna --- .github/workflows/nodejs.yml | 1 + jest.config.base.js | 182 +++++++++++++++++ jest.config.js | 183 +----------------- lerna.json | 16 ++ package.json | 115 +---------- .npmrc => packages/twilio-run/.npmrc | 0 .../twilio-run/.prettierrc | 0 .../twilio-run/CHANGELOG.md | 0 .../twilio-run/CONTRIBUTING.md | 0 README.md => packages/twilio-run/README.md | 0 .../twilio-run/__mocks__}/twilio.ts | 0 .../twilio-run/__mocks__}/window-size.ts | 0 .../twilio-run/__tests__}/config/list.test.ts | 0 .../__tests__}/config/start.test.ts | 0 .../__tests__}/config/utils.test.ts | 0 .../config/utils/credentials.test.ts | 0 .../__tests__}/config/utils/env.test.ts | 0 .../config/utils/mergeFlagsAndConfig.test.ts | 0 .../config/utils/service-name.test.ts | 0 .../__snapshots__/integration.test.ts.snap | 0 .../__tests__}/runtime/integration.test.ts | 0 .../runtime/internal/response.test.ts | 0 .../runtime/internal/runtime-paths.test.ts | 0 .../__tests__}/runtime/route.test.ts | 0 .../__tests__}/templating/data.test.ts | 0 .../__tests__}/templating/filesystem.test.ts | 0 .../twilio-run/__tests__}/utils/debug.test.ts | 0 .../utils/stack-trace/clean-up.test.ts | 0 .../utils/stack-trace/helpers.test.ts | 0 .../twilio-run/bin}/twilio-run.js | 0 .../examples}/basic/assets/something.txt | 0 .../examples}/basic/functions/error.js | 0 .../examples}/basic/functions/hello.js | 0 .../only-assets/assets/something.txt | 0 .../only-functions/functions/hello.js | 0 .../twilio-run/fixtures}/assets/hello.js | 0 .../fixtures}/functions/basic-error.js | 0 .../fixtures}/functions/basic-twiml.js | 0 .../twilio-run/hooks}/update-dependencies.sh | 0 packages/twilio-run/jest.config.js | 12 ++ packages/twilio-run/package.json | 107 ++++++++++ .../src}/checks/check-account-sid.ts | 0 .../src}/checks/check-credentials.ts | 0 .../src}/checks/check-service-sid.ts | 0 .../twilio-run/src}/checks/nodejs-version.ts | 0 .../src}/checks/project-structure.ts | 0 {src => packages/twilio-run/src}/cli.ts | 0 .../twilio-run/src}/commands/activate.ts | 0 .../twilio-run/src}/commands/deploy.ts | 0 .../src}/commands/list-templates.ts | 0 .../twilio-run/src}/commands/list.ts | 0 .../twilio-run/src}/commands/logs.ts | 0 .../twilio-run/src}/commands/new.ts | 0 .../twilio-run/src}/commands/shared.ts | 0 .../twilio-run/src}/commands/start.ts | 0 .../twilio-run/src}/commands/types.ts | 0 .../twilio-run/src}/commands/utils.ts | 0 .../src}/config/__mocks__/global.ts | 0 .../twilio-run/src}/config/__mocks__/utils.ts | 0 .../twilio-run/src}/config/activate.ts | 0 .../twilio-run/src}/config/deploy.ts | 0 .../twilio-run/src}/config/global.ts | 0 .../twilio-run/src}/config/list.ts | 0 .../twilio-run/src}/config/logs.ts | 0 .../twilio-run/src}/config/start.ts | 0 .../twilio-run/src}/config/utils.ts | 0 .../src}/config/utils/__mocks__/env.ts | 0 .../utils/__mocks__/mergeFlagsAndConfig.ts | 0 .../config/utils/__mocks__/package-json.ts | 0 .../src}/config/utils/credentials.ts | 0 .../twilio-run/src}/config/utils/env.ts | 0 .../src}/config/utils/mergeFlagsAndConfig.ts | 0 .../src}/config/utils/package-json.ts | 0 .../src}/config/utils/service-name.ts | 0 {src => packages/twilio-run/src}/index.ts | 0 .../twilio-run/src}/printers/activate.ts | 0 .../twilio-run/src}/printers/deploy.ts | 0 .../twilio-run/src}/printers/list.ts | 0 .../twilio-run/src}/printers/logs.ts | 0 .../twilio-run/src}/printers/new.ts | 0 .../twilio-run/src}/printers/start.ts | 0 .../twilio-run/src}/printers/utils.ts | 0 .../src}/runtime/internal/functionRunner.ts | 0 .../src}/runtime/internal/request-logger.ts | 0 .../src}/runtime/internal/response.ts | 0 .../src}/runtime/internal/route-cache.ts | 0 .../src}/runtime/internal/runtime-paths.ts | 0 .../src}/runtime/internal/runtime.ts | 0 .../twilio-run/src}/runtime/route.ts | 0 .../twilio-run/src}/runtime/server.ts | 0 .../src}/runtime/utils/inspector.ts | 0 .../twilio-run/src}/serverless-api/utils.ts | 0 .../twilio-run/src}/templating/actions.ts | 0 .../twilio-run/src}/templating/data.ts | 0 .../twilio-run/src}/templating/filesystem.ts | 0 {src => packages/twilio-run/src}/types.d.ts | 0 .../twilio-run/src}/types/generic.ts | 0 .../twilio-run/src}/utils/debug.ts | 0 .../twilio-run/src}/utils/error-html.ts | 0 {src => packages/twilio-run/src}/utils/fs.ts | 0 .../twilio-run/src}/utils/logger.ts | 0 .../twilio-run/src}/utils/output.ts | 0 .../src}/utils/stack-trace/clean-up.ts | 0 .../src}/utils/stack-trace/helpers.ts | 0 .../twilio-run/tsconfig.json | 2 +- packages/twilio-run/tsconfig.test.json | 6 + 106 files changed, 339 insertions(+), 285 deletions(-) create mode 100644 jest.config.base.js create mode 100644 lerna.json rename .npmrc => packages/twilio-run/.npmrc (100%) rename .prettierrc => packages/twilio-run/.prettierrc (100%) rename CHANGELOG.md => packages/twilio-run/CHANGELOG.md (100%) rename CONTRIBUTING.md => packages/twilio-run/CONTRIBUTING.md (100%) rename README.md => packages/twilio-run/README.md (100%) rename {__mocks__ => packages/twilio-run/__mocks__}/twilio.ts (100%) rename {__mocks__ => packages/twilio-run/__mocks__}/window-size.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/list.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/start.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/utils.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/utils/credentials.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/utils/env.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/utils/mergeFlagsAndConfig.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/config/utils/service-name.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/runtime/__snapshots__/integration.test.ts.snap (100%) rename {__tests__ => packages/twilio-run/__tests__}/runtime/integration.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/runtime/internal/response.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/runtime/internal/runtime-paths.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/runtime/route.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/templating/data.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/templating/filesystem.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/utils/debug.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/utils/stack-trace/clean-up.test.ts (100%) rename {__tests__ => packages/twilio-run/__tests__}/utils/stack-trace/helpers.test.ts (100%) rename {bin => packages/twilio-run/bin}/twilio-run.js (100%) rename {examples => packages/twilio-run/examples}/basic/assets/something.txt (100%) rename {examples => packages/twilio-run/examples}/basic/functions/error.js (100%) rename {examples => packages/twilio-run/examples}/basic/functions/hello.js (100%) rename {examples => packages/twilio-run/examples}/only-assets/assets/something.txt (100%) rename {examples => packages/twilio-run/examples}/only-functions/functions/hello.js (100%) rename {fixtures => packages/twilio-run/fixtures}/assets/hello.js (100%) rename {fixtures => packages/twilio-run/fixtures}/functions/basic-error.js (100%) rename {fixtures => packages/twilio-run/fixtures}/functions/basic-twiml.js (100%) rename {hooks => packages/twilio-run/hooks}/update-dependencies.sh (100%) create mode 100644 packages/twilio-run/jest.config.js create mode 100644 packages/twilio-run/package.json rename {src => packages/twilio-run/src}/checks/check-account-sid.ts (100%) rename {src => packages/twilio-run/src}/checks/check-credentials.ts (100%) rename {src => packages/twilio-run/src}/checks/check-service-sid.ts (100%) rename {src => packages/twilio-run/src}/checks/nodejs-version.ts (100%) rename {src => packages/twilio-run/src}/checks/project-structure.ts (100%) rename {src => packages/twilio-run/src}/cli.ts (100%) rename {src => packages/twilio-run/src}/commands/activate.ts (100%) rename {src => packages/twilio-run/src}/commands/deploy.ts (100%) rename {src => packages/twilio-run/src}/commands/list-templates.ts (100%) rename {src => packages/twilio-run/src}/commands/list.ts (100%) rename {src => packages/twilio-run/src}/commands/logs.ts (100%) rename {src => packages/twilio-run/src}/commands/new.ts (100%) rename {src => packages/twilio-run/src}/commands/shared.ts (100%) rename {src => packages/twilio-run/src}/commands/start.ts (100%) rename {src => packages/twilio-run/src}/commands/types.ts (100%) rename {src => packages/twilio-run/src}/commands/utils.ts (100%) rename {src => packages/twilio-run/src}/config/__mocks__/global.ts (100%) rename {src => packages/twilio-run/src}/config/__mocks__/utils.ts (100%) rename {src => packages/twilio-run/src}/config/activate.ts (100%) rename {src => packages/twilio-run/src}/config/deploy.ts (100%) rename {src => packages/twilio-run/src}/config/global.ts (100%) rename {src => packages/twilio-run/src}/config/list.ts (100%) rename {src => packages/twilio-run/src}/config/logs.ts (100%) rename {src => packages/twilio-run/src}/config/start.ts (100%) rename {src => packages/twilio-run/src}/config/utils.ts (100%) rename {src => packages/twilio-run/src}/config/utils/__mocks__/env.ts (100%) rename {src => packages/twilio-run/src}/config/utils/__mocks__/mergeFlagsAndConfig.ts (100%) rename {src => packages/twilio-run/src}/config/utils/__mocks__/package-json.ts (100%) rename {src => packages/twilio-run/src}/config/utils/credentials.ts (100%) rename {src => packages/twilio-run/src}/config/utils/env.ts (100%) rename {src => packages/twilio-run/src}/config/utils/mergeFlagsAndConfig.ts (100%) rename {src => packages/twilio-run/src}/config/utils/package-json.ts (100%) rename {src => packages/twilio-run/src}/config/utils/service-name.ts (100%) rename {src => packages/twilio-run/src}/index.ts (100%) rename {src => packages/twilio-run/src}/printers/activate.ts (100%) rename {src => packages/twilio-run/src}/printers/deploy.ts (100%) rename {src => packages/twilio-run/src}/printers/list.ts (100%) rename {src => packages/twilio-run/src}/printers/logs.ts (100%) rename {src => packages/twilio-run/src}/printers/new.ts (100%) rename {src => packages/twilio-run/src}/printers/start.ts (100%) rename {src => packages/twilio-run/src}/printers/utils.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/functionRunner.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/request-logger.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/response.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/route-cache.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/runtime-paths.ts (100%) rename {src => packages/twilio-run/src}/runtime/internal/runtime.ts (100%) rename {src => packages/twilio-run/src}/runtime/route.ts (100%) rename {src => packages/twilio-run/src}/runtime/server.ts (100%) rename {src => packages/twilio-run/src}/runtime/utils/inspector.ts (100%) rename {src => packages/twilio-run/src}/serverless-api/utils.ts (100%) rename {src => packages/twilio-run/src}/templating/actions.ts (100%) rename {src => packages/twilio-run/src}/templating/data.ts (100%) rename {src => packages/twilio-run/src}/templating/filesystem.ts (100%) rename {src => packages/twilio-run/src}/types.d.ts (100%) rename {src => packages/twilio-run/src}/types/generic.ts (100%) rename {src => packages/twilio-run/src}/utils/debug.ts (100%) rename {src => packages/twilio-run/src}/utils/error-html.ts (100%) rename {src => packages/twilio-run/src}/utils/fs.ts (100%) rename {src => packages/twilio-run/src}/utils/logger.ts (100%) rename {src => packages/twilio-run/src}/utils/output.ts (100%) rename {src => packages/twilio-run/src}/utils/stack-trace/clean-up.ts (100%) rename {src => packages/twilio-run/src}/utils/stack-trace/helpers.ts (100%) rename tsconfig.json => packages/twilio-run/tsconfig.json (83%) create mode 100644 packages/twilio-run/tsconfig.test.json diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 5ba61fca..e63fc581 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -27,6 +27,7 @@ jobs: - name: npm install, build, and test run: | npm install + npm run bootstrap npm run build --if-present npm run test env: diff --git a/jest.config.base.js b/jest.config.base.js new file mode 100644 index 00000000..f627da31 --- /dev/null +++ b/jest.config.base.js @@ -0,0 +1,182 @@ +// For a detailed explanation regarding each configuration property, visit: +// https://jestjs.io/docs/en/configuration.html + +module.exports = { + preset: "ts-jest", + + // Automatically clear mock calls and instances between every test + clearMocks: true, + + // The directory where Jest should output its coverage files + coverageDirectory: "coverage", + + // A set of global variables that need to be available in all test environments + globals: { + "ts-jest": { + tsConfig: "tsconfig.test.json" + } + }, + // The test environment that will be used for testing + testEnvironment: "node" + + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after the first failure + // bail: false, + + // Respect "browser" field in package.json when resolving modules + // browser: false, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/var/folders/hm/3p38c0353l3gvb3q_m69n1qh2hfrd1/T/jest_1e8c69", + + // Indicates whether the coverage information should be collected while executing the test + // collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: null, + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: null, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files usin a array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: null, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: null, + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "json", + // "jsx", + // "node" + // ], + + // A map from regular expressions to module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "always", + + // Run tests from one or more projects + // projects: null, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state between every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: null, + + // Automatically restore mock state between every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: null, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // The path to a module that runs some code to configure or set up the testing framework before each test + // setupTestFrameworkScriptFile: null, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // "**/__tests__/**/*.js?(x)", + // "**/?(*.)+(spec|test).js?(x)" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern Jest uses to detect test files + // testRegex: "", + + // This option allows the use of a custom results processor + // testResultsProcessor: null, + + // This option allows use of a custom test runner + // testRunner: "jasmine2", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: "about:blank", + + // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" + // timers: "real", + + // A map from regular expressions to paths to transformers + // transform: null, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: null, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; diff --git a/jest.config.js b/jest.config.js index d316667c..34176bc5 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,182 +1,7 @@ -// For a detailed explanation regarding each configuration property, visit: -// https://jestjs.io/docs/en/configuration.html +const base = require("./jest.config.base.js"); module.exports = { - preset: 'ts-jest', - - // Automatically clear mock calls and instances between every test - clearMocks: true, - - // The directory where Jest should output its coverage files - coverageDirectory: 'coverage', - - // A set of global variables that need to be available in all test environments - globals: { - 'ts-jest': { - tsConfig: 'tsconfig.test.json', - }, - }, - // The test environment that will be used for testing - testEnvironment: 'node', - - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after the first failure - // bail: false, - - // Respect "browser" field in package.json when resolving modules - // browser: false, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/var/folders/hm/3p38c0353l3gvb3q_m69n1qh2hfrd1/T/jest_1e8c69", - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: null, - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "/node_modules/" - // ], - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: null, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // Force coverage collection from ignored files usin a array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: null, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: null, - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - // An array of file extensions your modules use - // moduleFileExtensions: [ - // "js", - // "json", - // "jsx", - // "node" - // ], - - // A map from regular expressions to module names that allow to stub out resources with a single module - // moduleNameMapper: {}, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "always", - - // Run tests from one or more projects - // projects: null, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state between every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: null, - - // Automatically restore mock state between every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: null, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // "" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // The path to a module that runs some code to configure or set up the testing framework before each test - // setupTestFrameworkScriptFile: null, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - // testMatch: [ - // "**/__tests__/**/*.js?(x)", - // "**/?(*.)+(spec|test).js?(x)" - // ], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], - - // The regexp pattern Jest uses to detect test files - // testRegex: "", - - // This option allows the use of a custom results processor - // testResultsProcessor: null, - - // This option allows use of a custom test runner - // testRunner: "jasmine2", - - // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href - // testURL: "about:blank", - - // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" - // timers: "real", - - // A map from regular expressions to paths to transformers - // transform: null, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "/node_modules/" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: null, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, + ...base, + projects: ["/packages/*/jest.config.js"], + coverageDirectory: "/coverage/" }; diff --git a/lerna.json b/lerna.json new file mode 100644 index 00000000..001cebc7 --- /dev/null +++ b/lerna.json @@ -0,0 +1,16 @@ +{ + "npmClient": "npm", + "command": { + "publish": { + "message": "chore(release): publish %s" + }, + "bootstrap": { + "npmClientArgs": ["--no-package-lock"] + }, + "version": { + "allowBranch": ["master", "feature/*"] + } + }, + "packages": ["packages/*"], + "version": "independent" +} diff --git a/package.json b/package.json index 064cbf04..767e675a 100644 --- a/package.json +++ b/package.json @@ -1,131 +1,36 @@ { - "name": "twilio-run", - "version": "2.8.0", - "bin": { - "twilio-functions": "./bin/twilio-run.js", - "twilio-run": "./bin/twilio-run.js" - }, - "description": "CLI tool to run Twilio Functions locally for development", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "name": "@twilio-labs/serverless-toolkit", + "private": true, "scripts": { - "clean": "rimraf dist", - "build": "tsc", - "build:noemit": "tsc --noEmit", + "bootstrap": "lerna bootstrap --no-ci", + "release": "lerna version --conventional-commits", + "cm": "git-cz", "jest": "jest", + "build:noemit": "lerna run build:noemit", + "clean": "lerna run clean", "test": "run-s build:noemit jest", "contrib:add": "all-contributors add", "contrib:generate": "all-contributors generate", - "lint-staged": "lint-staged", - "prepack": "run-s clean build", - "cm": "git-cz", - "release": "HUSKY_SKIP_HOOKS=1 standard-version", - "reset-dependencies": "bash ./hooks/update-dependencies.sh" - }, - "keywords": [ - "twilio", - "twilio-functions", - "serverless" - ], - "repository": { - "type": "git", - "url": "https://github.com/twilio-labs/twilio-run.git" - }, - "bugs": { - "url": "https://github.com/twilio-labs/twilio-run/issues", - "email": "dkundel@twilio.com" - }, - "author": "Dominik Kundel ", - "license": "MIT", - "dependencies": { - "@twilio-labs/serverless-api": "^4.0.1", - "@twilio-labs/serverless-runtime-types": "^1.1.7", - "@types/express": "^4.17.0", - "@types/inquirer": "^6.0.3", - "@types/is-ci": "^2.0.0", - "@types/wrap-ansi": "^3.0.0", - "body-parser": "^1.18.3", - "boxen": "^1.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.2.3", - "columnify": "^1.5.4", - "common-tags": "^1.8.0", - "conf": "^5.0.0", - "debug": "^3.1.0", - "dotenv": "^6.2.0", - "express": "^4.16.3", - "express-useragent": "^1.0.13", - "fast-redact": "^1.5.0", - "got": "^9.6.0", - "inquirer": "^6.5.0", - "is-ci": "^2.0.0", - "listr": "^0.14.3", - "lodash.camelcase": "^4.3.0", - "lodash.debounce": "^4.0.8", - "lodash.flatten": "^4.4.0", - "lodash.kebabcase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "log-symbols": "^2.2.0", - "ngrok": "^3.0.1", - "nocache": "^2.1.0", - "normalize.css": "^8.0.1", - "ora": "^3.3.1", - "pkg-install": "^1.0.0", - "serialize-error": "^7.0.1", - "terminal-link": "^1.3.0", - "title": "^3.4.1", - "twilio": "^3.43.1", - "type-fest": "^0.15.1", - "window-size": "^1.1.1", - "wrap-ansi": "^5.1.0", - "yargs": "^13.2.2" + "lint-staged": "lint-staged" }, "devDependencies": { "@commitlint/cli": "^8.1.0", "@commitlint/config-conventional": "^8.0.0", - "@types/cheerio": "^0.22.12", - "@types/common-tags": "^1.8.0", - "@types/debug": "^4.1.4", - "@types/dotenv": "^6.1.1", - "@types/express-useragent": "^0.2.21", - "@types/got": "^9.6.0", "@types/jest": "^24.0.15", - "@types/listr": "^0.14.0", - "@types/lodash.debounce": "^4.0.6", - "@types/lodash.flatten": "^4.4.6", - "@types/lodash.kebabcase": "^4.1.6", - "@types/lodash.startcase": "^4.4.6", - "@types/mock-fs": "^4.10.0", - "@types/node": "^14.0.19", - "@types/prompts": "^2.0.1", - "@types/supertest": "^2.0.8", - "@types/title": "^1.0.5", - "@types/window-size": "^0.2.4", "all-contributors-cli": "^5.3.0", - "cheerio": "^1.0.0-rc.2", "commitizen": "^3.1.1", "cz-conventional-changelog": "^2.1.0", "husky": "^3.0.0", "jest": "^26.2.2", "jest-express": "^1.10.1", + "lerna": "^3.22.1", "lint-staged": "^8.2.1", - "listr-silent-renderer": "^1.1.1", - "mock-fs": "^4.12.0", - "nock": "^12.0.2", "npm-run-all": "^4.1.5", "prettier": "^1.18.2", "rimraf": "^2.6.3", - "standard-version": "^8.0.1", - "supertest": "^3.1.0", "ts-jest": "^26.0.0", - "typescript": "^3.9.2" + "typescript": "^3.9.7" }, - "files": [ - "bin/", - "dist/", - "LICENSE", - "README.md" - ], "husky": { "hooks": { "pre-commit": "run-s lint-staged test", diff --git a/.npmrc b/packages/twilio-run/.npmrc similarity index 100% rename from .npmrc rename to packages/twilio-run/.npmrc diff --git a/.prettierrc b/packages/twilio-run/.prettierrc similarity index 100% rename from .prettierrc rename to packages/twilio-run/.prettierrc diff --git a/CHANGELOG.md b/packages/twilio-run/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/twilio-run/CHANGELOG.md diff --git a/CONTRIBUTING.md b/packages/twilio-run/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to packages/twilio-run/CONTRIBUTING.md diff --git a/README.md b/packages/twilio-run/README.md similarity index 100% rename from README.md rename to packages/twilio-run/README.md diff --git a/__mocks__/twilio.ts b/packages/twilio-run/__mocks__/twilio.ts similarity index 100% rename from __mocks__/twilio.ts rename to packages/twilio-run/__mocks__/twilio.ts diff --git a/__mocks__/window-size.ts b/packages/twilio-run/__mocks__/window-size.ts similarity index 100% rename from __mocks__/window-size.ts rename to packages/twilio-run/__mocks__/window-size.ts diff --git a/__tests__/config/list.test.ts b/packages/twilio-run/__tests__/config/list.test.ts similarity index 100% rename from __tests__/config/list.test.ts rename to packages/twilio-run/__tests__/config/list.test.ts diff --git a/__tests__/config/start.test.ts b/packages/twilio-run/__tests__/config/start.test.ts similarity index 100% rename from __tests__/config/start.test.ts rename to packages/twilio-run/__tests__/config/start.test.ts diff --git a/__tests__/config/utils.test.ts b/packages/twilio-run/__tests__/config/utils.test.ts similarity index 100% rename from __tests__/config/utils.test.ts rename to packages/twilio-run/__tests__/config/utils.test.ts diff --git a/__tests__/config/utils/credentials.test.ts b/packages/twilio-run/__tests__/config/utils/credentials.test.ts similarity index 100% rename from __tests__/config/utils/credentials.test.ts rename to packages/twilio-run/__tests__/config/utils/credentials.test.ts diff --git a/__tests__/config/utils/env.test.ts b/packages/twilio-run/__tests__/config/utils/env.test.ts similarity index 100% rename from __tests__/config/utils/env.test.ts rename to packages/twilio-run/__tests__/config/utils/env.test.ts diff --git a/__tests__/config/utils/mergeFlagsAndConfig.test.ts b/packages/twilio-run/__tests__/config/utils/mergeFlagsAndConfig.test.ts similarity index 100% rename from __tests__/config/utils/mergeFlagsAndConfig.test.ts rename to packages/twilio-run/__tests__/config/utils/mergeFlagsAndConfig.test.ts diff --git a/__tests__/config/utils/service-name.test.ts b/packages/twilio-run/__tests__/config/utils/service-name.test.ts similarity index 100% rename from __tests__/config/utils/service-name.test.ts rename to packages/twilio-run/__tests__/config/utils/service-name.test.ts diff --git a/__tests__/runtime/__snapshots__/integration.test.ts.snap b/packages/twilio-run/__tests__/runtime/__snapshots__/integration.test.ts.snap similarity index 100% rename from __tests__/runtime/__snapshots__/integration.test.ts.snap rename to packages/twilio-run/__tests__/runtime/__snapshots__/integration.test.ts.snap diff --git a/__tests__/runtime/integration.test.ts b/packages/twilio-run/__tests__/runtime/integration.test.ts similarity index 100% rename from __tests__/runtime/integration.test.ts rename to packages/twilio-run/__tests__/runtime/integration.test.ts diff --git a/__tests__/runtime/internal/response.test.ts b/packages/twilio-run/__tests__/runtime/internal/response.test.ts similarity index 100% rename from __tests__/runtime/internal/response.test.ts rename to packages/twilio-run/__tests__/runtime/internal/response.test.ts diff --git a/__tests__/runtime/internal/runtime-paths.test.ts b/packages/twilio-run/__tests__/runtime/internal/runtime-paths.test.ts similarity index 100% rename from __tests__/runtime/internal/runtime-paths.test.ts rename to packages/twilio-run/__tests__/runtime/internal/runtime-paths.test.ts diff --git a/__tests__/runtime/route.test.ts b/packages/twilio-run/__tests__/runtime/route.test.ts similarity index 100% rename from __tests__/runtime/route.test.ts rename to packages/twilio-run/__tests__/runtime/route.test.ts diff --git a/__tests__/templating/data.test.ts b/packages/twilio-run/__tests__/templating/data.test.ts similarity index 100% rename from __tests__/templating/data.test.ts rename to packages/twilio-run/__tests__/templating/data.test.ts diff --git a/__tests__/templating/filesystem.test.ts b/packages/twilio-run/__tests__/templating/filesystem.test.ts similarity index 100% rename from __tests__/templating/filesystem.test.ts rename to packages/twilio-run/__tests__/templating/filesystem.test.ts diff --git a/__tests__/utils/debug.test.ts b/packages/twilio-run/__tests__/utils/debug.test.ts similarity index 100% rename from __tests__/utils/debug.test.ts rename to packages/twilio-run/__tests__/utils/debug.test.ts diff --git a/__tests__/utils/stack-trace/clean-up.test.ts b/packages/twilio-run/__tests__/utils/stack-trace/clean-up.test.ts similarity index 100% rename from __tests__/utils/stack-trace/clean-up.test.ts rename to packages/twilio-run/__tests__/utils/stack-trace/clean-up.test.ts diff --git a/__tests__/utils/stack-trace/helpers.test.ts b/packages/twilio-run/__tests__/utils/stack-trace/helpers.test.ts similarity index 100% rename from __tests__/utils/stack-trace/helpers.test.ts rename to packages/twilio-run/__tests__/utils/stack-trace/helpers.test.ts diff --git a/bin/twilio-run.js b/packages/twilio-run/bin/twilio-run.js similarity index 100% rename from bin/twilio-run.js rename to packages/twilio-run/bin/twilio-run.js diff --git a/examples/basic/assets/something.txt b/packages/twilio-run/examples/basic/assets/something.txt similarity index 100% rename from examples/basic/assets/something.txt rename to packages/twilio-run/examples/basic/assets/something.txt diff --git a/examples/basic/functions/error.js b/packages/twilio-run/examples/basic/functions/error.js similarity index 100% rename from examples/basic/functions/error.js rename to packages/twilio-run/examples/basic/functions/error.js diff --git a/examples/basic/functions/hello.js b/packages/twilio-run/examples/basic/functions/hello.js similarity index 100% rename from examples/basic/functions/hello.js rename to packages/twilio-run/examples/basic/functions/hello.js diff --git a/examples/only-assets/assets/something.txt b/packages/twilio-run/examples/only-assets/assets/something.txt similarity index 100% rename from examples/only-assets/assets/something.txt rename to packages/twilio-run/examples/only-assets/assets/something.txt diff --git a/examples/only-functions/functions/hello.js b/packages/twilio-run/examples/only-functions/functions/hello.js similarity index 100% rename from examples/only-functions/functions/hello.js rename to packages/twilio-run/examples/only-functions/functions/hello.js diff --git a/fixtures/assets/hello.js b/packages/twilio-run/fixtures/assets/hello.js similarity index 100% rename from fixtures/assets/hello.js rename to packages/twilio-run/fixtures/assets/hello.js diff --git a/fixtures/functions/basic-error.js b/packages/twilio-run/fixtures/functions/basic-error.js similarity index 100% rename from fixtures/functions/basic-error.js rename to packages/twilio-run/fixtures/functions/basic-error.js diff --git a/fixtures/functions/basic-twiml.js b/packages/twilio-run/fixtures/functions/basic-twiml.js similarity index 100% rename from fixtures/functions/basic-twiml.js rename to packages/twilio-run/fixtures/functions/basic-twiml.js diff --git a/hooks/update-dependencies.sh b/packages/twilio-run/hooks/update-dependencies.sh similarity index 100% rename from hooks/update-dependencies.sh rename to packages/twilio-run/hooks/update-dependencies.sh diff --git a/packages/twilio-run/jest.config.js b/packages/twilio-run/jest.config.js new file mode 100644 index 00000000..7daeab26 --- /dev/null +++ b/packages/twilio-run/jest.config.js @@ -0,0 +1,12 @@ +const base = require('../../jest.config.base.js'); + +module.exports = { + ...base, + globals: { + 'ts-jest': { + tsConfig: './tsconfig.test.json', + }, + }, + name: 'twilio-run', + displayName: 'twilio-run', +}; diff --git a/packages/twilio-run/package.json b/packages/twilio-run/package.json new file mode 100644 index 00000000..483bc319 --- /dev/null +++ b/packages/twilio-run/package.json @@ -0,0 +1,107 @@ +{ + "name": "twilio-run", + "version": "2.8.0", + "bin": { + "twilio-functions": "./bin/twilio-run.js", + "twilio-run": "./bin/twilio-run.js" + }, + "description": "CLI tool to run Twilio Functions locally for development", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "rimraf dist", + "build": "tsc", + "build:noemit": "tsc --noEmit", + "prepack": "run-s clean build" + }, + "keywords": [ + "twilio", + "twilio-functions", + "serverless" + ], + "repository": { + "type": "git", + "url": "https://github.com/twilio-labs/twilio-run.git" + }, + "bugs": { + "url": "https://github.com/twilio-labs/twilio-run/issues", + "email": "dkundel@twilio.com" + }, + "author": "Dominik Kundel ", + "license": "MIT", + "dependencies": { + "@twilio-labs/serverless-api": "^4.0.1", + "@twilio-labs/serverless-runtime-types": "^1.1.7", + "@types/express": "^4.17.0", + "@types/inquirer": "^6.0.3", + "@types/is-ci": "^2.0.0", + "@types/wrap-ansi": "^3.0.0", + "body-parser": "^1.18.3", + "boxen": "^1.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.2.3", + "columnify": "^1.5.4", + "common-tags": "^1.8.0", + "conf": "^5.0.0", + "debug": "^3.1.0", + "dotenv": "^6.2.0", + "express": "^4.16.3", + "express-useragent": "^1.0.13", + "fast-redact": "^1.5.0", + "got": "^9.6.0", + "inquirer": "^6.5.0", + "is-ci": "^2.0.0", + "listr": "^0.14.3", + "lodash.camelcase": "^4.3.0", + "lodash.debounce": "^4.0.8", + "lodash.flatten": "^4.4.0", + "lodash.kebabcase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "log-symbols": "^2.2.0", + "ngrok": "^3.0.1", + "nocache": "^2.1.0", + "normalize.css": "^8.0.1", + "ora": "^3.3.1", + "pkg-install": "^1.0.0", + "serialize-error": "^7.0.1", + "terminal-link": "^1.3.0", + "title": "^3.4.1", + "twilio": "^3.43.1", + "type-fest": "^0.15.1", + "window-size": "^1.1.1", + "wrap-ansi": "^5.1.0", + "yargs": "^13.2.2" + }, + "devDependencies": { + "@types/cheerio": "^0.22.12", + "@types/common-tags": "^1.8.0", + "@types/debug": "^4.1.4", + "@types/dotenv": "^6.1.1", + "@types/express-useragent": "^0.2.21", + "@types/got": "^9.6.0", + "@types/jest": "^24.0.15", + "@types/listr": "^0.14.0", + "@types/lodash.debounce": "^4.0.6", + "@types/lodash.flatten": "^4.4.6", + "@types/lodash.kebabcase": "^4.1.6", + "@types/lodash.startcase": "^4.4.6", + "@types/mock-fs": "^4.10.0", + "@types/node": "^14.0.19", + "@types/prompts": "^2.0.1", + "@types/supertest": "^2.0.8", + "@types/title": "^1.0.5", + "@types/window-size": "^0.2.4", + "cheerio": "^1.0.0-rc.2", + "listr-silent-renderer": "^1.1.1", + "mock-fs": "^4.12.0", + "nock": "^12.0.2", + "supertest": "^3.1.0", + "typescript": "^3.9.2" + }, + "files": [ + "bin/", + "dist/", + "LICENSE", + "README.md" + ] +} diff --git a/src/checks/check-account-sid.ts b/packages/twilio-run/src/checks/check-account-sid.ts similarity index 100% rename from src/checks/check-account-sid.ts rename to packages/twilio-run/src/checks/check-account-sid.ts diff --git a/src/checks/check-credentials.ts b/packages/twilio-run/src/checks/check-credentials.ts similarity index 100% rename from src/checks/check-credentials.ts rename to packages/twilio-run/src/checks/check-credentials.ts diff --git a/src/checks/check-service-sid.ts b/packages/twilio-run/src/checks/check-service-sid.ts similarity index 100% rename from src/checks/check-service-sid.ts rename to packages/twilio-run/src/checks/check-service-sid.ts diff --git a/src/checks/nodejs-version.ts b/packages/twilio-run/src/checks/nodejs-version.ts similarity index 100% rename from src/checks/nodejs-version.ts rename to packages/twilio-run/src/checks/nodejs-version.ts diff --git a/src/checks/project-structure.ts b/packages/twilio-run/src/checks/project-structure.ts similarity index 100% rename from src/checks/project-structure.ts rename to packages/twilio-run/src/checks/project-structure.ts diff --git a/src/cli.ts b/packages/twilio-run/src/cli.ts similarity index 100% rename from src/cli.ts rename to packages/twilio-run/src/cli.ts diff --git a/src/commands/activate.ts b/packages/twilio-run/src/commands/activate.ts similarity index 100% rename from src/commands/activate.ts rename to packages/twilio-run/src/commands/activate.ts diff --git a/src/commands/deploy.ts b/packages/twilio-run/src/commands/deploy.ts similarity index 100% rename from src/commands/deploy.ts rename to packages/twilio-run/src/commands/deploy.ts diff --git a/src/commands/list-templates.ts b/packages/twilio-run/src/commands/list-templates.ts similarity index 100% rename from src/commands/list-templates.ts rename to packages/twilio-run/src/commands/list-templates.ts diff --git a/src/commands/list.ts b/packages/twilio-run/src/commands/list.ts similarity index 100% rename from src/commands/list.ts rename to packages/twilio-run/src/commands/list.ts diff --git a/src/commands/logs.ts b/packages/twilio-run/src/commands/logs.ts similarity index 100% rename from src/commands/logs.ts rename to packages/twilio-run/src/commands/logs.ts diff --git a/src/commands/new.ts b/packages/twilio-run/src/commands/new.ts similarity index 100% rename from src/commands/new.ts rename to packages/twilio-run/src/commands/new.ts diff --git a/src/commands/shared.ts b/packages/twilio-run/src/commands/shared.ts similarity index 100% rename from src/commands/shared.ts rename to packages/twilio-run/src/commands/shared.ts diff --git a/src/commands/start.ts b/packages/twilio-run/src/commands/start.ts similarity index 100% rename from src/commands/start.ts rename to packages/twilio-run/src/commands/start.ts diff --git a/src/commands/types.ts b/packages/twilio-run/src/commands/types.ts similarity index 100% rename from src/commands/types.ts rename to packages/twilio-run/src/commands/types.ts diff --git a/src/commands/utils.ts b/packages/twilio-run/src/commands/utils.ts similarity index 100% rename from src/commands/utils.ts rename to packages/twilio-run/src/commands/utils.ts diff --git a/src/config/__mocks__/global.ts b/packages/twilio-run/src/config/__mocks__/global.ts similarity index 100% rename from src/config/__mocks__/global.ts rename to packages/twilio-run/src/config/__mocks__/global.ts diff --git a/src/config/__mocks__/utils.ts b/packages/twilio-run/src/config/__mocks__/utils.ts similarity index 100% rename from src/config/__mocks__/utils.ts rename to packages/twilio-run/src/config/__mocks__/utils.ts diff --git a/src/config/activate.ts b/packages/twilio-run/src/config/activate.ts similarity index 100% rename from src/config/activate.ts rename to packages/twilio-run/src/config/activate.ts diff --git a/src/config/deploy.ts b/packages/twilio-run/src/config/deploy.ts similarity index 100% rename from src/config/deploy.ts rename to packages/twilio-run/src/config/deploy.ts diff --git a/src/config/global.ts b/packages/twilio-run/src/config/global.ts similarity index 100% rename from src/config/global.ts rename to packages/twilio-run/src/config/global.ts diff --git a/src/config/list.ts b/packages/twilio-run/src/config/list.ts similarity index 100% rename from src/config/list.ts rename to packages/twilio-run/src/config/list.ts diff --git a/src/config/logs.ts b/packages/twilio-run/src/config/logs.ts similarity index 100% rename from src/config/logs.ts rename to packages/twilio-run/src/config/logs.ts diff --git a/src/config/start.ts b/packages/twilio-run/src/config/start.ts similarity index 100% rename from src/config/start.ts rename to packages/twilio-run/src/config/start.ts diff --git a/src/config/utils.ts b/packages/twilio-run/src/config/utils.ts similarity index 100% rename from src/config/utils.ts rename to packages/twilio-run/src/config/utils.ts diff --git a/src/config/utils/__mocks__/env.ts b/packages/twilio-run/src/config/utils/__mocks__/env.ts similarity index 100% rename from src/config/utils/__mocks__/env.ts rename to packages/twilio-run/src/config/utils/__mocks__/env.ts diff --git a/src/config/utils/__mocks__/mergeFlagsAndConfig.ts b/packages/twilio-run/src/config/utils/__mocks__/mergeFlagsAndConfig.ts similarity index 100% rename from src/config/utils/__mocks__/mergeFlagsAndConfig.ts rename to packages/twilio-run/src/config/utils/__mocks__/mergeFlagsAndConfig.ts diff --git a/src/config/utils/__mocks__/package-json.ts b/packages/twilio-run/src/config/utils/__mocks__/package-json.ts similarity index 100% rename from src/config/utils/__mocks__/package-json.ts rename to packages/twilio-run/src/config/utils/__mocks__/package-json.ts diff --git a/src/config/utils/credentials.ts b/packages/twilio-run/src/config/utils/credentials.ts similarity index 100% rename from src/config/utils/credentials.ts rename to packages/twilio-run/src/config/utils/credentials.ts diff --git a/src/config/utils/env.ts b/packages/twilio-run/src/config/utils/env.ts similarity index 100% rename from src/config/utils/env.ts rename to packages/twilio-run/src/config/utils/env.ts diff --git a/src/config/utils/mergeFlagsAndConfig.ts b/packages/twilio-run/src/config/utils/mergeFlagsAndConfig.ts similarity index 100% rename from src/config/utils/mergeFlagsAndConfig.ts rename to packages/twilio-run/src/config/utils/mergeFlagsAndConfig.ts diff --git a/src/config/utils/package-json.ts b/packages/twilio-run/src/config/utils/package-json.ts similarity index 100% rename from src/config/utils/package-json.ts rename to packages/twilio-run/src/config/utils/package-json.ts diff --git a/src/config/utils/service-name.ts b/packages/twilio-run/src/config/utils/service-name.ts similarity index 100% rename from src/config/utils/service-name.ts rename to packages/twilio-run/src/config/utils/service-name.ts diff --git a/src/index.ts b/packages/twilio-run/src/index.ts similarity index 100% rename from src/index.ts rename to packages/twilio-run/src/index.ts diff --git a/src/printers/activate.ts b/packages/twilio-run/src/printers/activate.ts similarity index 100% rename from src/printers/activate.ts rename to packages/twilio-run/src/printers/activate.ts diff --git a/src/printers/deploy.ts b/packages/twilio-run/src/printers/deploy.ts similarity index 100% rename from src/printers/deploy.ts rename to packages/twilio-run/src/printers/deploy.ts diff --git a/src/printers/list.ts b/packages/twilio-run/src/printers/list.ts similarity index 100% rename from src/printers/list.ts rename to packages/twilio-run/src/printers/list.ts diff --git a/src/printers/logs.ts b/packages/twilio-run/src/printers/logs.ts similarity index 100% rename from src/printers/logs.ts rename to packages/twilio-run/src/printers/logs.ts diff --git a/src/printers/new.ts b/packages/twilio-run/src/printers/new.ts similarity index 100% rename from src/printers/new.ts rename to packages/twilio-run/src/printers/new.ts diff --git a/src/printers/start.ts b/packages/twilio-run/src/printers/start.ts similarity index 100% rename from src/printers/start.ts rename to packages/twilio-run/src/printers/start.ts diff --git a/src/printers/utils.ts b/packages/twilio-run/src/printers/utils.ts similarity index 100% rename from src/printers/utils.ts rename to packages/twilio-run/src/printers/utils.ts diff --git a/src/runtime/internal/functionRunner.ts b/packages/twilio-run/src/runtime/internal/functionRunner.ts similarity index 100% rename from src/runtime/internal/functionRunner.ts rename to packages/twilio-run/src/runtime/internal/functionRunner.ts diff --git a/src/runtime/internal/request-logger.ts b/packages/twilio-run/src/runtime/internal/request-logger.ts similarity index 100% rename from src/runtime/internal/request-logger.ts rename to packages/twilio-run/src/runtime/internal/request-logger.ts diff --git a/src/runtime/internal/response.ts b/packages/twilio-run/src/runtime/internal/response.ts similarity index 100% rename from src/runtime/internal/response.ts rename to packages/twilio-run/src/runtime/internal/response.ts diff --git a/src/runtime/internal/route-cache.ts b/packages/twilio-run/src/runtime/internal/route-cache.ts similarity index 100% rename from src/runtime/internal/route-cache.ts rename to packages/twilio-run/src/runtime/internal/route-cache.ts diff --git a/src/runtime/internal/runtime-paths.ts b/packages/twilio-run/src/runtime/internal/runtime-paths.ts similarity index 100% rename from src/runtime/internal/runtime-paths.ts rename to packages/twilio-run/src/runtime/internal/runtime-paths.ts diff --git a/src/runtime/internal/runtime.ts b/packages/twilio-run/src/runtime/internal/runtime.ts similarity index 100% rename from src/runtime/internal/runtime.ts rename to packages/twilio-run/src/runtime/internal/runtime.ts diff --git a/src/runtime/route.ts b/packages/twilio-run/src/runtime/route.ts similarity index 100% rename from src/runtime/route.ts rename to packages/twilio-run/src/runtime/route.ts diff --git a/src/runtime/server.ts b/packages/twilio-run/src/runtime/server.ts similarity index 100% rename from src/runtime/server.ts rename to packages/twilio-run/src/runtime/server.ts diff --git a/src/runtime/utils/inspector.ts b/packages/twilio-run/src/runtime/utils/inspector.ts similarity index 100% rename from src/runtime/utils/inspector.ts rename to packages/twilio-run/src/runtime/utils/inspector.ts diff --git a/src/serverless-api/utils.ts b/packages/twilio-run/src/serverless-api/utils.ts similarity index 100% rename from src/serverless-api/utils.ts rename to packages/twilio-run/src/serverless-api/utils.ts diff --git a/src/templating/actions.ts b/packages/twilio-run/src/templating/actions.ts similarity index 100% rename from src/templating/actions.ts rename to packages/twilio-run/src/templating/actions.ts diff --git a/src/templating/data.ts b/packages/twilio-run/src/templating/data.ts similarity index 100% rename from src/templating/data.ts rename to packages/twilio-run/src/templating/data.ts diff --git a/src/templating/filesystem.ts b/packages/twilio-run/src/templating/filesystem.ts similarity index 100% rename from src/templating/filesystem.ts rename to packages/twilio-run/src/templating/filesystem.ts diff --git a/src/types.d.ts b/packages/twilio-run/src/types.d.ts similarity index 100% rename from src/types.d.ts rename to packages/twilio-run/src/types.d.ts diff --git a/src/types/generic.ts b/packages/twilio-run/src/types/generic.ts similarity index 100% rename from src/types/generic.ts rename to packages/twilio-run/src/types/generic.ts diff --git a/src/utils/debug.ts b/packages/twilio-run/src/utils/debug.ts similarity index 100% rename from src/utils/debug.ts rename to packages/twilio-run/src/utils/debug.ts diff --git a/src/utils/error-html.ts b/packages/twilio-run/src/utils/error-html.ts similarity index 100% rename from src/utils/error-html.ts rename to packages/twilio-run/src/utils/error-html.ts diff --git a/src/utils/fs.ts b/packages/twilio-run/src/utils/fs.ts similarity index 100% rename from src/utils/fs.ts rename to packages/twilio-run/src/utils/fs.ts diff --git a/src/utils/logger.ts b/packages/twilio-run/src/utils/logger.ts similarity index 100% rename from src/utils/logger.ts rename to packages/twilio-run/src/utils/logger.ts diff --git a/src/utils/output.ts b/packages/twilio-run/src/utils/output.ts similarity index 100% rename from src/utils/output.ts rename to packages/twilio-run/src/utils/output.ts diff --git a/src/utils/stack-trace/clean-up.ts b/packages/twilio-run/src/utils/stack-trace/clean-up.ts similarity index 100% rename from src/utils/stack-trace/clean-up.ts rename to packages/twilio-run/src/utils/stack-trace/clean-up.ts diff --git a/src/utils/stack-trace/helpers.ts b/packages/twilio-run/src/utils/stack-trace/helpers.ts similarity index 100% rename from src/utils/stack-trace/helpers.ts rename to packages/twilio-run/src/utils/stack-trace/helpers.ts diff --git a/tsconfig.json b/packages/twilio-run/tsconfig.json similarity index 83% rename from tsconfig.json rename to packages/twilio-run/tsconfig.json index 5b2ecd36..aaa06045 100644 --- a/tsconfig.json +++ b/packages/twilio-run/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "./tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "declaration": true, "outDir": "./dist" /* Redirect output structure to the directory. */, diff --git a/packages/twilio-run/tsconfig.test.json b/packages/twilio-run/tsconfig.test.json new file mode 100644 index 00000000..8dabc9e8 --- /dev/null +++ b/packages/twilio-run/tsconfig.test.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "incremental": true + } +} From 903e9980866fd1e58de14996a3946bd6d3e1c191 Mon Sep 17 00:00:00 2001 From: Dominik Kundel Date: Fri, 7 Aug 2020 18:08:36 -0700 Subject: [PATCH 3/4] docs: move docs from serverless-toolkit --- DESIGN.md | 94 +++++++++++++++++++++++ README.md | 46 +++++++++++ images/squared-serverless-logo-small.png | Bin 0 -> 51026 bytes 3 files changed, 140 insertions(+) create mode 100644 DESIGN.md create mode 100644 README.md create mode 100644 images/squared-serverless-logo-small.png diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 00000000..dc29a7d6 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,94 @@ +# Design of the Serverless Toolkit + +The Serverless Toolkit is broken up into a variety of sub-projects that serve +different purposes. In order to guide contributors for any contributions to the +Serverless Toolkit, we wrote a set of guidelines that should be taken into +consideration. + +- [Design of the Serverless Toolkit](#design-of-the-serverless-toolkit) + - [1. Modularity](#1-modularity) + - [2. Designed for Twilio Functions development first](#2-designed-for-twilio-functions-development-first) + - [3. From Node.js Developers for Node.js Developers](#3-from-nodejs-developers-for-nodejs-developers) + - [4. The Toolkit should work standalone](#4-the-toolkit-should-work-standalone) + - [5. Convention over configuration](#5-convention-over-configuration) + - [6. Convenience over scriptability](#6-convenience-over-scriptability) + +## 1. Modularity + +While all modules together form the Serverless Toolkit, we offer with the +different modules a way for people to use different parts of the project. + +For example the [Serverless Framework Integration](https://github.com/twilio-labs/serverless-framework-integration) makes use of [`@twilio-labs/serverless-api`] but not of any of the CLI functionality. + +Right now the project breaks down into the following modules: + +| Project | Content | +| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`twilio-run`] | Core CLI logic of the Serverless Toolkit | +| [`create-twilio-function`] | CLI logic for creating a new project. This can be called with `npm init twilio-function` and therefore should stay separate | +| [`@twilio-labs/plugin-serverless`] | A thin wrapper exposing the commands of [`twilio-run`] and [`create-twilio-function`] to the [Twilio CLI] | +| [`@twilio-labs/serverless-api`] | The core logic that interacts with the REST API. This should not include any CLI-related code. It should instead expose [EventEmitter](https://nodejs.org/api/events.html) or [Streams](https://nodejs.org/api/streams.html). | +| [`function-templates`] | The repository hosting all Twilio Function templates exposed by the CLI toolings | +| [`@twilio-labs/serverless-twilio-runtime`] | Twilio Runtime integration for the [Serverless Framework](https://serverless.com/) | +| [`@twilio-labs/serverless-runtime-types`] | TypeScript definitions for the Twilio Runtime environment | + +## 2. Designed for Twilio Functions development first + +The tooling has some inconsistencies with other tooling of the [Twilio CLI]. + +For example this tooling uses `ACCOUNT_SID` and `AUTH_TOKEN` in the `.env` file +but the [Twilio CLI] and other tools use `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN`. + +This is by design because the Twilio Runtime will expose `ACCOUNT_SID` and +`AUTH_TOKEN` to the user instead. + +## 3. From Node.js Developers for Node.js Developers + +Whenever possible the tooling should not introduce unnecessary configuration but +make it intuitive for any Node.js developer to use it. Some examples: + +- `npm install ` should just install a dependency +- Adding an environment variable to the `.env` file should expose it to `process.env` + +## 4. The Toolkit should work standalone + +This goes inline with #3. A project should be able to be used by anyone who didn't use +Twilio before. As a result setup instructions of any Serverless project should be as +easy as: + +``` +git clone ... project +cd project +npm install +npm start +``` + +Therefore, you should be able to install the Toolkit as a developer dependency +using: + +``` +npm install --save-dev twilio-run +``` + +## 5. Convention over configuration + +Whenever we can avoid the developers having to learn and create configuration, we should. + +For example we should prefer the filesystem to infer information rather than +having an explicit configuration file. + +## 6. Convenience over scriptability + +While scriptability is important, the CLI part of the Toolkit should not be a thin-wrapper +of the REST API to allow Shell scripting. This is a good use case for the [Twilio CLI]. + +Instead it should focus on creating usable and convenient commands with as little configuration as possible. + +[`twilio-run`]: https://npm.im/twilio-run +[`create-twilio-function`]: https://npm.im/create-twilio-function +[`@twilio-labs/plugin-serverless`]: https://npm.im/@twilio-labs/plugin-serverless +[`@twilio-labs/serverless-api`]: https://npm.im/@twilio-labs/serverless-api +[`@twilio-labs/serverless-runtime-types`]: https://npm.im/@twilio-labs/serverless-runtime-types +[`@twilio-labs/serverless-twilio-runtime`]: https://npm.im/@twilio-labs/serverless-twilio-runtime +[`function-templates`]: https://github.com/twilio-labs/function-templates +[twilio cli]: https://twilio.com/docs/cli diff --git a/README.md b/README.md new file mode 100644 index 00000000..85615c2f --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +

Seagull with a French Fry*

+

Serverless Toolkit

+

Part of Twilio Labs Banner

+ +## What is the Serverless Toolkit? + +The [Serverless Toolkit](https://www.twilio.com/docs/labs/serverless-toolkit) is CLI tooling to help you develop locally and deploy to the [Twilio Runtime](https://www.twilio.com/runtime). + +There are two ways you can use the toolkit. If you are already using the [Twilio CLI](https://www.twilio.com/docs/twilio-cli), you can install it via a plugin. Alternatively, you can use the toolkit as a standalone using [twilio-run](https://npm.im/twilio-run) via npm or another Node.js package manager. + +Throughout the [docs](https://www.twilio.com/docs/labs/serverless-toolkit), you can switch in the code snippets between Twilio-CLI and Bash Session to get the commands for both versions. + +## Let's work together + +Everything in this toolkit is released under [Twilio Labs](https://www.twilio.com/docs/labs) and fully open-source. If you find any problems with this, [please file an issue](https://github.com/twilio-labs/serverless-toolkit/issues) or even create a pull request to work together with us on the toolkit. We would love to hear your ideas and feedback! + +## Project Structure & Contributing + +This project is a monorepo, meaning it contains multiple packages in one repository. It consists out of the following packages: + +- [`twilio-run`](packages/twilio-run) - The underlying CLI tool +- [`plugin-serverless`](https://github.com/twilio-labs/plugin-serverless) - Exposes the `twilio-run` CLI into the [Twilio CLI](https://www.twilio.com/docs/twilio-cli) +- [`create-twilio-function`](https://github.com/twilio-labs/create-twilio-function) - Handles templating and bootstrapping of new projects and Functions +- [`serverless-api`](https://github.com/twilio-labs/serverless-api) - The module used to interact with the actual [Serverless API](https://github.com/twilio-labs/serverless-api) +- [`function-templates`](https://github.com/twilio-labs/function-templates) - The templates used by the toolkit to create new Functions + +To understand more about the structure and the design of the Toolkit check out the [design documentation](DESIGN.md). + +## Setup & Development + +This project uses [`lerna`](https://npm.im/lerna) as a tool to manage the monorepo. If you are unfamiliar with the tool, start by checking out the the [lerna docs](https://lerna.js.org/). + +```bash +git clone git@github.com:twilio-labs/twilio-run.git serverless-toolkit +cd serverless-toolkit +npm install +npm run bootstrap +``` + +## License + +MIT + +## Disclaimer + +Unofficial logo. Not a Twilio logo. diff --git a/images/squared-serverless-logo-small.png b/images/squared-serverless-logo-small.png new file mode 100644 index 0000000000000000000000000000000000000000..2c240287ee6ba9aae66800e61a8ea75df089e039 GIT binary patch literal 51026 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 z Date: Fri, 7 Aug 2020 18:10:32 -0700 Subject: [PATCH 4/4] docs(readme): fix link to issues --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85615c2f..9ae5bb80 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Throughout the [docs](https://www.twilio.com/docs/labs/serverless-toolkit), you ## Let's work together -Everything in this toolkit is released under [Twilio Labs](https://www.twilio.com/docs/labs) and fully open-source. If you find any problems with this, [please file an issue](https://github.com/twilio-labs/serverless-toolkit/issues) or even create a pull request to work together with us on the toolkit. We would love to hear your ideas and feedback! +Everything in this toolkit is released under [Twilio Labs](https://www.twilio.com/docs/labs) and fully open-source. If you find any problems with this, [please file an issue](https://github.com/twilio-labs/twilio-run/issues) or even create a pull request to work together with us on the toolkit. We would love to hear your ideas and feedback! ## Project Structure & Contributing