From c1b1e18613de34615a5549ea82f316f3f3b23ffd Mon Sep 17 00:00:00 2001 From: Timothy Jones Date: Wed, 11 Oct 2023 12:26:23 +1100 Subject: [PATCH] chore: Initial commit for case-connector --- .release-please-manifest.json | 3 +- package-lock.json | 82 ++++++++ packages/case-connector/.eslintrc.json | 161 +++++++++++++++ packages/case-connector/.gitignore | 2 + packages/case-connector/.npmignore | 20 ++ packages/case-connector/.prettierrc | 3 + packages/case-connector/CHANGELOG.md | 0 packages/case-connector/LICENSE | 29 +++ packages/case-connector/README.md | 10 + packages/case-connector/index.ts | 1 + packages/case-connector/jest.config.ts | 191 ++++++++++++++++++ packages/case-connector/package.json | 88 ++++++++ .../case-connector/src/connectors/define.js | 107 ++++++++++ .../case-connector/src/connectors/define.ts | 167 +++++++++++++++ .../case-connector/src/connectors/types.js | 0 .../case-connector/src/connectors/types.ts | 0 packages/case-connector/src/index.js | 42 ++++ packages/case-connector/src/index.ts | 42 ++++ packages/case-connector/src/types.js | 3 + packages/case-connector/src/types.ts | 9 + packages/case-connector/src/versionString.js | 11 + packages/case-connector/src/versionString.ts | 12 ++ packages/case-connector/tsconfig.build.json | 14 ++ packages/case-connector/tsconfig.json | 33 +++ release-please-config.json | 5 + 25 files changed, 1034 insertions(+), 1 deletion(-) create mode 100644 packages/case-connector/.eslintrc.json create mode 100644 packages/case-connector/.gitignore create mode 100644 packages/case-connector/.npmignore create mode 100644 packages/case-connector/.prettierrc create mode 100644 packages/case-connector/CHANGELOG.md create mode 100644 packages/case-connector/LICENSE create mode 100644 packages/case-connector/README.md create mode 100644 packages/case-connector/index.ts create mode 100644 packages/case-connector/jest.config.ts create mode 100644 packages/case-connector/package.json create mode 100644 packages/case-connector/src/connectors/define.js create mode 100644 packages/case-connector/src/connectors/define.ts create mode 100644 packages/case-connector/src/connectors/types.js create mode 100644 packages/case-connector/src/connectors/types.ts create mode 100644 packages/case-connector/src/index.js create mode 100644 packages/case-connector/src/index.ts create mode 100644 packages/case-connector/src/types.js create mode 100644 packages/case-connector/src/types.ts create mode 100644 packages/case-connector/src/versionString.js create mode 100644 packages/case-connector/src/versionString.ts create mode 100644 packages/case-connector/tsconfig.build.json create mode 100644 packages/case-connector/tsconfig.json diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 57e806ea..6d304181 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -7,5 +7,6 @@ "packages/test-equivalence-matchers": "0.13.0", "packages/documentation": "0.0.6", ".": "0.13.0", - "packages/contract-case-cli": "0.1.4" + "packages/contract-case-cli": "0.1.4", + "packages/case-connector": "0.6.3" } diff --git a/package-lock.json b/package-lock.json index b0e31902..bdb4c2dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2594,6 +2594,10 @@ "resolved": "packages/case-boundary", "link": true }, + "node_modules/@contract-case/case-connector": { + "resolved": "packages/case-connector", + "link": true + }, "node_modules/@contract-case/case-core": { "resolved": "packages/case-core", "link": true @@ -6454,6 +6458,12 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, + "node_modules/@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.4", "license": "MIT", @@ -23961,6 +23971,42 @@ "@contract-case/test-equivalence-matchers": "0.13.0" } }, + "packages/case-connector": { + "name": "@contract-case/case-connector", + "version": "0.6.3", + "license": "BSD-3-Clause", + "dependencies": { + "@contract-case/case-boundary": "0.6.3", + "read-pkg-up": "^7.0.1", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@contract-case/case-boundary": "0.6.3", + "@types/jest": "^29.5.2", + "@types/uuid": "^9.0.2", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-import-resolver-typescript": "^3.5.3", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-tsdoc": "^0.2.17", + "prettier": "^2.8.7", + "rimraf": "^5.0.1", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1" + } + }, + "packages/case-connector/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "packages/case-core": { "name": "@contract-case/case-core", "version": "0.13.0", @@ -26124,6 +26170,36 @@ "ts-node": "^10.9.1" } }, + "@contract-case/case-connector": { + "version": "file:packages/case-connector", + "requires": { + "@contract-case/case-boundary": "0.6.3", + "@types/jest": "^29.5.2", + "@types/uuid": "*", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-import-resolver-typescript": "^3.5.3", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-tsdoc": "^0.2.17", + "prettier": "^2.8.7", + "read-pkg-up": "^7.0.1", + "rimraf": "^5.0.1", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1", + "uuid": "^9.0.0" + }, + "dependencies": { + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + } + } + }, "@contract-case/case-core": { "version": "file:packages/case-core", "requires": { @@ -29138,6 +29214,12 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, + "@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, "@types/ws": { "version": "8.5.4", "requires": { diff --git a/packages/case-connector/.eslintrc.json b/packages/case-connector/.eslintrc.json new file mode 100644 index 00000000..82f79b04 --- /dev/null +++ b/packages/case-connector/.eslintrc.json @@ -0,0 +1,161 @@ +{ + "parser": "@typescript-eslint/parser", + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/typescript", + "airbnb-base", + "airbnb-typescript/base", + "prettier" + ], + "plugins": ["import", "@typescript-eslint", "eslint-plugin-tsdoc"], + "settings": { + "import/resolver": { + "typescript": { + "project": "tsconfig.json" + } + } + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module", + "project": "tsconfig.json" + }, + "ignorePatterns": ["jest.config.ts"], + "rules": { + "max-classes-per-file": "off", + "tsdoc/syntax": "error", + "camelcase": "off", + "no-console": "error", + "no-underscore-dangle": "off", + "import/prefer-default-export": "off", + "import/no-useless-path-segments": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/explicit-module-boundary-types": "error" + }, + + "overrides": [ + { + "files": ["example/**/*.ts"], + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module", + "project": "example/tsconfig.json" + }, + "rules": { + "no-restricted-imports": [ + "error", + { "patterns": ["src/connectors/*"] } + ], + + "import/no-extraneous-dependencies": [ + "error", + { "devDependencies": true } + ], + "no-console": "off" + } + }, + { + "files": ["src/__tests__/**/*.ts"], + "rules": { + "no-restricted-imports": "off" + } + }, + + { + "files": ["src/connectors/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { "patterns": ["**/boundaries", "**/boundaries/*"] } + ] + } + }, + { + "files": ["src/core/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + "**/connectors", + "**/connectors/*", + "**/boundaries", + "**/boundaries/*" + ] + } + ] + } + }, + { + "files": ["src/diffmatch/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + "**/core", + "**/core/*", + "**/connectors", + "**/connectors/*", + "**/boundaries", + "**/boundaries/*" + ] + } + ] + } + }, + { + "files": ["src/entities/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + "**/diffmatch", + "**/diffmatch/*", + "**/core", + "**/core/*", + "**/connectors", + "**/connectors/*", + "**/boundaries", + "**/boundaries/*" + ] + } + ] + } + }, + { + "files": ["*.js"], + "rules": { + "@typescript-eslint/no-var-requires": "off" + } + }, + { + "extends": "plugin:jest/recommended", + "files": ["**/*.test.ts", "**/*.spec.ts"], + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module", + "project": "tsconfig.spec.json" + }, + "env": { + "jest": true + }, + "plugins": ["jest"], + "rules": { + "no-unused-expressions": "off", + "no-restricted-imports": "off", + "@typescript-eslint/no-explicit-any": "off", + "jest/no-disabled-tests": "warn", + "jest/no-focused-tests": "error", + "jest/no-identical-title": "error", + "jest/prefer-to-have-length": "warn", + "jest/expect-expect": [ + "error", + { "assertFunctionNames": ["expect", "expectErrorContaining"] } + ] + } + } + ] +} diff --git a/packages/case-connector/.gitignore b/packages/case-connector/.gitignore new file mode 100644 index 00000000..a7e8e215 --- /dev/null +++ b/packages/case-connector/.gitignore @@ -0,0 +1,2 @@ +build +dist \ No newline at end of file diff --git a/packages/case-connector/.npmignore b/packages/case-connector/.npmignore new file mode 100644 index 00000000..e7069ff7 --- /dev/null +++ b/packages/case-connector/.npmignore @@ -0,0 +1,20 @@ + +# Exclude typescript source and config +*.ts +tsconfig.json + +# Include javascript files and typescript declarations +!*.js +!*.d.ts + +# Exclude jsii outdir +dist + +# Exclude IDE settings +.vscode + +# Include .jsii and .jsii.gz +!.jsii +!.jsii.gz + +coverage \ No newline at end of file diff --git a/packages/case-connector/.prettierrc b/packages/case-connector/.prettierrc new file mode 100644 index 00000000..544138be --- /dev/null +++ b/packages/case-connector/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/packages/case-connector/CHANGELOG.md b/packages/case-connector/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/packages/case-connector/LICENSE b/packages/case-connector/LICENSE new file mode 100644 index 00000000..54774713 --- /dev/null +++ b/packages/case-connector/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2023, Timothy Jones +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +- Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/case-connector/README.md b/packages/case-connector/README.md new file mode 100644 index 00000000..733e9079 --- /dev/null +++ b/packages/case-connector/README.md @@ -0,0 +1,10 @@ +# Case-Connector + +[![Build and test](https://github.com/case-contract-testing/case/actions/workflows/build-and-test.yml/badge.svg?branch=main)](https://github.com/case-contract-testing/case/actions/workflows/build-and-test.yml) +[![Known Vulnerabilities](https://snyk.io/test/github/case-contract-testing/case/badge.svg?targetFile=packages/case-boundary/package.json)](https://snyk.io/test/github/case-contract-testing/case?targetFile=packages/case-boundary/package.json) + +This is the server connector (alternative to the case-boundary) to allow ContractCase to be run as a server. + +Don't depend on this directly unless you are writing a custom wrapper for ContractCase. + +[Start here instead](https://case.contract-testing.io/docs/intro) diff --git a/packages/case-connector/index.ts b/packages/case-connector/index.ts new file mode 100644 index 00000000..8420b109 --- /dev/null +++ b/packages/case-connector/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/case-connector/jest.config.ts b/packages/case-connector/jest.config.ts new file mode 100644 index 00000000..f3543bfb --- /dev/null +++ b/packages/case-connector/jest.config.ts @@ -0,0 +1,191 @@ +/* + * For a detailed explanation regarding each configuration property and type check, visit: + * https://jestjs.io/docs/en/configuration.html + */ + +export default { + preset: 'ts-jest', + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/private/var/folders/35/09t_zsws5d9dnb6jvrwd92rw0000gp/T/jest_dy", + + // Automatically clear mock calls and instances between every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: true, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + coverageDirectory: 'coverage', + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: 'v8', + + // 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: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + moduleDirectories: ['node_modules', 'src'], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "json", + // "jsx", + // "ts", + // "tsx", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of 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: "failure-change", + + // A preset that is used as a base for Jest's configuration + // preset: undefined, + + // Run tests from one or more projects + // projects: undefined, + + // 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: undefined, + + // Automatically restore mock state between every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // 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: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + testEnvironment: 'node', + + // 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__/**/(*.)+(spec|test).[jt]s?(x)', + '**/?(*.)+(spec|test).[tj]s?(x)', + ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + testPathIgnorePatterns: ['/node_modules/', '/dist/'], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // 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: "http://localhost", + + // 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: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // 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: undefined, + + // 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/packages/case-connector/package.json b/packages/case-connector/package.json new file mode 100644 index 00000000..0458f174 --- /dev/null +++ b/packages/case-connector/package.json @@ -0,0 +1,88 @@ +{ + "name": "@contract-case/case-connector", + "version": "0.6.3", + "description": "Connector to allow ContractCase to run as a server. Use only if you're creating a custom wrapper for a new language", + "author": "Timothy Jones (https://github.com/TimothyJones)", + "homepage": "https://case.contract-testing.io/docs", + "license": "BSD-3-Clause", + "main": "build/index.js", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/case-contract-testing/case.git" + }, + "scripts": { + "build": "rimraf dist && tsc --project tsconfig.build.json", + "lint": "eslint src --ext .ts --config .eslintrc.json", + "lint:fix": "eslint src --fix --ext .ts --config .eslintrc.json", + "format:base": "prettier --parser typescript \"src/**/*.ts\"", + "format:check": "npm run format:base -- --list-different", + "format:fix": "npm run format:base -- --write " + }, + "bugs": { + "url": "https://github.com/case-contract-testing/case/issues" + }, + "devDependencies": { + "@contract-case/case-boundary": "0.6.3", + "@types/jest": "^29.5.2", + "@types/uuid": "^9.0.2", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-import-resolver-typescript": "^3.5.3", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-tsdoc": "^0.2.17", + "prettier": "^2.8.7", + "rimraf": "^5.0.1", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1" + }, + "dependencies": { + "@contract-case/case-boundary": "0.6.3", + "read-pkg-up": "^7.0.1", + "uuid": "^9.0.0" + }, + "stability": "stable", + "types": "build/index.d.ts", + "nx": { + "tasksRunnerOptions": { + "default": { + "runner": "nx/tasks-runners/default", + "options": { + "cacheableOperations": [ + "build", + "package", + "lint", + "format:check", + "test" + ] + } + } + }, + "targetDefaults": { + "prebuild": { + "dependsOn": [ + "^prebuild" + ] + }, + "build": { + "dependsOn": [ + "^build" + ], + "outputs": [ + "{projectRoot}/build" + ] + }, + "package": { + "outputs": [ + "{projectRoot}/dist" + ] + } + } + } +} diff --git a/packages/case-connector/src/connectors/define.js b/packages/case-connector/src/connectors/define.js new file mode 100644 index 00000000..9715cfe2 --- /dev/null +++ b/packages/case-connector/src/connectors/define.js @@ -0,0 +1,107 @@ +"use strict"; +/** + * Begin define + * - Begin define + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * - runExample + * Define ID + * json definition + * and config + * - runRejectingExample + * Define ID + * json definition + * and config + * - endRecord + * Define ID + * invalidates ID + */ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.endRecord = exports.runRejectingExample = exports.runExample = exports.beginDefinition = void 0; +var uuid_1 = require("uuid"); +var case_boundary_1 = require("@contract-case/case-boundary"); +var versionString_1 = require("../versionString"); +var ENDED_DEFINER = 'CLOSED'; +var DEFINING_CONTRACTS = {}; +var mapConfig = function (config, testRunId) { return (__assign(__assign({}, config), { testRunId: testRunId })); }; +var beginDefinition = function (config, callbackPrinter, resultPrinter, callerVersions) { + var id = (0, uuid_1.v4)(); + var definer = { + id: id, + definer: new case_boundary_1.BoundaryContractDefiner(mapConfig(config, id), callbackPrinter, resultPrinter, __spreadArray(__spreadArray([], callerVersions, true), [versionString_1.versionString], false)), + }; + DEFINING_CONTRACTS[id] = definer; + return id; +}; +exports.beginDefinition = beginDefinition; +var makeCoreError = function (message, location) { + return new case_boundary_1.BoundaryFailure(case_boundary_1.BoundaryFailureKindConstants.CASE_CORE_ERROR, message, location); +}; +var makeConfigurationError = function (message, location) { + return new case_boundary_1.BoundaryFailure(case_boundary_1.BoundaryFailureKindConstants.CASE_CONFIGURATION_ERROR, message, location); +}; +var getDefiner = function (defineId, methodName) { + var definerHandle = DEFINING_CONTRACTS[defineId]; + if (definerHandle === undefined) { + return makeCoreError("The defineId '".concat(defineId, "' doesn't have an associated handle.\n\nThis might happen if the case-connector methods are called out of order, or the wrong connector is contacted"), "case-connector::".concat(methodName)); + } + if (definerHandle === ENDED_DEFINER) { + return makeConfigurationError('runRejectingExample was called after endRecord was called', "case-connector::".concat(methodName)); + } + return definerHandle; +}; +var runExample = function (defineId, definition, config) { + return Promise.resolve().then(function () { + var definerHandle = getDefiner(defineId, 'runExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.runExample(definition, mapConfig(config, defineId)); + }); +}; +exports.runExample = runExample; +var runRejectingExample = function (defineId, definition, config) { + return Promise.resolve().then(function () { + var definerHandle = getDefiner(defineId, 'runRejectingExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.runRejectingExample(definition, mapConfig(config, defineId)); + }); +}; +exports.runRejectingExample = runRejectingExample; +var endRecord = function (defineId) { + return Promise.resolve().then(function () { + var definerHandle = getDefiner(defineId, 'runExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.endRecord(); + }); +}; +exports.endRecord = endRecord; diff --git a/packages/case-connector/src/connectors/define.ts b/packages/case-connector/src/connectors/define.ts new file mode 100644 index 00000000..ce3ba63e --- /dev/null +++ b/packages/case-connector/src/connectors/define.ts @@ -0,0 +1,167 @@ +/** + * Begin define + * - Begin define + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * - runExample + * Define ID + * json definition + * and config + * - runRejectingExample + * Define ID + * json definition + * and config + * - endRecord + * Define ID + * invalidates ID + */ + +import { v4 as uuid4 } from 'uuid'; +import { + BoundaryContractDefiner, + BoundaryFailure, + BoundaryFailureKindConstants, + BoundaryMockDefinition, + BoundaryResult, + BoundaryStateHandler, + ContractCaseBoundaryConfig, + ILogPrinter, + IResultPrinter, + ITriggerFunction, +} from '@contract-case/case-boundary'; +import { versionString } from '../versionString'; + +const ENDED_DEFINER = 'CLOSED' as const; + +type DefinitionContainer = + | { id: string; definer: BoundaryContractDefiner } + | typeof ENDED_DEFINER; + +type ContractCaseConnectorConfig = { + providerName: string; + consumerName: string; + logLevel: string; + contractDir: string; + contractFilename: string; + + publish: string; + brokerCiAccessToken: string; + brokerBaseUrl: string; + brokerBasicAuth: { username: string; password: string }; + + baseUrlUnderTest: string; + printResults: boolean; + throwOnFail: boolean; + + stateHandlers: Record; + triggerAndTests: Record; + triggerAndTest: ITriggerFunction; +}; + +type DefinitionId = string; + +type ExampleDefinition = BoundaryMockDefinition; + +const DEFINING_CONTRACTS: Record = {}; + +const mapConfig = ( + config: ContractCaseConnectorConfig, + testRunId: string +): Required => ({ ...config, testRunId }); + +export const beginDefinition = ( + config: ContractCaseConnectorConfig, + callbackPrinter: ILogPrinter, + resultPrinter: IResultPrinter, + callerVersions: string[] +): DefinitionId => { + const id = uuid4(); + const definer = { + id, + definer: new BoundaryContractDefiner( + mapConfig(config, id), + callbackPrinter, + resultPrinter, + [...callerVersions, versionString] + ), + }; + DEFINING_CONTRACTS[id] = definer; + return id; +}; + +const makeCoreError = (message: string, location: string) => + new BoundaryFailure( + BoundaryFailureKindConstants.CASE_CORE_ERROR, + message, + location + ); + +const makeConfigurationError = (message: string, location: string) => + new BoundaryFailure( + BoundaryFailureKindConstants.CASE_CONFIGURATION_ERROR, + message, + location + ); + +const getDefiner = (defineId: DefinitionId, methodName: string) => { + const definerHandle = DEFINING_CONTRACTS[defineId]; + if (definerHandle === undefined) { + return makeCoreError( + `The defineId '${defineId}' doesn't have an associated handle.\n\nThis might happen if the case-connector methods are called out of order, or the wrong connector is contacted`, + `case-connector::${methodName}` + ); + } + if (definerHandle === ENDED_DEFINER) { + return makeConfigurationError( + 'runRejectingExample was called after endRecord was called', + `case-connector::${methodName}` + ); + } + return definerHandle; +}; + +export const runExample = ( + defineId: string, + definition: ExampleDefinition, + config: ContractCaseConnectorConfig +): Promise => + Promise.resolve().then(() => { + const definerHandle = getDefiner(defineId, 'runExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.runExample( + definition, + mapConfig(config, defineId) + ); + }); + +export const runRejectingExample = ( + defineId: string, + definition: ExampleDefinition, + config: ContractCaseConnectorConfig +): Promise => + Promise.resolve().then(() => { + const definerHandle = getDefiner(defineId, 'runRejectingExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.runRejectingExample( + definition, + mapConfig(config, defineId) + ); + }); + +export const endRecord = (defineId: string): Promise => + Promise.resolve().then(() => { + const definerHandle = getDefiner(defineId, 'runExample'); + if (!('id' in definerHandle)) { + return definerHandle; + } + return definerHandle.definer.endRecord(); + }); diff --git a/packages/case-connector/src/connectors/types.js b/packages/case-connector/src/connectors/types.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/case-connector/src/connectors/types.ts b/packages/case-connector/src/connectors/types.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/case-connector/src/index.js b/packages/case-connector/src/index.js new file mode 100644 index 00000000..6caa34ce --- /dev/null +++ b/packages/case-connector/src/index.js @@ -0,0 +1,42 @@ +/** + * Begin define + * - Begin define + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * - runExample + * Define ID + * json definition + * and config + * - runRejectingExample + * Define ID + * json definition + * and config + * - endRecord + * Define ID + * invalidates ID + * + * + * Verify + * - Begin Verify + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * + * - availableContractDescriptions + * - Verifier ID + * - Returns CaseContractDescription + * + * - runVerification + * - Verifier ID + * - map config + * + */ diff --git a/packages/case-connector/src/index.ts b/packages/case-connector/src/index.ts new file mode 100644 index 00000000..6caa34ce --- /dev/null +++ b/packages/case-connector/src/index.ts @@ -0,0 +1,42 @@ +/** + * Begin define + * - Begin define + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * - runExample + * Define ID + * json definition + * and config + * - runRejectingExample + * Define ID + * json definition + * and config + * - endRecord + * Define ID + * invalidates ID + * + * + * Verify + * - Begin Verify + * - Config + * - Statehandlers need to be callbacks + * - triggerAndTest needs to be a callback + * - LogPrinter is a callback + * - resultPrinter is a callback + * - Parent Versions + * - Returns ID + * + * - availableContractDescriptions + * - Verifier ID + * - Returns CaseContractDescription + * + * - runVerification + * - Verifier ID + * - map config + * + */ diff --git a/packages/case-connector/src/types.js b/packages/case-connector/src/types.js new file mode 100644 index 00000000..2b5963b5 --- /dev/null +++ b/packages/case-connector/src/types.js @@ -0,0 +1,3 @@ +"use strict"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/case-connector/src/types.ts b/packages/case-connector/src/types.ts new file mode 100644 index 00000000..eb53ebd0 --- /dev/null +++ b/packages/case-connector/src/types.ts @@ -0,0 +1,9 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export interface BoundaryMockDefinition { + // TODO: Types for states + readonly states: Array; + readonly definition: any; +} + +export type BoundaryAnyMatcher = any; diff --git a/packages/case-connector/src/versionString.js b/packages/case-connector/src/versionString.js new file mode 100644 index 00000000..84e620f7 --- /dev/null +++ b/packages/case-connector/src/versionString.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.versionString = void 0; +var readPackage = require("read-pkg-up"); +var pkg = readPackage.sync({ cwd: __dirname }) || { + packageJson: { + name: __dirname, + version: 'unknown', + }, +}; +exports.versionString = "".concat(pkg.packageJson.name, "@").concat(pkg.packageJson.version || 'UNKNOWN-VERSION').replace('@contract-case/', ''); diff --git a/packages/case-connector/src/versionString.ts b/packages/case-connector/src/versionString.ts new file mode 100644 index 00000000..64def547 --- /dev/null +++ b/packages/case-connector/src/versionString.ts @@ -0,0 +1,12 @@ +import * as readPackage from 'read-pkg-up'; + +const pkg = readPackage.sync({ cwd: __dirname }) || { + packageJson: { + name: __dirname, + version: 'unknown', + }, +}; + +export const versionString = `${pkg.packageJson.name}@${ + pkg.packageJson.version || 'UNKNOWN-VERSION' +}`.replace('@contract-case/', ''); diff --git a/packages/case-connector/tsconfig.build.json b/packages/case-connector/tsconfig.build.json new file mode 100644 index 00000000..2db60cfb --- /dev/null +++ b/packages/case-connector/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "include": ["package.json", "src/**/*.ts"], + "exclude": [ + "jest.config.ts", + "dist/**/*.js", + "example/*", + "src/__tests__/*", + "**/*.spec.verify.ts", + "**/*.spec.ts", + "**/*.test.ts", + "coverage" + ] +} diff --git a/packages/case-connector/tsconfig.json b/packages/case-connector/tsconfig.json new file mode 100644 index 00000000..16067057 --- /dev/null +++ b/packages/case-connector/tsconfig.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "composite": true, + "declarationMap": true, + "sourceMap": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "declaration": true, + "esModuleInterop": true, + "exactOptionalPropertyTypes": true, + "forceConsistentCasingInFileNames": true, + "lib": ["es2022"], + "module": "commonjs", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "outDir": "./dist/", + "resolveJsonModule": true, + "rootDir": ".", + "skipLibCheck": true, + "strict": true, + "target": "es2022" + }, + "display": "Node LTS + Strictest", + "exclude": ["jest.config.ts", "dist/**/*.js", "example/*", "coverage", "dist"] +} diff --git a/release-please-config.json b/release-please-config.json index 402b709f..1bb1e551 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -22,6 +22,7 @@ "include-component-in-tag": false, "exclude-paths": [ "packages/case-boundary", + "packages/case-connector", "packages/contract-case-cli", "packages/contract-case-jest", "packages/documentation" @@ -73,6 +74,10 @@ "packages/contract-case-jest": { "component": "@contract-case/contract-case-jest", "changelog-path": "CHANGELOG.md" + }, + "packages/case-connector": { + "component": "@contract-case/case-connector", + "changelog-path": "CHANGELOG.md" } } }