From cbbd490a4397fa7f2c724bcb2b3a3cf1658a6048 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 31 May 2023 17:33:38 +0200 Subject: [PATCH 01/68] wip --- packages/nodejs/index.ts | 13 +++++++++++++ packages/nodejs/package.json | 27 +++++++++++++++++++++++++++ packages/nodejs/src/abby.ts | 12 ++++++++++++ packages/nodejs/src/createAbby.ts | 28 ++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 packages/nodejs/index.ts create mode 100644 packages/nodejs/package.json create mode 100644 packages/nodejs/src/abby.ts create mode 100644 packages/nodejs/src/createAbby.ts diff --git a/packages/nodejs/index.ts b/packages/nodejs/index.ts new file mode 100644 index 00000000..56eaa3a6 --- /dev/null +++ b/packages/nodejs/index.ts @@ -0,0 +1,13 @@ +import express from "express" +import { useFeatureFlag } from "./src/abby"; + +const app = express(); +const port = 3000; + +app.get('/', async (req, res) => { + if (await useFeatureFlag("lol")) { + res.send("not enabled") + } +}); + +app.listen(port, () => console.log(`Express app running on port ${port}!`)); \ No newline at end of file diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json new file mode 100644 index 00000000..c12bd14b --- /dev/null +++ b/packages/nodejs/package.json @@ -0,0 +1,27 @@ +{ + "name": "my-express-app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "dev": "tsnd --respawn index.ts" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@tryabby/core": "workspace:^", + "axios": "^1.4.0", + "express": "^4.18.2", + "node-fetch": "^3.3.1", + "ts-toolbelt": "^9.6.0", + "typescript": "^5.0.4" + }, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/node": "^20.2.5", + "ts-node-dev": "^2.0.0" + } +} \ No newline at end of file diff --git a/packages/nodejs/src/abby.ts b/packages/nodejs/src/abby.ts new file mode 100644 index 00000000..4dd016ee --- /dev/null +++ b/packages/nodejs/src/abby.ts @@ -0,0 +1,12 @@ +import { createAbby } from "./createAbby"; + +export const { useFeatureFlag } = createAbby({ + projectId: "clfn3hs1t0002kx08x3kidi80", + currentEnvironment: process.env.NODE_ENV, + tests: { + "New Test3": { + variants: ["A", "B"], + }, + }, + flags: ["lol", "test3", "testAbby"], +}); diff --git a/packages/nodejs/src/createAbby.ts b/packages/nodejs/src/createAbby.ts new file mode 100644 index 00000000..c3cc3ac2 --- /dev/null +++ b/packages/nodejs/src/createAbby.ts @@ -0,0 +1,28 @@ +import { ABConfig, Abby, AbbyConfig, HttpService, ABBY_BASE_URL } from "@tryabby/core"; +import { F } from "ts-toolbelt" +// import fetch from 'node-fetch'; + +export function createAbby< + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig +>(abbyConfig: F.Narrow>) { + const abby = new Abby( + abbyConfig + ); + + const useFeatureFlag = async [number]>( + name: F + ) => { + // const res = await fetch( + // `${ABBY_BASE_URL}api/dashboard/${abbyConfig.projectId}/data` + // ); + console.log(2) + return true + // await abby.loadProjectData() + // return abby.getFeatureFlag(name); + }; + + return { useFeatureFlag } +} \ No newline at end of file From 83de4ffee914fdd61134cd530b5ec42e64ec512a Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Wed, 31 May 2023 21:30:03 +0200 Subject: [PATCH 02/68] switch to nodemon --- packages/nodejs/package.json | 12 +- packages/nodejs/{ => src}/index.ts | 5 +- packages/nodejs/src/{ => lib}/abby.ts | 0 packages/nodejs/src/{ => lib}/createAbby.ts | 8 +- packages/nodejs/tsconfig.json | 104 ++++++++ pnpm-lock.yaml | 252 +++++++++++++++++--- 6 files changed, 334 insertions(+), 47 deletions(-) rename packages/nodejs/{ => src}/index.ts (73%) rename packages/nodejs/src/{ => lib}/abby.ts (100%) rename packages/nodejs/src/{ => lib}/createAbby.ts (71%) create mode 100644 packages/nodejs/tsconfig.json diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index c12bd14b..039ff4d3 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "dev": "tsnd --respawn index.ts" + "dev": "nodemon ./src/index.ts" }, "keywords": [], "author": "", @@ -14,14 +14,14 @@ "dependencies": { "@tryabby/core": "workspace:^", "axios": "^1.4.0", - "express": "^4.18.2", - "node-fetch": "^3.3.1", - "ts-toolbelt": "^9.6.0", - "typescript": "^5.0.4" + "express": "^4.18.2" }, "devDependencies": { "@types/express": "^4.17.17", "@types/node": "^20.2.5", - "ts-node-dev": "^2.0.0" + "nodemon": "^2.0.22", + "ts-node": "^10.9.1", + "ts-toolbelt": "^9.6.0", + "typescript": "^5.0.4" } } \ No newline at end of file diff --git a/packages/nodejs/index.ts b/packages/nodejs/src/index.ts similarity index 73% rename from packages/nodejs/index.ts rename to packages/nodejs/src/index.ts index 56eaa3a6..2877fcb2 100644 --- a/packages/nodejs/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,11 +1,12 @@ import express from "express" -import { useFeatureFlag } from "./src/abby"; +// import { useFeatureFlag } from "./lib/abby.ts"; +console.log("hi") const app = express(); const port = 3000; app.get('/', async (req, res) => { - if (await useFeatureFlag("lol")) { + if (1) { res.send("not enabled") } }); diff --git a/packages/nodejs/src/abby.ts b/packages/nodejs/src/lib/abby.ts similarity index 100% rename from packages/nodejs/src/abby.ts rename to packages/nodejs/src/lib/abby.ts diff --git a/packages/nodejs/src/createAbby.ts b/packages/nodejs/src/lib/createAbby.ts similarity index 71% rename from packages/nodejs/src/createAbby.ts rename to packages/nodejs/src/lib/createAbby.ts index c3cc3ac2..3cc61155 100644 --- a/packages/nodejs/src/createAbby.ts +++ b/packages/nodejs/src/lib/createAbby.ts @@ -1,6 +1,5 @@ import { ABConfig, Abby, AbbyConfig, HttpService, ABBY_BASE_URL } from "@tryabby/core"; import { F } from "ts-toolbelt" -// import fetch from 'node-fetch'; export function createAbby< FlagName extends string, @@ -14,14 +13,9 @@ export function createAbby< const useFeatureFlag = async [number]>( name: F - ) => { - // const res = await fetch( - // `${ABBY_BASE_URL}api/dashboard/${abbyConfig.projectId}/data` - // ); + ) => { console.log(2) return true - // await abby.loadProjectData() - // return abby.getFeatureFlag(name); }; return { useFeatureFlag } diff --git a/packages/nodejs/tsconfig.json b/packages/nodejs/tsconfig.json new file mode 100644 index 00000000..d8970ac0 --- /dev/null +++ b/packages/nodejs/tsconfig.json @@ -0,0 +1,104 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "ES5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "node16", /* Specify what module code is generated. */ + "rootDir": "./src", /* Specify the root folder within your source files. */ + "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "ts-node": { + "esm": true + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8060499..4f14e371 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: version: 2.8.8 turbo: specifier: latest - version: 1.9.9 + version: 1.9.5 apps/angular-example: dependencies: @@ -672,7 +672,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.9.9(eslint@7.32.0) + version: 1.9.5(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -751,6 +751,40 @@ importers: specifier: ^0.25.3 version: 0.25.8(jsdom@20.0.3) + packages/nodejs: + dependencies: + '@tryabby/core': + specifier: workspace:^ + version: link:../core + axios: + specifier: ^1.4.0 + version: 1.4.0 + express: + specifier: ^4.18.2 + version: 4.18.2 + devDependencies: + '@types/express': + specifier: ^4.17.17 + version: 4.17.17 + '@types/node': + specifier: ^20.2.5 + version: 20.2.5 + nodemon: + specifier: ^2.0.22 + version: 2.0.22 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) + ts-node-dev: + specifier: ^2.0.0 + version: 2.0.0(@types/node@20.2.5)(typescript@5.0.4) + ts-toolbelt: + specifier: ^9.6.0 + version: 9.6.0 + typescript: + specifier: ^5.0.4 + version: 5.0.4 + packages/react: dependencies: '@tryabby/core': @@ -7988,6 +8022,10 @@ packages: /@types/node@18.15.11: resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} + /@types/node@20.2.5: + resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==} + dev: true + /@types/nodemailer@6.4.7: resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} dependencies: @@ -8110,6 +8148,14 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true + /@types/strip-bom@3.0.0: + resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} + dev: true + + /@types/strip-json-comments@0.0.30: + resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} + dev: true + /@types/stripe-v3@3.1.28: resolution: {integrity: sha512-5poJyz1QFXpi1hE2bAWy7gFMdj5Fgofm94DNCaTK9V2LeWPdhCQIaP/6qUagZwgCcTURXzih1J7f3sjXH1cOsw==} dev: false @@ -9020,6 +9066,16 @@ packages: - debug dev: false + /axios@1.4.0: + resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} + dependencies: + follow-redirects: 1.15.2(debug@4.3.2) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query@2.2.0: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} @@ -10189,7 +10245,7 @@ packages: dependencies: ms: 2.0.0 - /debug@3.2.7: + /debug@3.2.7(supports-color@5.5.0): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -10198,6 +10254,7 @@ packages: optional: true dependencies: ms: 2.1.3 + supports-color: 5.5.0 /debug@4.3.2: resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==} @@ -10561,6 +10618,12 @@ packages: stream-shift: 1.0.1 dev: true + /dynamic-dedupe@0.3.0: + resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} + dependencies: + xtend: 4.0.2 + dev: true + /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true @@ -11203,19 +11266,19 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.9.9(eslint@7.32.0): - resolution: {integrity: sha512-OQLvRK9Ej/8HIEAW6e9hPu3nk1nCYWJ76voB4eOIaI2fYeIKC++0/r0zJPMOD8puo5V1DH+Gkd0XioKpL14ncg==} + /eslint-config-turbo@1.9.5(eslint@7.32.0): + resolution: {integrity: sha512-mV52KGcx65xQGckAqIC44kKA9Iv9B0QVHeFbl5ZoJ0SwyBJwug2bkdhnWh/KU/t3Wc3+5TpBHU8u2ygmB0nBbg==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.9.9(eslint@7.32.0) + eslint-plugin-turbo: 1.9.5(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) resolve: 1.22.1 transitivePeerDependencies: - supports-color @@ -11297,7 +11360,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 5.58.0(eslint@7.32.0)(typescript@4.9.3) - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) eslint: 7.32.0 eslint-import-resolver-node: 0.3.6 eslint-import-resolver-typescript: 2.7.1(eslint-plugin-import@2.26.0)(eslint@7.32.0) @@ -11496,8 +11559,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.9.9(eslint@7.32.0): - resolution: {integrity: sha512-BgtBMcgNd2YKiHbn1clRiEAmnlpSl19kt9yfIhFEsNIVPg2Gx0O1H++vWXGzMtT19mjHG4Unx0uIMRENKnDYLg==} + /eslint-plugin-turbo@1.9.5(eslint@7.32.0): + resolution: {integrity: sha512-fJW2uLWuv7J3tqJckjDKcApMNcqseV92kQoFMTZwSL5B1g8wJx0sAx9FcDpWgElFnqe2k63Iqz/DMZjdXI72aw==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -13045,6 +13108,10 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true + /ignore-walk@5.0.1: resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -15625,7 +15692,7 @@ packages: engines: {node: '>= 4.4.x'} requiresBuild: true dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) iconv-lite: 0.6.3 sax: 1.2.4 transitivePeerDependencies: @@ -15984,9 +16051,34 @@ packages: engines: {node: '>=6.0.0'} dev: false + /nodemon@2.0.22: + resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} + engines: {node: '>=8.10.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 5.7.1 + simple-update-notifier: 1.1.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: true + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + /nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true dependencies: abbrev: 1.1.1 @@ -17168,7 +17260,6 @@ packages: /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} @@ -17180,6 +17271,10 @@ packages: /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + /publint@0.1.11: resolution: {integrity: sha512-sD0rtIEadks83MkpomJswBO/YHExJLkta1TyqUhb0/aVV+o3ZlVnwsDPjCAow8tpfxmLGutCSLWq32yfhPB98w==} engines: {node: '>=16'} @@ -17786,6 +17881,7 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18048,6 +18144,7 @@ packages: /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} @@ -18733,6 +18830,11 @@ packages: min-indent: 1.0.1 dev: true + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -19264,6 +19366,13 @@ packages: engines: {node: '>=6'} dev: true + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + /tough-cookie@4.1.2: resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} engines: {node: '>=6'} @@ -19297,6 +19406,7 @@ packages: /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -19326,6 +19436,34 @@ packages: code-block-writer: 12.0.0 dev: true + /ts-node-dev@2.0.0(@types/node@20.2.5)(typescript@5.0.4): + resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} + engines: {node: '>=0.8.0'} + hasBin: true + peerDependencies: + node-notifier: '*' + typescript: '*' + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + chokidar: 3.5.3 + dynamic-dedupe: 0.3.0 + minimist: 1.2.7 + mkdirp: 1.0.4 + resolve: 1.22.1 + rimraf: 2.7.1 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + ts-node: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) + tsconfig: 7.0.0 + typescript: 5.0.4 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + dev: true + /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -19356,6 +19494,37 @@ packages: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.0.4): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 20.2.5 + acorn: 8.8.2 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + /ts-pattern@4.2.2: resolution: {integrity: sha512-qzJMo2pbkUJWusRH5o8xR+xogn6RmvViyUgwBFTtRENLse470clCGjHDf6haWGZ1AOmk8XkEohUoBW8Uut6Scg==} dev: false @@ -19380,6 +19549,15 @@ packages: strip-bom: 3.0.0 dev: true + /tsconfig@7.0.0: + resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} + dependencies: + '@types/strip-bom': 3.0.0 + '@types/strip-json-comments': 0.0.30 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + dev: true + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -19465,65 +19643,65 @@ packages: - supports-color dev: true - /turbo-darwin-64@1.9.9: - resolution: {integrity: sha512-UDGM9E21eCDzF5t1F4rzrjwWutcup33e7ZjNJcW/mJDPorazZzqXGKEPIy9kXwKhamUUXfC7668r6ZuA1WXF2Q==} + /turbo-darwin-64@1.9.5: + resolution: {integrity: sha512-rtVuXm4QH5oA+BU/Vv7mfu9y4ok2zmpqQJEnV3Fn+h+BNgFaPU5HOOEZNiBLVHvpefO9uUB7maU5IVc76w4VPA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.9.9: - resolution: {integrity: sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==} + /turbo-darwin-arm64@1.9.5: + resolution: {integrity: sha512-KH01n3GwpphOf3mx9pZoRBt0r9zZi0s5omDJorenN9hKDudTCLRhitbHyfCE9v/2x4hiX1zz8y/zET950YYCEw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.9.9: - resolution: {integrity: sha512-Fu1MY29Odg8dHOqXcpIIGC3T63XLOGgnGfbobXMKdrC7JQDvtJv8TUCYciRsyknZYjyyKK1z6zKuYIiDjf3KeQ==} + /turbo-linux-64@1.9.5: + resolution: {integrity: sha512-b1XXy/NReTe/sNiohCDcl8YTDe/WSnz+DPA9jPoBfKH4crF8QlIuPUDFHYFmBflAYdItD4htKxy+47ReCoES1w==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.9.9: - resolution: {integrity: sha512-50LI8NafPuJxdnMCBeDdzgyt1cgjQG7FwkyY336v4e95WJPUVjrHdrKH6jYXhOUyrv9+jCJxwX1Yrg02t5yJ1g==} + /turbo-linux-arm64@1.9.5: + resolution: {integrity: sha512-0tlgIsjNChtyPlPCnB6k9oh2WCoO80D4nEj9zdU1D3xBL30qlsC1dAEOouGi0uK6Sh2GJLrEiRaeBh+/M9h68w==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.9.9: - resolution: {integrity: sha512-9IsTReoLmQl1IRsy3WExe2j2RKWXQyXujfJ4fXF+jp08KxjVF4/tYP2CIRJx/A7UP/7keBta27bZqzAjsmbSTA==} + /turbo-windows-64@1.9.5: + resolution: {integrity: sha512-HO8Bh4zoViQ3BE8TKG6XJGQyUnCR4ljejWj+soCCZnmgg0rYUgRPKVTDmLA/9wV58b4QWsaEOWN9sWApydDrkg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.9.9: - resolution: {integrity: sha512-CUu4hpeQo68JjDr0V0ygTQRLbS+/sNfdqEVV+Xz9136vpKn2WMQLAuUBVZV0Sp0S/7i+zGnplskT0fED+W46wQ==} + /turbo-windows-arm64@1.9.5: + resolution: {integrity: sha512-XNpxXggn7JtqfLUHOj/hgLMwhTGEVVBix42N4gBMVOgo2GLA5AngTf0dt8ZGKkOFXA75zHn+iHA3sq+lrCRT/g==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.9.9: - resolution: {integrity: sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==} + /turbo@1.9.5: + resolution: {integrity: sha512-ipfHCxx4/DOoEcdp8eItqfQ878NbCJrfAQ28EJdMUUS85sDbftn6XzGQULYdfJDp4q+Wwvu3m4tMNRjZSWZz5Q==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.9.9 - turbo-darwin-arm64: 1.9.9 - turbo-linux-64: 1.9.9 - turbo-linux-arm64: 1.9.9 - turbo-windows-64: 1.9.9 - turbo-windows-arm64: 1.9.9 + turbo-darwin-64: 1.9.5 + turbo-darwin-arm64: 1.9.5 + turbo-linux-64: 1.9.5 + turbo-linux-arm64: 1.9.5 + turbo-windows-64: 1.9.5 + turbo-windows-arm64: 1.9.5 dev: true /type-check@0.3.2: @@ -19608,6 +19786,12 @@ packages: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} + /typescript@5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true + dev: true + /ua-parser-js@0.7.35: resolution: {integrity: sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==} @@ -19634,6 +19818,10 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true + /undici@5.22.1: resolution: {integrity: sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==} engines: {node: '>=14.0'} From 070aa7f79ac1b6bccfe300400d09ec4b900e2566 Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Wed, 31 May 2023 22:55:16 +0200 Subject: [PATCH 03/68] make http service agnostic --- packages/core/package.json | 1 + packages/core/src/shared/http.ts | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 089243a0..f66d6410 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,6 +39,7 @@ "zod": "^3.19.1" }, "dependencies": { + "cross-fetch": "^3.1.6", "ts-toolbelt": "^9.6.0" } } \ No newline at end of file diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index ae3280eb..d901cddb 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,5 +1,7 @@ import { ABBY_BASE_URL } from "./constants"; import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; +import { fetch } from "cross-fetch"; + export abstract class HttpService { static async getProjectData({ projectId, @@ -12,8 +14,7 @@ export abstract class HttpService { }) { try { const res = await fetch( - `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ - environment ? `?environment=${environment}` : "" + `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${environment ? `?environment=${environment}` : "" }` ); @@ -52,6 +53,6 @@ export abstract class HttpService { body: JSON.stringify({ type, ...data }), // catch error and forget about them for now // TODO: add error debugging - }).catch(() => {}); + }).catch(() => { }); } } From 8840ac81e10e9fd4a36c28ba489c2ff2e10ba6d9 Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 00:24:58 +0200 Subject: [PATCH 04/68] add getFeatureFlagValue, add simple express example --- .vscode/settings.json | 3 + packages/nodejs/src/{lib => abby}/abby.ts | 4 +- .../nodejs/src/{lib => abby}/createAbby.ts | 10 +- packages/nodejs/src/express/abbyMiddleware.ts | 14 +++ packages/nodejs/src/index.ts | 11 +-- pnpm-lock.yaml | 95 ++++++------------- 6 files changed, 60 insertions(+), 77 deletions(-) rename packages/nodejs/src/{lib => abby}/abby.ts (69%) rename packages/nodejs/src/{lib => abby}/createAbby.ts (69%) create mode 100644 packages/nodejs/src/express/abbyMiddleware.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 270a1f3a..c523dcd4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,8 @@ }, "[typescript][typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" } } \ No newline at end of file diff --git a/packages/nodejs/src/lib/abby.ts b/packages/nodejs/src/abby/abby.ts similarity index 69% rename from packages/nodejs/src/lib/abby.ts rename to packages/nodejs/src/abby/abby.ts index 4dd016ee..ed4b40eb 100644 --- a/packages/nodejs/src/lib/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -1,6 +1,6 @@ -import { createAbby } from "./createAbby"; +import { createAbby } from "./createAbby.ts"; -export const { useFeatureFlag } = createAbby({ +export const { getFeatureFlagValue } = createAbby({ projectId: "clfn3hs1t0002kx08x3kidi80", currentEnvironment: process.env.NODE_ENV, tests: { diff --git a/packages/nodejs/src/lib/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts similarity index 69% rename from packages/nodejs/src/lib/createAbby.ts rename to packages/nodejs/src/abby/createAbby.ts index 3cc61155..c668ec7f 100644 --- a/packages/nodejs/src/lib/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -11,12 +11,12 @@ export function createAbby< abbyConfig ); - const useFeatureFlag = async [number]>( + const getFeatureFlagValue = async [number]>( name: F - ) => { - console.log(2) - return true + ) => { + await abby.loadProjectData(); + return abby.getFeatureFlag(name); }; - return { useFeatureFlag } + return { getFeatureFlagValue } } \ No newline at end of file diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts new file mode 100644 index 00000000..6a2bdf20 --- /dev/null +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -0,0 +1,14 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +//TODO fix eslint +import { getFeatureFlagValue } from "../abby/abby.ts"; +import { Express, NextFunction, Request, Response } from "express"; + +export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types + const flagValue = await getFeatureFlagValue(name as any); //type? + console.log("hi from middleware", name, flagValue) + if (!flagValue) { + res.sendStatus(403); + return; + } + next(); +} diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 2877fcb2..de6f0948 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,14 +1,13 @@ -import express from "express" -// import { useFeatureFlag } from "./lib/abby.ts"; +import express, { NextFunction, Request, Response } from "express" +import { featureFlagMiddleware } from "./express/abbyMiddleware.ts"; -console.log("hi") const app = express(); const port = 3000; +app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) + app.get('/', async (req, res) => { - if (1) { - res.send("not enabled") - } + res.send("very nice content that needs to be protected") }); app.listen(port, () => console.log(`Express app running on port ${port}!`)); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f14e371..0b02c4fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,8 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false importers: @@ -560,6 +564,9 @@ importers: packages/core: dependencies: + cross-fetch: + specifier: ^3.1.6 + version: 3.1.6 ts-toolbelt: specifier: ^9.6.0 version: 9.6.0 @@ -775,9 +782,6 @@ importers: ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) - ts-node-dev: - specifier: ^2.0.0 - version: 2.0.0(@types/node@20.2.5)(typescript@5.0.4) ts-toolbelt: specifier: ^9.6.0 version: 9.6.0 @@ -5500,7 +5504,7 @@ packages: '@octokit/request-error': 3.0.3 '@octokit/types': 9.2.3 is-plain-object: 5.0.0 - node-fetch: 2.6.7 + node-fetch: 2.6.11 universal-user-agent: 6.0.0 transitivePeerDependencies: - encoding @@ -6814,7 +6818,7 @@ packages: globby: 11.1.0 ip: 2.0.0 lodash: 4.17.21 - node-fetch: 2.6.7 + node-fetch: 2.6.11 open: 8.4.1 pretty-hrtime: 1.0.3 prompts: 2.4.2 @@ -8148,14 +8152,6 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true - /@types/strip-bom@3.0.0: - resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} - dev: true - - /@types/strip-json-comments@0.0.30: - resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} - dev: true - /@types/stripe-v3@3.1.28: resolution: {integrity: sha512-5poJyz1QFXpi1hE2bAWy7gFMdj5Fgofm94DNCaTK9V2LeWPdhCQIaP/6qUagZwgCcTURXzih1J7f3sjXH1cOsw==} dev: false @@ -10090,6 +10086,14 @@ packages: postcss: 8.4.21 pretty-bytes: 5.6.0 + /cross-fetch@3.1.6: + resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} + dependencies: + node-fetch: 2.6.11 + transitivePeerDependencies: + - encoding + dev: false + /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -10618,12 +10622,6 @@ packages: stream-shift: 1.0.1 dev: true - /dynamic-dedupe@0.3.0: - resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} - dependencies: - xtend: 4.0.2 - dev: true - /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true @@ -13672,7 +13670,7 @@ packages: /isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} dependencies: - node-fetch: 2.6.7 + node-fetch: 2.6.11 whatwg-fetch: 3.6.2 transitivePeerDependencies: - encoding @@ -13681,7 +13679,7 @@ packages: /isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: - node-fetch: 2.6.7 + node-fetch: 2.6.11 unfetch: 4.2.0 transitivePeerDependencies: - encoding @@ -15982,6 +15980,17 @@ packages: resolution: {integrity: sha512-nl5goFCig93JZ9FIV8GHT9xpNqXbxQUzkOmKIMKmncsBH9jhg7qKex8hirpymkBFmNQ114chEEG5lS4wgK2I+Q==} dev: true + /node-fetch@2.6.11: + resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -18830,11 +18839,6 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: true - /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -19436,34 +19440,6 @@ packages: code-block-writer: 12.0.0 dev: true - /ts-node-dev@2.0.0(@types/node@20.2.5)(typescript@5.0.4): - resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} - engines: {node: '>=0.8.0'} - hasBin: true - peerDependencies: - node-notifier: '*' - typescript: '*' - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - chokidar: 3.5.3 - dynamic-dedupe: 0.3.0 - minimist: 1.2.7 - mkdirp: 1.0.4 - resolve: 1.22.1 - rimraf: 2.7.1 - source-map-support: 0.5.21 - tree-kill: 1.2.2 - ts-node: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) - tsconfig: 7.0.0 - typescript: 5.0.4 - transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - '@types/node' - dev: true - /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -19549,15 +19525,6 @@ packages: strip-bom: 3.0.0 dev: true - /tsconfig@7.0.0: - resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} - dependencies: - '@types/strip-bom': 3.0.0 - '@types/strip-json-comments': 0.0.30 - strip-bom: 3.0.0 - strip-json-comments: 2.0.1 - dev: true - /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} From f829b2efebce44e70b8f028d74fee4882fada168 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 14:46:25 +0200 Subject: [PATCH 05/68] add abTestMiddleware --- .../nodejs/src/abby/TestStorageService.ts | 0 packages/nodejs/src/abby/abby.ts | 2 +- packages/nodejs/src/abby/createAbby.ts | 22 +++++++++++++++++-- packages/nodejs/src/express/abbyMiddleware.ts | 9 +++++++- packages/nodejs/src/index.ts | 5 +++-- pnpm-lock.yaml | 2 +- 6 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 packages/nodejs/src/abby/TestStorageService.ts diff --git a/packages/nodejs/src/abby/TestStorageService.ts b/packages/nodejs/src/abby/TestStorageService.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/nodejs/src/abby/abby.ts b/packages/nodejs/src/abby/abby.ts index ed4b40eb..3b66e0ae 100644 --- a/packages/nodejs/src/abby/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -1,6 +1,6 @@ import { createAbby } from "./createAbby.ts"; -export const { getFeatureFlagValue } = createAbby({ +export const { getFeatureFlagValue, getABTestValue } = createAbby({ projectId: "clfn3hs1t0002kx08x3kidi80", currentEnvironment: process.env.NODE_ENV, tests: { diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index c668ec7f..0760944a 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,5 +1,6 @@ import { ABConfig, Abby, AbbyConfig, HttpService, ABBY_BASE_URL } from "@tryabby/core"; import { F } from "ts-toolbelt" +import { Request } from "express"; export function createAbby< FlagName extends string, @@ -8,9 +9,26 @@ export function createAbby< ConfigType extends AbbyConfig = AbbyConfig >(abbyConfig: F.Narrow>) { const abby = new Abby( - abbyConfig + abbyConfig, + { + get: (key: string) => { + if (typeof window === "undefined") return null; + return "askdjsalj" + // return TestStorageService.get(abbyConfig.projectId, key); + }, + set: (key: string, value: any) => { + if (typeof window === "undefined") return; + // TestStorageService.set(abbyConfig.projectId, key, value); + }, + }, ); + const getABTestValue = (req: Request, name: T) => { + console.log(req) + const value = abby.getTestVariant(name); + return value; + } + const getFeatureFlagValue = async [number]>( name: F ) => { @@ -18,5 +36,5 @@ export function createAbby< return abby.getFeatureFlag(name); }; - return { getFeatureFlagValue } + return { getFeatureFlagValue, getABTestValue } } \ No newline at end of file diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index 6a2bdf20..4d32baf1 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -1,6 +1,6 @@ /* eslint-disable react-hooks/rules-of-hooks */ //TODO fix eslint -import { getFeatureFlagValue } from "../abby/abby.ts"; +import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; import { Express, NextFunction, Request, Response } from "express"; export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types @@ -12,3 +12,10 @@ export const featureFlagMiddleware = async (req: Request, res: Response, name: s } next(); } + +export const AbTestMiddleware = (req: Request, res: Response, name: string, next: NextFunction) => { + const value = getABTestValue(req, name as any); + res.cookie("test", "5555") + console.log(value); + next(); +} \ No newline at end of file diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index de6f0948..1b7f439d 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,10 +1,11 @@ import express, { NextFunction, Request, Response } from "express" -import { featureFlagMiddleware } from "./express/abbyMiddleware.ts"; +import { featureFlagMiddleware, AbTestMiddleware } from "./express/abbyMiddleware.ts"; const app = express(); const port = 3000; -app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) +app.use("/", (req, res, next) => AbTestMiddleware(req, res, "New Test3", next)) +// app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) app.get('/', async (req, res) => { res.send("very nice content that needs to be protected") diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b02c4fe..2856eb30 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true From dc085643f85ad134094d287c17963974ade4ddc5 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:06:08 +0200 Subject: [PATCH 06/68] use unified IStorageService interface --- packages/angular/src/lib/StorageService.ts | 8 +------- packages/core/src/shared/index.ts | 1 + packages/core/src/shared/interfaces.ts | 5 +++++ packages/react/src/StorageService.ts | 8 +------- packages/svelte/src/lib/StorageService.ts | 8 +------- 5 files changed, 9 insertions(+), 21 deletions(-) create mode 100644 packages/core/src/shared/interfaces.ts diff --git a/packages/angular/src/lib/StorageService.ts b/packages/angular/src/lib/StorageService.ts index 916bc175..ba854046 100644 --- a/packages/angular/src/lib/StorageService.ts +++ b/packages/angular/src/lib/StorageService.ts @@ -1,10 +1,4 @@ -import { getABStorageKey, getFFStorageKey } from "@tryabby/core"; - -export interface IStorageService { - get(projectId: string, key: string): string | null; - set(projectId: string, key: string, value: string): void; - remove(projectId: string, key: string): void; -} +import { getABStorageKey, getFFStorageKey , type IStorageService} from "@tryabby/core"; class ABStorageService implements IStorageService { get(projectId: string, testName: string): string | null { diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts index 400ca27c..ea866db7 100644 --- a/packages/core/src/shared/index.ts +++ b/packages/core/src/shared/index.ts @@ -3,3 +3,4 @@ export * from "./schemas"; export * from "./constants"; export * from "./helpers"; export * from "./http"; +export * from "./interfaces" diff --git a/packages/core/src/shared/interfaces.ts b/packages/core/src/shared/interfaces.ts new file mode 100644 index 00000000..bc9dd4a5 --- /dev/null +++ b/packages/core/src/shared/interfaces.ts @@ -0,0 +1,5 @@ +export interface IStorageService { + get(projectId: string, key: string): string | null; + set(projectId: string, key: string, value: string): void; + remove(projectId: string, key: string): void; + } \ No newline at end of file diff --git a/packages/react/src/StorageService.ts b/packages/react/src/StorageService.ts index f7a39887..17d0ffd8 100644 --- a/packages/react/src/StorageService.ts +++ b/packages/react/src/StorageService.ts @@ -1,12 +1,6 @@ -import { getABStorageKey, getFFStorageKey } from "@tryabby/core"; +import { getABStorageKey, getFFStorageKey , type IStorageService} from "@tryabby/core"; import Cookie from "js-cookie"; -export interface IStorageService { - get(projectId: string, key: string): string | null; - set(projectId: string, key: string, value: string): void; - remove(projectId: string, key: string): void; -} - class ABStorageService implements IStorageService { get(projectId: string, testName: string): string | null { const retrievedValue = Cookie.get(getABStorageKey(projectId, testName)); diff --git a/packages/svelte/src/lib/StorageService.ts b/packages/svelte/src/lib/StorageService.ts index f7a39887..17d0ffd8 100644 --- a/packages/svelte/src/lib/StorageService.ts +++ b/packages/svelte/src/lib/StorageService.ts @@ -1,12 +1,6 @@ -import { getABStorageKey, getFFStorageKey } from "@tryabby/core"; +import { getABStorageKey, getFFStorageKey , type IStorageService} from "@tryabby/core"; import Cookie from "js-cookie"; -export interface IStorageService { - get(projectId: string, key: string): string | null; - set(projectId: string, key: string, value: string): void; - remove(projectId: string, key: string): void; -} - class ABStorageService implements IStorageService { get(projectId: string, testName: string): string | null { const retrievedValue = Cookie.get(getABStorageKey(projectId, testName)); From 66a1912b27691f13197d7c4937207f3e5e5a4f9c Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:29:02 +0200 Subject: [PATCH 07/68] add storage service --- packages/nodejs/src/abby/StorageService.ts | 32 +++++++++++++++++++ .../nodejs/src/abby/TestStorageService.ts | 0 2 files changed, 32 insertions(+) create mode 100644 packages/nodejs/src/abby/StorageService.ts delete mode 100644 packages/nodejs/src/abby/TestStorageService.ts diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts new file mode 100644 index 00000000..4ecbcb95 --- /dev/null +++ b/packages/nodejs/src/abby/StorageService.ts @@ -0,0 +1,32 @@ +import { IStorageService } from "@tryabby/core"; + +class ABStorageService implements IStorageService { + get(projectId: string, key: string): string | null { + // throw new Error("Method not implemented."); + return null; + } + set(projectId: string, key: string, value: string): void { + throw new Error("Method not implemented."); + } + remove(projectId: string, key: string): void { + throw new Error("Method not implemented."); + } + +} + +class FFStorageService implements IStorageService { + get(projectId: string, key: string): string | null { + throw new Error("Method not implemented."); + } + set(projectId: string, key: string, value: string): void { + throw new Error("Method not implemented."); + } + remove(projectId: string, key: string): void { + throw new Error("Method not implemented."); + } + + +} + +export const TestStorageService = new ABStorageService(); +export const FlagStorageService = new FFStorageService(); \ No newline at end of file diff --git a/packages/nodejs/src/abby/TestStorageService.ts b/packages/nodejs/src/abby/TestStorageService.ts deleted file mode 100644 index e69de29b..00000000 From c50e1c2331748df604b146bcf12c8c77b7f5e462 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 16:52:39 +0200 Subject: [PATCH 08/68] add cookieParser helper --- packages/nodejs/src/abby/helpers.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 packages/nodejs/src/abby/helpers.ts diff --git a/packages/nodejs/src/abby/helpers.ts b/packages/nodejs/src/abby/helpers.ts new file mode 100644 index 00000000..30c9d8c2 --- /dev/null +++ b/packages/nodejs/src/abby/helpers.ts @@ -0,0 +1,16 @@ +import { Request } from "express"; + +/** + * helper function to parse express cookie + * @param req express Request object + */ +export function parseCookies(req: Request) { + const cookies = req.headers.cookie; + const cookieMap = new Map(); + cookies?.split(";").map((res, index) => { + const parsedCookie = res.trim().split("="); + cookieMap.set(parsedCookie[0], parsedCookie[1]) + }) + console.log(cookieMap) + return cookieMap; +} \ No newline at end of file From a2fec41407872c07c6a4db1673d267eda2556636 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:06:05 +0200 Subject: [PATCH 09/68] fix ab test middle ware add requestContext, fix cookie parser add middleware --- packages/nodejs/src/abby/StorageService.ts | 14 ++++- packages/nodejs/src/abby/createAbby.ts | 9 +-- packages/nodejs/src/abby/helpers.ts | 3 +- packages/nodejs/src/abby/requestContext.ts | 13 ++++ packages/nodejs/src/express/abbyMiddleware.ts | 2 + pnpm-lock.yaml | 62 +++++++++---------- 6 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 packages/nodejs/src/abby/requestContext.ts diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index 4ecbcb95..637f06e1 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -1,9 +1,17 @@ -import { IStorageService } from "@tryabby/core"; +import { IStorageService, getABStorageKey } from "@tryabby/core"; +import { parseCookies } from "./helpers.ts"; +import { getRequest, setRequest } from "./requestContext.ts"; class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { - // throw new Error("Method not implemented."); - return null; + const req = getRequest(); + if (!req) return null; + const cookieMap = parseCookies(req); + console.log(cookieMap) + const cookieKey = getABStorageKey(projectId, key); + const cookieValue = cookieMap.get(cookieKey) + console.log(cookieValue) + return cookieValue ?? null; } set(projectId: string, key: string, value: string): void { throw new Error("Method not implemented."); diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 0760944a..ab96888c 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,6 +1,7 @@ import { ABConfig, Abby, AbbyConfig, HttpService, ABBY_BASE_URL } from "@tryabby/core"; import { F } from "ts-toolbelt" import { Request } from "express"; +import { TestStorageService } from "./StorageService.ts"; export function createAbby< FlagName extends string, @@ -12,19 +13,15 @@ export function createAbby< abbyConfig, { get: (key: string) => { - if (typeof window === "undefined") return null; - return "askdjsalj" - // return TestStorageService.get(abbyConfig.projectId, key); + return TestStorageService.get(abbyConfig.projectId, key); }, set: (key: string, value: any) => { - if (typeof window === "undefined") return; - // TestStorageService.set(abbyConfig.projectId, key, value); + }, }, ); const getABTestValue = (req: Request, name: T) => { - console.log(req) const value = abby.getTestVariant(name); return value; } diff --git a/packages/nodejs/src/abby/helpers.ts b/packages/nodejs/src/abby/helpers.ts index 30c9d8c2..07c36ac8 100644 --- a/packages/nodejs/src/abby/helpers.ts +++ b/packages/nodejs/src/abby/helpers.ts @@ -2,7 +2,7 @@ import { Request } from "express"; /** * helper function to parse express cookie - * @param req express Request object + * @param req express Request */ export function parseCookies(req: Request) { const cookies = req.headers.cookie; @@ -11,6 +11,5 @@ export function parseCookies(req: Request) { const parsedCookie = res.trim().split("="); cookieMap.set(parsedCookie[0], parsedCookie[1]) }) - console.log(cookieMap) return cookieMap; } \ No newline at end of file diff --git a/packages/nodejs/src/abby/requestContext.ts b/packages/nodejs/src/abby/requestContext.ts new file mode 100644 index 00000000..92315bef --- /dev/null +++ b/packages/nodejs/src/abby/requestContext.ts @@ -0,0 +1,13 @@ +// hacky way to get request object in storage service without passing it +import { Request, Response } from "express"; +let req: Request | null = null; + +export function setRequest(request: Request) { + req = request; +} + +export function getRequest(): Request { + if (!req) throw new Error("request object not set") + return req; +} + diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index 4d32baf1..5948b5c5 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -2,6 +2,7 @@ //TODO fix eslint import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; import { Express, NextFunction, Request, Response } from "express"; +import { setRequest } from "../abby/requestContext.ts"; export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types const flagValue = await getFeatureFlagValue(name as any); //type? @@ -14,6 +15,7 @@ export const featureFlagMiddleware = async (req: Request, res: Response, name: s } export const AbTestMiddleware = (req: Request, res: Response, name: string, next: NextFunction) => { + setRequest(req) const value = getABTestValue(req, name as any); res.cookie("test", "5555") console.log(value); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2856eb30..2ec4513d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - importers: .: @@ -19,7 +15,7 @@ importers: version: 2.8.8 turbo: specifier: latest - version: 1.9.5 + version: 1.10.1 apps/angular-example: dependencies: @@ -679,7 +675,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.9.5(eslint@7.32.0) + version: 1.10.1(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -11264,13 +11260,13 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.9.5(eslint@7.32.0): - resolution: {integrity: sha512-mV52KGcx65xQGckAqIC44kKA9Iv9B0QVHeFbl5ZoJ0SwyBJwug2bkdhnWh/KU/t3Wc3+5TpBHU8u2ygmB0nBbg==} + /eslint-config-turbo@1.10.1(eslint@7.32.0): + resolution: {integrity: sha512-XRF5adpGJIX+IQNRHcGtUCsPZV95vabSvttrxuLOyWufzBctWNkgIo8Mpi5om8ZmYuMqXPUo8IOh3sRR5H1HCw==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.9.5(eslint@7.32.0) + eslint-plugin-turbo: 1.10.1(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -11557,8 +11553,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.9.5(eslint@7.32.0): - resolution: {integrity: sha512-fJW2uLWuv7J3tqJckjDKcApMNcqseV92kQoFMTZwSL5B1g8wJx0sAx9FcDpWgElFnqe2k63Iqz/DMZjdXI72aw==} + /eslint-plugin-turbo@1.10.1(eslint@7.32.0): + resolution: {integrity: sha512-bScQeG42PhVPzSeJgCTk79hRqN8jFYY6Io7fw2qyuOtlff4QkSuBTot+BBooxk4BL11gJglWZUJk2nqumLJGOA==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -19610,65 +19606,65 @@ packages: - supports-color dev: true - /turbo-darwin-64@1.9.5: - resolution: {integrity: sha512-rtVuXm4QH5oA+BU/Vv7mfu9y4ok2zmpqQJEnV3Fn+h+BNgFaPU5HOOEZNiBLVHvpefO9uUB7maU5IVc76w4VPA==} + /turbo-darwin-64@1.10.1: + resolution: {integrity: sha512-isLLoPuAOMNsYovOq9BhuQOZWQuU13zYsW988KkkaA4OJqOn7qwa9V/KBYCJL8uVQqtG+/Y42J37lO8RJjyXuA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.9.5: - resolution: {integrity: sha512-KH01n3GwpphOf3mx9pZoRBt0r9zZi0s5omDJorenN9hKDudTCLRhitbHyfCE9v/2x4hiX1zz8y/zET950YYCEw==} + /turbo-darwin-arm64@1.10.1: + resolution: {integrity: sha512-x1nloPR10fLElNCv17BKr0kCx/O5gse/UXAcVscMZH2tvRUtXrdBmut62uw2YU3J9hli2fszYjUWXkulVpQvFA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.9.5: - resolution: {integrity: sha512-b1XXy/NReTe/sNiohCDcl8YTDe/WSnz+DPA9jPoBfKH4crF8QlIuPUDFHYFmBflAYdItD4htKxy+47ReCoES1w==} + /turbo-linux-64@1.10.1: + resolution: {integrity: sha512-abV+ODCeOlz0503OZlHhPWdy3VwJZc1jObf1VQj7uQM+JqJ/kXbMyqJIMQVz+m7QJUFdferYPRxGhYT/NbYK7Q==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.9.5: - resolution: {integrity: sha512-0tlgIsjNChtyPlPCnB6k9oh2WCoO80D4nEj9zdU1D3xBL30qlsC1dAEOouGi0uK6Sh2GJLrEiRaeBh+/M9h68w==} + /turbo-linux-arm64@1.10.1: + resolution: {integrity: sha512-zRC3nZbHQ63tofOmbuySzEn1ROISWTkemYYr1L98rpmT5aVa0kERlGiYcfDwZh3cBso/Ylg/wxexRAaPzcCJYQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.9.5: - resolution: {integrity: sha512-HO8Bh4zoViQ3BE8TKG6XJGQyUnCR4ljejWj+soCCZnmgg0rYUgRPKVTDmLA/9wV58b4QWsaEOWN9sWApydDrkg==} + /turbo-windows-64@1.10.1: + resolution: {integrity: sha512-Irqz8IU+o7Q/5V44qatZBTunk+FQAOII1hZTsEU54ah62f9Y297K6/LSp+yncmVQOZlFVccXb6MDqcETExIQtA==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.9.5: - resolution: {integrity: sha512-XNpxXggn7JtqfLUHOj/hgLMwhTGEVVBix42N4gBMVOgo2GLA5AngTf0dt8ZGKkOFXA75zHn+iHA3sq+lrCRT/g==} + /turbo-windows-arm64@1.10.1: + resolution: {integrity: sha512-124IT15d2gyjC+NEn11pHOaVFvZDRHpxfF+LDUzV7YxfNIfV0mGkR3R/IyVXtQHOgqOdtQTbC4y411sm31+SEw==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.9.5: - resolution: {integrity: sha512-ipfHCxx4/DOoEcdp8eItqfQ878NbCJrfAQ28EJdMUUS85sDbftn6XzGQULYdfJDp4q+Wwvu3m4tMNRjZSWZz5Q==} + /turbo@1.10.1: + resolution: {integrity: sha512-wq0YeSv6P/eEDXOL42jkMUr+T4z34dM8mdHu5u6C6OOAq8JuLJ72F/v4EVR1JmY8icyTkFz10ICLV0haUUYhbQ==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.9.5 - turbo-darwin-arm64: 1.9.5 - turbo-linux-64: 1.9.5 - turbo-linux-arm64: 1.9.5 - turbo-windows-64: 1.9.5 - turbo-windows-arm64: 1.9.5 + turbo-darwin-64: 1.10.1 + turbo-darwin-arm64: 1.10.1 + turbo-linux-64: 1.10.1 + turbo-linux-arm64: 1.10.1 + turbo-windows-64: 1.10.1 + turbo-windows-arm64: 1.10.1 dev: true /type-check@0.3.2: @@ -21115,3 +21111,7 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false From a3364529ec3ebbb171606963ddfe5c93d6f4a614 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:09:15 +0200 Subject: [PATCH 10/68] add response context --- packages/nodejs/src/abby/responseContext.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/nodejs/src/abby/responseContext.ts diff --git a/packages/nodejs/src/abby/responseContext.ts b/packages/nodejs/src/abby/responseContext.ts new file mode 100644 index 00000000..b8b99d48 --- /dev/null +++ b/packages/nodejs/src/abby/responseContext.ts @@ -0,0 +1,12 @@ +// hacky way to get response object in storage service without passing it +import { Request as Response, } from "express"; +let response: Response | null = null; + +export function setResponse(response: Response) { + response = response; +} + +export function getResponse() { + return response; +} + From ade1b65d9cca01aa6783b233b85509c91b462b20 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:22:28 +0200 Subject: [PATCH 11/68] fix responseContext --- packages/nodejs/src/abby/StorageService.ts | 24 +++++++++++-------- packages/nodejs/src/abby/createAbby.ts | 2 +- packages/nodejs/src/abby/requestContext.ts | 5 ++-- packages/nodejs/src/abby/responseContext.ts | 8 +++---- packages/nodejs/src/express/abbyMiddleware.ts | 2 ++ 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index 637f06e1..fc905122 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -1,20 +1,24 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers.ts"; -import { getRequest, setRequest } from "./requestContext.ts"; +import { getRequest } from "./requestContext.ts"; +import { getResponse } from "./responseContext.ts"; class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { - const req = getRequest(); - if (!req) return null; - const cookieMap = parseCookies(req); - console.log(cookieMap) - const cookieKey = getABStorageKey(projectId, key); - const cookieValue = cookieMap.get(cookieKey) - console.log(cookieValue) - return cookieValue ?? null; + return null; + // const req = getRequest(); + // if (!req) return null; + // const cookieMap = parseCookies(req); + // const cookieKey = getABStorageKey(projectId, key); + // const cookieValue = cookieMap.get(cookieKey) + // return cookieValue ?? null; } set(projectId: string, key: string, value: string): void { - throw new Error("Method not implemented."); + const response = getResponse(); + console.log("resp:", response?.cookie) + // if (!response) throw new Error("no response object") + // console.log("set cookie") + // response.cookie(key, value) } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index ab96888c..0e853121 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -16,7 +16,7 @@ export function createAbby< return TestStorageService.get(abbyConfig.projectId, key); }, set: (key: string, value: any) => { - + TestStorageService.set(abbyConfig.projectId, key, value) }, }, ); diff --git a/packages/nodejs/src/abby/requestContext.ts b/packages/nodejs/src/abby/requestContext.ts index 92315bef..30443309 100644 --- a/packages/nodejs/src/abby/requestContext.ts +++ b/packages/nodejs/src/abby/requestContext.ts @@ -1,13 +1,12 @@ // hacky way to get request object in storage service without passing it -import { Request, Response } from "express"; +import { Request } from "express"; let req: Request | null = null; export function setRequest(request: Request) { req = request; } -export function getRequest(): Request { - if (!req) throw new Error("request object not set") +export function getRequest() { return req; } diff --git a/packages/nodejs/src/abby/responseContext.ts b/packages/nodejs/src/abby/responseContext.ts index b8b99d48..46f68aa2 100644 --- a/packages/nodejs/src/abby/responseContext.ts +++ b/packages/nodejs/src/abby/responseContext.ts @@ -1,12 +1,12 @@ // hacky way to get response object in storage service without passing it -import { Request as Response, } from "express"; -let response: Response | null = null; +import { Response, } from "express"; +let res: Response | null = null; export function setResponse(response: Response) { - response = response; + res = response; } export function getResponse() { - return response; + return res; } diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index 5948b5c5..f9788987 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -3,6 +3,7 @@ import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; import { Express, NextFunction, Request, Response } from "express"; import { setRequest } from "../abby/requestContext.ts"; +import { setResponse } from "../abby/responseContext.ts"; export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types const flagValue = await getFeatureFlagValue(name as any); //type? @@ -16,6 +17,7 @@ export const featureFlagMiddleware = async (req: Request, res: Response, name: s export const AbTestMiddleware = (req: Request, res: Response, name: string, next: NextFunction) => { setRequest(req) + setResponse(res) const value = getABTestValue(req, name as any); res.cookie("test", "5555") console.log(value); From d6ceca7a0eb4c0296d2ab72d0943599d70d5e332 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:25:47 +0200 Subject: [PATCH 12/68] add cookieMiddleware cookie middleware working --- packages/nodejs/src/abby/StorageService.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index fc905122..ca47a796 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -5,20 +5,18 @@ import { getResponse } from "./responseContext.ts"; class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { - return null; - // const req = getRequest(); - // if (!req) return null; - // const cookieMap = parseCookies(req); - // const cookieKey = getABStorageKey(projectId, key); - // const cookieValue = cookieMap.get(cookieKey) - // return cookieValue ?? null; + const req = getRequest(); + if (!req) return null; + const cookieMap = parseCookies(req); + const cookieKey = getABStorageKey(projectId, key); + const cookieValue = cookieMap.get(cookieKey) + return cookieValue ?? null; } set(projectId: string, key: string, value: string): void { const response = getResponse(); - console.log("resp:", response?.cookie) - // if (!response) throw new Error("no response object") - // console.log("set cookie") - // response.cookie(key, value) + if (!response) throw new Error("no response object") + const cookieKey = getABStorageKey(projectId, key); + response.cookie(cookieKey, value) } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); From 9fc56f8e952d29dc096345e199b7c1985e468149 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:51:25 +0200 Subject: [PATCH 13/68] refac: move contexts to new folder --- packages/nodejs/src/abby/StorageService.ts | 4 ++-- packages/nodejs/src/abby/{ => contexts}/requestContext.ts | 0 packages/nodejs/src/abby/{ => contexts}/responseContext.ts | 0 packages/nodejs/src/express/abbyMiddleware.ts | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename packages/nodejs/src/abby/{ => contexts}/requestContext.ts (100%) rename packages/nodejs/src/abby/{ => contexts}/responseContext.ts (100%) diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index ca47a796..d1dfd12e 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -1,7 +1,7 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers.ts"; -import { getRequest } from "./requestContext.ts"; -import { getResponse } from "./responseContext.ts"; +import { getRequest } from "./contexts/requestContext.ts"; +import { getResponse } from "./contexts/responseContext.ts"; class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { diff --git a/packages/nodejs/src/abby/requestContext.ts b/packages/nodejs/src/abby/contexts/requestContext.ts similarity index 100% rename from packages/nodejs/src/abby/requestContext.ts rename to packages/nodejs/src/abby/contexts/requestContext.ts diff --git a/packages/nodejs/src/abby/responseContext.ts b/packages/nodejs/src/abby/contexts/responseContext.ts similarity index 100% rename from packages/nodejs/src/abby/responseContext.ts rename to packages/nodejs/src/abby/contexts/responseContext.ts diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index f9788987..eb1684c8 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -2,8 +2,8 @@ //TODO fix eslint import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; import { Express, NextFunction, Request, Response } from "express"; -import { setRequest } from "../abby/requestContext.ts"; -import { setResponse } from "../abby/responseContext.ts"; +import { setRequest } from "../abby/contexts/requestContext.ts"; +import { setResponse } from "../abby/contexts/responseContext.ts"; export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types const flagValue = await getFeatureFlagValue(name as any); //type? From 174c81e6333514921bc8a8e8db96bb5f4826724e Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:52:05 +0200 Subject: [PATCH 14/68] docs: add documentation to create abby --- packages/nodejs/src/abby/createAbby.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 0e853121..51a4e70b 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -21,11 +21,23 @@ export function createAbby< }, ); + //load data and initialise the abby Object + // await abby.loadProjectData(); + + /** + * @param req express request object + * @param name Name of the test that the variant should be retrieved for + * @returns Value of the currently selected variant + */ const getABTestValue = (req: Request, name: T) => { const value = abby.getTestVariant(name); return value; } - + /** + * + * @param name Name of the feature flag + * @returns Value of the feature flag + */ const getFeatureFlagValue = async [number]>( name: F ) => { From 911e2dbcfa8f8354fddd121d269400aee8fe6b98 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:08:05 +0200 Subject: [PATCH 15/68] refac: cleanup unused things --- packages/nodejs/src/abby/createAbby.ts | 4 ++-- packages/nodejs/src/express/abbyMiddleware.ts | 3 +-- packages/nodejs/src/index.ts | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 51a4e70b..01a7adf0 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,4 +1,4 @@ -import { ABConfig, Abby, AbbyConfig, HttpService, ABBY_BASE_URL } from "@tryabby/core"; +import { ABConfig, Abby, AbbyConfig } from "@tryabby/core"; import { F } from "ts-toolbelt" import { Request } from "express"; import { TestStorageService } from "./StorageService.ts"; @@ -20,7 +20,7 @@ export function createAbby< }, }, ); - + //TODO find way to await initialisation //load data and initialise the abby Object // await abby.loadProjectData(); diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index eb1684c8..a9b15096 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -1,7 +1,7 @@ /* eslint-disable react-hooks/rules-of-hooks */ //TODO fix eslint import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; -import { Express, NextFunction, Request, Response } from "express"; +import { NextFunction, Request, Response } from "express"; import { setRequest } from "../abby/contexts/requestContext.ts"; import { setResponse } from "../abby/contexts/responseContext.ts"; @@ -19,7 +19,6 @@ export const AbTestMiddleware = (req: Request, res: Response, name: string, next setRequest(req) setResponse(res) const value = getABTestValue(req, name as any); - res.cookie("test", "5555") console.log(value); next(); } \ No newline at end of file diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 1b7f439d..a3600001 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,4 +1,4 @@ -import express, { NextFunction, Request, Response } from "express" +import express from "express" import { featureFlagMiddleware, AbTestMiddleware } from "./express/abbyMiddleware.ts"; const app = express(); From 316caa23b26374d91c1f08bd70adf2ad2d2cd3c7 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:29:24 +0200 Subject: [PATCH 16/68] add test adding basic setup for tests including msw setup --- packages/nodejs/package.json | 8 +- packages/nodejs/src/tests/abby.test.ts | 9 + packages/nodejs/src/tests/mocks/handlers.ts | 31 ++ packages/nodejs/src/tests/mocks/server.ts | 5 + pnpm-lock.yaml | 321 +++++++++++++++++++- 5 files changed, 356 insertions(+), 18 deletions(-) create mode 100644 packages/nodejs/src/tests/abby.test.ts create mode 100644 packages/nodejs/src/tests/mocks/handlers.ts create mode 100644 packages/nodejs/src/tests/mocks/server.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 039ff4d3..cd6315f8 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -5,7 +5,7 @@ "main": "index.js", "type": "module", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "vitest ", "dev": "nodemon ./src/index.ts" }, "keywords": [], @@ -18,10 +18,14 @@ }, "devDependencies": { "@types/express": "^4.17.17", + "@types/jest": "^29.5.1", "@types/node": "^20.2.5", + "msw": "^1.2.1", + "node-fetch": "^3.3.1", "nodemon": "^2.0.22", "ts-node": "^10.9.1", "ts-toolbelt": "^9.6.0", - "typescript": "^5.0.4" + "typescript": "^5.0.4", + "vitest": "^0.31.4" } } \ No newline at end of file diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts new file mode 100644 index 00000000..a3e014ab --- /dev/null +++ b/packages/nodejs/src/tests/abby.test.ts @@ -0,0 +1,9 @@ +import { expect, test, describe } from "vitest" + +describe("it works", () => { + test("test", () => { + console.log("test running") + expect(true, "ja").toBeTruthy(); + }) +} +) \ No newline at end of file diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts new file mode 100644 index 00000000..5fb79a5a --- /dev/null +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -0,0 +1,31 @@ +import { rest } from "msw"; +import { type AbbyDataResponse, ABBY_BASE_URL } from "@tryabby/core"; + +export const handlers = [ + rest.get(`${ABBY_BASE_URL}api/dashboard/:projectId/data`, (req, res, ctx) => { + return res( + ctx.json({ + tests: [ + { + name: "test", + weights: [1, 1, 1, 1], + }, + { + name: "test2", + weights: [1, 0], + }, + ], + flags: [ + { + name: "flag1", + isEnabled: true, + }, + { + name: "flag2", + isEnabled: false, + }, + ], + } as AbbyDataResponse) + ); + }), +]; diff --git a/packages/nodejs/src/tests/mocks/server.ts b/packages/nodejs/src/tests/mocks/server.ts new file mode 100644 index 00000000..5f3117f0 --- /dev/null +++ b/packages/nodejs/src/tests/mocks/server.ts @@ -0,0 +1,5 @@ +import { setupServer } from "msw/node"; +import { handlers } from "./handlers.ts"; + +// This configures a request mocking server with the given request handlers. +export const server = setupServer(...handlers); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ec4513d..e56d5734 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -769,9 +769,18 @@ importers: '@types/express': specifier: ^4.17.17 version: 4.17.17 + '@types/jest': + specifier: ^29.5.1 + version: 29.5.1 '@types/node': specifier: ^20.2.5 version: 20.2.5 + msw: + specifier: ^1.2.1 + version: 1.2.1(typescript@5.0.4) + node-fetch: + specifier: ^3.3.1 + version: 3.3.1 nodemon: specifier: ^2.0.22 version: 2.0.22 @@ -784,6 +793,9 @@ importers: typescript: specifier: ^5.0.4 version: 5.0.4 + vitest: + specifier: ^0.31.4 + version: 0.31.4 packages/react: dependencies: @@ -3926,7 +3938,7 @@ packages: react: ^16.8.3 || ^17 || ^18 dependencies: '@code-hike/lighter': 0.6.4 - node-fetch: 2.6.7 + node-fetch: 2.6.11 react: 18.2.0 shiki: 0.10.1 transitivePeerDependencies: @@ -4844,7 +4856,7 @@ packages: '@xmldom/xmldom': 0.8.6 debug: 4.3.4 headers-polyfill: 3.1.2 - outvariant: 1.3.0 + outvariant: 1.4.0 strict-event-emitter: 0.2.8 web-encoding: 1.1.5 transitivePeerDependencies: @@ -7784,13 +7796,17 @@ packages: /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: - '@types/chai': 4.3.4 + '@types/chai': 4.3.5 dev: true /@types/chai@4.3.4: resolution: {integrity: sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==} dev: true + /@types/chai@4.3.5: + resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} + dev: true + /@types/connect-history-api-fallback@1.5.0: resolution: {integrity: sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==} dependencies: @@ -8461,6 +8477,45 @@ packages: vitest: 0.25.8(jsdom@20.0.3) dev: true + /@vitest/expect@0.31.4: + resolution: {integrity: sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==} + dependencies: + '@vitest/spy': 0.31.4 + '@vitest/utils': 0.31.4 + chai: 4.3.7 + dev: true + + /@vitest/runner@0.31.4: + resolution: {integrity: sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==} + dependencies: + '@vitest/utils': 0.31.4 + concordance: 5.0.4 + p-limit: 4.0.0 + pathe: 1.1.0 + dev: true + + /@vitest/snapshot@0.31.4: + resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==} + dependencies: + magic-string: 0.30.0 + pathe: 1.1.0 + pretty-format: 27.5.1 + dev: true + + /@vitest/spy@0.31.4: + resolution: {integrity: sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==} + dependencies: + tinyspy: 2.1.1 + dev: true + + /@vitest/utils@0.31.4: + resolution: {integrity: sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==} + dependencies: + concordance: 5.0.4 + loupe: 2.3.6 + pretty-format: 27.5.1 + dev: true + /@webassemblyjs/ast@1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: @@ -9226,6 +9281,10 @@ packages: inherits: 2.0.4 readable-stream: 3.6.0 + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: true + /body-parser@1.20.1: resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -9930,6 +9989,20 @@ packages: typedarray: 0.0.6 dev: true + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.3.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.3.8 + well-known-symbols: 2.0.0 + dev: true + /condense-newlines@0.2.1: resolution: {integrity: sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==} engines: {node: '>=0.10.0'} @@ -10231,6 +10304,13 @@ packages: resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} engines: {node: '>=4.0'} + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: true + /dayjs@1.11.7: resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} dev: false @@ -12054,6 +12134,10 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true + /fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -13466,6 +13550,10 @@ packages: resolution: {integrity: sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==} dev: true + /is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + dev: true + /is-number-like@1.0.8: resolution: {integrity: sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==} dependencies: @@ -13894,6 +13982,11 @@ packages: /js-sdsl@4.2.0: resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -14748,6 +14841,13 @@ packages: remove-accents: 0.4.2 dev: false + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: true + /mdast-util-definitions@4.0.0: resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} dependencies: @@ -15555,6 +15655,15 @@ packages: hasBin: true dev: true + /mlly@1.3.0: + resolution: {integrity: sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==} + dependencies: + acorn: 8.8.2 + pathe: 1.1.0 + pkg-types: 1.0.3 + ufo: 1.1.2 + dev: true + /mousetrap@1.6.5: resolution: {integrity: sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==} dev: false @@ -15605,7 +15714,7 @@ packages: inquirer: 8.2.5 is-node-process: 1.0.1 js-levenshtein: 1.1.6 - node-fetch: 2.6.7 + node-fetch: 2.6.11 outvariant: 1.3.0 path-to-regexp: 6.2.1 strict-event-emitter: 0.2.8 @@ -15641,7 +15750,7 @@ packages: inquirer: 8.2.5 is-node-process: 1.0.1 js-levenshtein: 1.1.6 - node-fetch: 2.6.7 + node-fetch: 2.6.11 outvariant: 1.3.0 path-to-regexp: 6.2.1 strict-event-emitter: 0.4.6 @@ -15653,6 +15762,42 @@ packages: - supports-color dev: true + /msw@1.2.1(typescript@5.0.4): + resolution: {integrity: sha512-bF7qWJQSmKn6bwGYVPXOxhexTCGD5oJSZg8yt8IBClxvo3Dx/1W0zqE1nX9BSWmzRsCKWfeGWcB/vpqV6aclpw==} + engines: {node: '>=14'} + hasBin: true + requiresBuild: true + peerDependencies: + typescript: '>= 4.4.x <= 5.0.x' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@mswjs/cookies': 0.2.2 + '@mswjs/interceptors': 0.17.6 + '@open-draft/until': 1.0.3 + '@types/cookie': 0.4.1 + '@types/js-levenshtein': 1.1.1 + chalk: 4.1.1 + chokidar: 3.5.3 + cookie: 0.4.2 + graphql: 16.6.0 + headers-polyfill: 3.1.2 + inquirer: 8.2.5 + is-node-process: 1.2.0 + js-levenshtein: 1.1.6 + node-fetch: 2.6.11 + outvariant: 1.4.0 + path-to-regexp: 6.2.1 + strict-event-emitter: 0.4.6 + type-fest: 2.19.0 + typescript: 5.0.4 + yargs: 17.6.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + /multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} dependencies: @@ -15987,17 +16132,6 @@ packages: dependencies: whatwg-url: 5.0.0 - /node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - /node-fetch@3.3.0: resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -16470,6 +16604,10 @@ packages: resolution: {integrity: sha512-yeWM9k6UPfG/nzxdaPlJkB2p08hCg4xP6Lx99F+vP8YF7xyZVfTmJjrrNalkmzudD4WFvNLVudQikqUmF8zhVQ==} dev: true + /outvariant@1.4.0: + resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==} + dev: true + /p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -16494,6 +16632,13 @@ packages: dependencies: yocto-queue: 0.1.0 + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} @@ -16787,6 +16932,14 @@ packages: find-up: 5.0.0 dev: true + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.3.0 + pathe: 1.1.0 + dev: true + /polished@4.2.2: resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} engines: {node: '>=10'} @@ -18350,6 +18503,10 @@ packages: get-intrinsic: 1.1.3 object-inspect: 1.12.2 + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + /sigmund@1.0.1: resolution: {integrity: sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==} dev: false @@ -18649,6 +18806,10 @@ packages: escape-string-regexp: 2.0.0 dev: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + /standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} dev: false @@ -19281,6 +19442,11 @@ packages: /thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: true + /tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} dependencies: @@ -19291,16 +19457,30 @@ packages: resolution: {integrity: sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==} dev: true + /tinybench@2.5.0: + resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + dev: true + /tinypool@0.3.1: resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} engines: {node: '>=14.0.0'} dev: true + /tinypool@0.5.0: + resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==} + engines: {node: '>=14.0.0'} + dev: true + /tinyspy@1.1.1: resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==} engines: {node: '>=14.0.0'} dev: true + /tinyspy@2.1.1: + resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + engines: {node: '>=14.0.0'} + dev: true + /tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} dependencies: @@ -19766,6 +19946,10 @@ packages: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} dev: false + /ufo@1.1.2: + resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} + dev: true + /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} @@ -20192,6 +20376,27 @@ packages: vfile-message: 3.1.3 dev: false + /vite-node@0.31.4(@types/node@18.15.11): + resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.3.0 + pathe: 1.1.0 + picocolors: 1.0.0 + vite: 4.3.2(@types/node@18.15.11) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite-plugin-dts@2.3.0(vite@4.2.0): resolution: {integrity: sha512-WbJgGtsStgQhdm3EosYmIdTGbag5YQpZ3HXWUAPCDyoXI5qN6EY0V7NXq0lAmnv9hVQsvh0htbYcg0Or5Db9JQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -20405,6 +20610,71 @@ packages: - terser dev: true + /vitest@0.31.4: + resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 18.15.11 + '@vitest/expect': 0.31.4 + '@vitest/runner': 0.31.4 + '@vitest/snapshot': 0.31.4 + '@vitest/spy': 0.31.4 + '@vitest/utils': 0.31.4 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + concordance: 5.0.4 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.0 + pathe: 1.1.0 + picocolors: 1.0.0 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.5.0 + vite: 4.3.2(@types/node@18.15.11) + vite-node: 0.31.4(@types/node@18.15.11) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /void-elements@2.0.1: resolution: {integrity: sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==} engines: {node: '>=0.10.0'} @@ -20719,6 +20989,11 @@ packages: resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} engines: {node: '>=0.8.0'} + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: true + /whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} dependencies: @@ -20835,6 +21110,15 @@ packages: isexe: 2.0.0 dev: true + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: @@ -21084,6 +21368,11 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + /z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} From 87221b90f44f30c92ee3d1f28a3c2423cdec9c4b Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 6 Jun 2023 11:36:14 +0200 Subject: [PATCH 17/68] add await abby initialization --- packages/nodejs/package.json | 3 ++- packages/nodejs/src/abby/StorageService.ts | 2 +- packages/nodejs/src/abby/abby.ts | 2 +- packages/nodejs/src/abby/createAbby.ts | 6 +++--- packages/nodejs/tsconfig.json | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index cd6315f8..4df3f6a7 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -6,7 +6,8 @@ "type": "module", "scripts": { "test": "vitest ", - "dev": "nodemon ./src/index.ts" + "dev": "nodemon ./src/index.ts", + "dev:debugger": "nodemon ./src/index.ts --inspect" }, "keywords": [], "author": "", diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index d1dfd12e..9382e472 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -14,7 +14,7 @@ class ABStorageService implements IStorageService { } set(projectId: string, key: string, value: string): void { const response = getResponse(); - if (!response) throw new Error("no response object") + if (!response) return; const cookieKey = getABStorageKey(projectId, key); response.cookie(cookieKey, value) } diff --git a/packages/nodejs/src/abby/abby.ts b/packages/nodejs/src/abby/abby.ts index 3b66e0ae..fba94ea7 100644 --- a/packages/nodejs/src/abby/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -1,6 +1,6 @@ import { createAbby } from "./createAbby.ts"; -export const { getFeatureFlagValue, getABTestValue } = createAbby({ +export const { getFeatureFlagValue, getABTestValue } = await createAbby({ projectId: "clfn3hs1t0002kx08x3kidi80", currentEnvironment: process.env.NODE_ENV, tests: { diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 01a7adf0..5959a18a 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -3,7 +3,7 @@ import { F } from "ts-toolbelt" import { Request } from "express"; import { TestStorageService } from "./StorageService.ts"; -export function createAbby< +export async function createAbby< FlagName extends string, TestName extends string, Tests extends Record, @@ -20,9 +20,9 @@ export function createAbby< }, }, ); - //TODO find way to await initialisation + //load data and initialise the abby Object - // await abby.loadProjectData(); + await abby.loadProjectData(); /** * @param req express request object diff --git a/packages/nodejs/tsconfig.json b/packages/nodejs/tsconfig.json index d8970ac0..58354e67 100644 --- a/packages/nodejs/tsconfig.json +++ b/packages/nodejs/tsconfig.json @@ -9,7 +9,7 @@ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ From dc77bb0fc53857fdda92b0f424f3212f8ff79799 Mon Sep 17 00:00:00 2001 From: Tim-53 <82676248+Tim-53@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:15:35 +0200 Subject: [PATCH 18/68] Feat/core/add feature flag caching (#22) * use unified IStorageService interface (#19) * add timeout to feature flags * add flag timeout map * fix type flagTimeoutMap * add test for feature flag caching * add optional config, fix tests * add more tests for config * add even more tests * rename to timetolive * update tests --- packages/core/src/index.ts | 49 ++++++++- packages/core/tests/base.test.ts | 138 ++++++++++++++++++++++++++ packages/core/tests/mocks/handlers.ts | 30 ++++++ 3 files changed, 213 insertions(+), 4 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f125310d..d21e3833 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -43,6 +43,11 @@ interface PersistentStorage { set: (key: string, value: string) => void; } +type flagCacheConfig = { + refetchFlags: boolean, + timeToLive: number +} + export type AbbyConfig< FlagName extends string = string, Tests extends Record = Record @@ -54,6 +59,7 @@ export type AbbyConfig< flags?: Array; settings?: Settings>; debug?: boolean; + flagCacheConfig?: flagCacheConfig, }; export class Abby< @@ -62,7 +68,7 @@ export class Abby< Tests extends Record > { private log = (...args: any[]) => - this.config.debug ? console.log(`core.Abby`, ...args) : () => {}; + this.config.debug ? console.log(`core.Abby`, ...args) : () => { }; private testDevtoolOverrides: Map< keyof Tests, @@ -71,6 +77,8 @@ export class Abby< private flagDevtoolOverrides: Map = new Map(); + #flagTimeoutMap:Map = new Map; + #data: LocalData = { tests: {} as any, flags: {} as any, @@ -151,6 +159,8 @@ export class Abby< return acc; }, (this.config.tests ?? {}) as any), flags: data.flags.reduce((acc, { name, isEnabled }) => { + const validUntil = new Date(new Date().getTime() + 1000 * 60 *( this.config.flagCacheConfig?.timeToLive ?? 1)); // flagdefault timeout is 1 minute + this.#flagTimeoutMap.set(name, validUntil) acc[name] = isEnabled; return acc; }, {} as Record), @@ -203,6 +213,37 @@ export class Abby< return this.getProjectData(); } + /** + * Helper function to retrieve the time a flag is valid + * @param key + * @returns + */ + getFeatureFlagTimeout(key: F) { + return this.#flagTimeoutMap.get(key) + } + + /** + * Helper function to check if a featureflag should be refetched + * @param key name of the featureflag + * @returns value of flag + */ + getValidFlag(key: F) { + const flagTime = this.#flagTimeoutMap.get(key) + if (!flagTime) return this.#data.flags[key]; + const now = new Date(); + if (flagTime.getTime() <= now.getTime()) { + this.refetchFlags() + } + return this.#data.flags[key]; + } + + /** + * helper function to make testing easier + */ + refetchFlags() { + this.loadProjectData(); + } + /** * Function to get the value of a feature flag. This includes * the overrides from the dev tools and the local overrides if in development mode @@ -213,8 +254,6 @@ export class Abby< getFeatureFlag(key: T) { this.log(`getFeatureFlag()`, key); - const storedValue = this.#data.flags[key]; - const localOverride = this.flagOverrides?.get(key); if (localOverride != null) { @@ -227,7 +266,7 @@ export class Abby< * 1. DevTools * 2. DevOverrides from config * 3. DevDefault from config - */ + */ if (process.env.NODE_ENV === "development") { const devOverride = (this.config.settings?.flags?.devOverrides as any)?.[ key @@ -240,6 +279,8 @@ export class Abby< } } + const storedValue = this.config.flagCacheConfig?.refetchFlags ? this.getValidFlag(key) : this.#data.flags[key]; + if (storedValue != null) { this.log(`getFeatureFlag() => storedValue:`, storedValue); return storedValue; diff --git a/packages/core/tests/base.test.ts b/packages/core/tests/base.test.ts index bfed6630..eca7377b 100644 --- a/packages/core/tests/base.test.ts +++ b/packages/core/tests/base.test.ts @@ -110,8 +110,146 @@ describe("Abby", () => { expect(abby.getFeatureFlag("flag1")).toBe(false); }); + + it("refetches an expired flag", async () =>{ + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 2 + } + }); + await abby.loadProjectData() + const expiredDate = new Date(new Date().getTime() + 1000 * 60 * 10) //date in 100 minutes + vi.setSystemTime(expiredDate) + const spy = vi.spyOn(abby, "refetchFlags") + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).toBeCalled() + }) + + it("non expired flag does not get refetched", async () => { + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 2 + } + }); + + await abby.loadProjectData(); + + const spy = vi.spyOn(abby, "refetchFlags") + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).not.toBeCalled() + }) + + it("respects the featureFlagCacheConfig refetchFlags value set to false", async () => { + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + flagCacheConfig: { + refetchFlags: false, + timeToLive: 2 + } + }); + + await abby.loadProjectData(); + + const spy = vi.spyOn(abby, "refetchFlags") + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).not.toBeCalled() + }) + + it("", async () => { + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 2 + } + }); + + await abby.loadProjectData(); + + const spy = vi.spyOn(abby, "refetchFlags") + + //set date to 5 Minutes in the future + const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); + vi.setSystemTime(dateIn3Minutes) + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).toBeCalled() + }) + + it("respects the featureFlagCacheCOnfig expiration time", async () => { + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 2 + } + }); + + await abby.loadProjectData(); + + const spy = vi.spyOn(abby, "refetchFlags") + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).not.toBeCalled() + + //set date to 5 Minutes in the future + const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); + vi.setSystemTime(dateIn3Minutes) + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).toBeCalled() + }) + }); +it("respects the default behaviour", async () => { + const date = new Date() //current date + vi.setSystemTime(date) + const abby = new Abby({ + projectId: "expired", + flags: ["flag1", "flag2"], + }); + + await abby.loadProjectData(); + + const spy = vi.spyOn(abby, "refetchFlags") + + //set date to 5 Minutes in the future + const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); + vi.setSystemTime(dateIn3Minutes) + + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBeFalsy(); + expect(spy).not.toBeCalled() +}) + describe("Math helpers", () => { it("validates weight", () => { const variants = ["variant1", "variant2"]; diff --git a/packages/core/tests/mocks/handlers.ts b/packages/core/tests/mocks/handlers.ts index cb19d326..b1f34be1 100644 --- a/packages/core/tests/mocks/handlers.ts +++ b/packages/core/tests/mocks/handlers.ts @@ -31,4 +31,34 @@ export const handlers = [ ); } ), + rest.get( + "https://www.tryabby.com/api/dashboard/expired/data", + // `${ABBY_BASE_URL}/api/dashboard/expired/data`, + (req, res, ctx) => { + return res( + ctx.json({ + tests: [ + { + name: "test", + weights: [1, 1, 1, 1], + }, + { + name: "test2", + weights: [1, 0], + }, + ], + flags: [ + { + name: "flag1", + isEnabled: true, + }, + { + name: "flag2", + isEnabled: false, + }, + ], + } as AbbyDataResponse) + ); + } + ), ]; From bcd5d9977323024eae9c877ae0ef218c63e37c1a Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:45:25 +0200 Subject: [PATCH 19/68] add cache config --- packages/nodejs/src/abby/abby.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/nodejs/src/abby/abby.ts b/packages/nodejs/src/abby/abby.ts index fba94ea7..0a168155 100644 --- a/packages/nodejs/src/abby/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -9,4 +9,8 @@ export const { getFeatureFlagValue, getABTestValue } = await createAbby({ }, }, flags: ["lol", "test3", "testAbby"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1 + } }); From cf6123327690c17f5a2993f785168dcfe151c1c9 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:09:30 +0200 Subject: [PATCH 20/68] repair lockfile --- pnpm-lock.yaml | 123 +++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 96 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e56d5734..4d4bac6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: version: 2.8.8 turbo: specifier: latest - version: 1.10.1 + version: 1.10.2 apps/angular-example: dependencies: @@ -675,7 +675,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.1(eslint@7.32.0) + version: 1.10.2(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -1368,7 +1368,6 @@ packages: /@angular/compiler-cli@15.2.0(@angular/compiler@15.2.0)(typescript@4.9.5): resolution: {integrity: sha512-ETnRBdY/LGcmDRQ9GQc9KyCd1kuRnj+Y9luq2dCTMysP+NgylmYoGDsJOsDKm6SzPo+B4PSAyHX2J4CVQFHpPg==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler': 15.2.0 typescript: '>=4.8.2 <5.0' @@ -1940,7 +1939,6 @@ packages: /@babel/parser@7.21.4: resolution: {integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==} engines: {node: '>=6.0.0'} - hasBin: true dependencies: '@babel/types': 7.21.4 @@ -4808,7 +4806,6 @@ packages: /@microsoft/api-extractor@7.34.4: resolution: {integrity: sha512-HOdcci2nT40ejhwPC3Xja9G+WSJmWhCUKKryRfQYsmE9cD+pxmBaKBKCbuS9jUcl6bLLb4Gz+h7xEN5r0QiXnQ==} - hasBin: true dependencies: '@microsoft/api-extractor-model': 7.26.4 '@microsoft/tsdoc': 0.14.2 @@ -7113,7 +7110,6 @@ packages: /@sveltejs/kit@1.15.8(svelte@3.58.0)(vite@4.3.2): resolution: {integrity: sha512-xPIF3UbFEA5BBZWFTGGUtSZ0O3DAtmzIp/yZZVdLIfzZ9+geKG3iGSVFnOUdYstjU7JcvJg12UC5MD5xoED59A==} engines: {node: ^16.14 || >=18} - hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 @@ -7141,7 +7137,6 @@ packages: /@sveltejs/package@2.0.2(svelte@3.58.0)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} - hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -8122,7 +8117,6 @@ packages: /@types/sass@1.45.0: resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==} - deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed. dependencies: sass: 1.62.0 dev: true @@ -8715,7 +8709,6 @@ packages: /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} - hasBin: true /acorn@8.8.1: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} @@ -8724,7 +8717,6 @@ packages: /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} - hasBin: true /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} @@ -9068,7 +9060,6 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -9083,7 +9074,6 @@ packages: /autoprefixer@10.4.14(postcss@8.4.21): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -11165,7 +11155,6 @@ packages: /esbuild@0.17.17: resolution: {integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.17 @@ -11333,20 +11322,19 @@ packages: /eslint-config-prettier@8.5.0(eslint@7.32.0): resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.10.1(eslint@7.32.0): - resolution: {integrity: sha512-XRF5adpGJIX+IQNRHcGtUCsPZV95vabSvttrxuLOyWufzBctWNkgIo8Mpi5om8ZmYuMqXPUo8IOh3sRR5H1HCw==} + /eslint-config-turbo@1.10.2(eslint@7.32.0): + resolution: {integrity: sha512-BaCnpn2GM0rTFLuTVplqY8n+3ttWcu/vEmfjJ2BNBVmwX6ALZoJQfL26ZW6VucRk0psTUJALeo+aPrf3VKEJXA==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.10.1(eslint@7.32.0) + eslint-plugin-turbo: 1.10.2(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -11633,8 +11621,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.10.1(eslint@7.32.0): - resolution: {integrity: sha512-bScQeG42PhVPzSeJgCTk79hRqN8jFYY6Io7fw2qyuOtlff4QkSuBTot+BBooxk4BL11gJglWZUJk2nqumLJGOA==} + /eslint-plugin-turbo@1.10.2(eslint@7.32.0): + resolution: {integrity: sha512-Kxsy4zlKLrGkEqZgcAQtu16YqU/g0mV1vYa9/VweF+MSnWWQsEzsJ1qlzTfXV6N9VqGmkuLiyWOA84sRUklOOg==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -11843,7 +11831,6 @@ packages: /eslint@8.4.1: resolution: {integrity: sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true dependencies: '@eslint/eslintrc': 1.3.3 '@humanwhocodes/config-array': 0.9.5 @@ -12660,7 +12647,6 @@ packages: /glob@10.2.3: resolution: {integrity: sha512-Kb4rfmBVE3eQTAimgmeqc2LwSnN0wIOkkUL6HmxEFxNJ4fHghYHVbFba/HcGcRjE6s9KoMNK3rSOwkL4PioZjg==} engines: {node: '>=16 || 14 >=14.17'} - hasBin: true dependencies: foreground-child: 3.1.1 jackspeak: 2.2.0 @@ -13992,20 +13978,17 @@ packages: /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true dependencies: argparse: 1.0.10 esprima: 4.0.1 /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true dependencies: argparse: 2.0.1 /jscodeshift@0.14.0(@babel/preset-env@7.21.4): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15459,18 +15442,15 @@ packages: /mime@1.4.1: resolution: {integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==} - hasBin: true dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} - hasBin: true /mime@2.5.2: resolution: {integrity: sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==} engines: {node: '>=4.0.0'} - hasBin: true dev: true /mime@2.6.0: @@ -15480,7 +15460,6 @@ packages: /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} - hasBin: true dev: true /mimic-fn@2.1.0: @@ -15647,12 +15626,10 @@ packages: /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} - hasBin: true /mkdirp@2.1.6: resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} engines: {node: '>=10'} - hasBin: true dev: true /mlly@1.3.0: @@ -15693,7 +15670,6 @@ packages: /msw@0.49.1(typescript@4.9.3): resolution: {integrity: sha512-JpIIq4P65ofj0HVmDMkJuRwgP9s5kcdutpZ15evMTb2k91/USB7IKWRLV9J1Mzc3OqTdwNj4RwtOWJ5y/FulQQ==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15729,7 +15705,6 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15765,7 +15740,6 @@ packages: /msw@1.2.1(typescript@5.0.4): resolution: {integrity: sha512-bF7qWJQSmKn6bwGYVPXOxhexTCGD5oJSZg8yt8IBClxvo3Dx/1W0zqE1nX9BSWmzRsCKWfeGWcB/vpqV6aclpw==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 5.0.x' @@ -15817,7 +15791,6 @@ packages: /nanoid@3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -15903,7 +15876,6 @@ packages: /next-sitemap@3.1.55(@next/env@13.3.4)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -15929,7 +15901,6 @@ packages: /next@13.3.4(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -16041,7 +16012,6 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.0)(tslib@2.5.0)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -16102,7 +16072,6 @@ packages: /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - requiresBuild: true optional: true /node-dir@0.1.17: @@ -16156,7 +16125,6 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} - requiresBuild: true optional: true /node-gyp@9.3.1: @@ -16193,7 +16161,6 @@ packages: /nodemon@2.0.22: resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} engines: {node: '>=8.10.0'} - hasBin: true dependencies: chokidar: 3.5.3 debug: 3.2.7(supports-color@5.5.0) @@ -16209,7 +16176,6 @@ packages: /nopt@1.0.10: resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true dependencies: abbrev: 1.1.1 dev: true @@ -16217,7 +16183,6 @@ packages: /nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true dependencies: abbrev: 1.1.1 @@ -18039,7 +18004,6 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18047,7 +18011,6 @@ packages: /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} - hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18088,14 +18051,12 @@ packages: /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - hasBin: true dependencies: glob: 7.2.3 dev: true /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - hasBin: true dependencies: glob: 7.2.3 dev: true @@ -18115,7 +18076,6 @@ packages: /rollup@3.21.6: resolution: {integrity: sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -18225,7 +18185,6 @@ packages: /sass@1.62.0: resolution: {integrity: sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==} engines: {node: '>=14.0.0'} - hasBin: true dependencies: chokidar: 3.5.3 immutable: 4.3.0 @@ -18302,21 +18261,17 @@ packages: /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} - hasBin: true dev: true /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} - hasBin: true dependencies: lru-cache: 6.0.0 @@ -18666,7 +18621,6 @@ packages: /sorcery@0.10.0: resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==} - hasBin: true dependencies: buffer-crc32: 0.2.13 minimist: 1.2.7 @@ -18719,7 +18673,6 @@ packages: /sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead dev: true /space-separated-tokens@1.1.5: @@ -19086,7 +19039,6 @@ packages: /svelte-check@2.10.3(@babel/core@7.21.4)(svelte@3.55.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} - hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -19260,7 +19212,6 @@ packages: /tailwindcss@3.3.1(postcss@8.4.21)(ts-node@10.9.1): resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} engines: {node: '>=12.13.0'} - hasBin: true peerDependencies: postcss: ^8.0.9 dependencies: @@ -19548,7 +19499,6 @@ packages: /touch@3.1.0: resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} - hasBin: true dependencies: nopt: 1.0.10 dev: true @@ -19586,7 +19536,6 @@ packages: /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -19618,7 +19567,6 @@ packages: /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19648,7 +19596,6 @@ packages: /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19710,7 +19657,6 @@ packages: /tsup@6.5.0(typescript@4.9.3): resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} engines: {node: '>=14'} - hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -19786,65 +19732,65 @@ packages: - supports-color dev: true - /turbo-darwin-64@1.10.1: - resolution: {integrity: sha512-isLLoPuAOMNsYovOq9BhuQOZWQuU13zYsW988KkkaA4OJqOn7qwa9V/KBYCJL8uVQqtG+/Y42J37lO8RJjyXuA==} + /turbo-darwin-64@1.10.2: + resolution: {integrity: sha512-sVLpVVANByfMgqf7OYPcZM4KiDnjGu7ITvAzBSa9Iwe14yoWLn8utrNsWCRaQEB6kEqBGLPmvL7AKwkl8M2Gqg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.1: - resolution: {integrity: sha512-x1nloPR10fLElNCv17BKr0kCx/O5gse/UXAcVscMZH2tvRUtXrdBmut62uw2YU3J9hli2fszYjUWXkulVpQvFA==} + /turbo-darwin-arm64@1.10.2: + resolution: {integrity: sha512-TKG91DSoYQjsCft4XBx4lYycVT5n3UQB/nOKgv/WJCSfwshLWulya3yhP8JT5erv9rPF8gwgnx87lrCmT4EAVA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.1: - resolution: {integrity: sha512-abV+ODCeOlz0503OZlHhPWdy3VwJZc1jObf1VQj7uQM+JqJ/kXbMyqJIMQVz+m7QJUFdferYPRxGhYT/NbYK7Q==} + /turbo-linux-64@1.10.2: + resolution: {integrity: sha512-ZIzAkfrzjJFkSM/uEfxU6JjseCsT5PHRu0s0lmYce37ApQbv/HC7tI0cFhuosI30+O8109/mkyZykKE7AQfgqA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.1: - resolution: {integrity: sha512-zRC3nZbHQ63tofOmbuySzEn1ROISWTkemYYr1L98rpmT5aVa0kERlGiYcfDwZh3cBso/Ylg/wxexRAaPzcCJYQ==} + /turbo-linux-arm64@1.10.2: + resolution: {integrity: sha512-G4uZA+RBQ5S1X/oUxO5KoLL2NDMkrrBZF52+00jQv6UEb9lWDgwzqSwoAGjdXxeDCrqMW5rBVwb/IBIF2/yhwA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.1: - resolution: {integrity: sha512-Irqz8IU+o7Q/5V44qatZBTunk+FQAOII1hZTsEU54ah62f9Y297K6/LSp+yncmVQOZlFVccXb6MDqcETExIQtA==} + /turbo-windows-64@1.10.2: + resolution: {integrity: sha512-ObfQO37kGu1jBzFs/L+hybrCXBwdnimotJwzg7pCoSyGijKITlugrpJoPDKlg0eMr3/1Y6KUeHy26vZaDXrbuQ==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.1: - resolution: {integrity: sha512-124IT15d2gyjC+NEn11pHOaVFvZDRHpxfF+LDUzV7YxfNIfV0mGkR3R/IyVXtQHOgqOdtQTbC4y411sm31+SEw==} + /turbo-windows-arm64@1.10.2: + resolution: {integrity: sha512-7S6dx4738R/FIT2cxbsunqgHN5LelXzuzkcaZgdkU33oswRf/6KOfOABzQLdTX7Uos59cBSdwayf6KQJxuOXUg==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.1: - resolution: {integrity: sha512-wq0YeSv6P/eEDXOL42jkMUr+T4z34dM8mdHu5u6C6OOAq8JuLJ72F/v4EVR1JmY8icyTkFz10ICLV0haUUYhbQ==} + /turbo@1.10.2: + resolution: {integrity: sha512-m9sR5XHhuzxUQACf0vI2qCG5OqDYAZiPTaAsTwECnwUF4/cXwEmcYddbLJnO+K9orNvcnjjent5oBNBVQ/o0ow==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.1 - turbo-darwin-arm64: 1.10.1 - turbo-linux-64: 1.10.1 - turbo-linux-arm64: 1.10.1 - turbo-windows-64: 1.10.1 - turbo-windows-arm64: 1.10.1 + turbo-darwin-64: 1.10.2 + turbo-darwin-arm64: 1.10.2 + turbo-linux-64: 1.10.2 + turbo-linux-arm64: 1.10.2 + turbo-windows-64: 1.10.2 + turbo-windows-arm64: 1.10.2 dev: true /type-check@0.3.2: @@ -19918,7 +19864,6 @@ packages: /typescript@4.8.4: resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} engines: {node: '>=4.2.0'} - hasBin: true dev: true /typescript@4.9.3: @@ -19932,7 +19877,6 @@ packages: /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} - hasBin: true dev: true /ua-parser-js@0.7.35: @@ -20191,7 +20135,6 @@ packages: /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -20379,7 +20322,6 @@ packages: /vite-node@0.31.4(@types/node@18.15.11): resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} engines: {node: '>=v14.18.0'} - hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 @@ -20446,7 +20388,6 @@ packages: /vite@3.2.5: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20479,7 +20420,6 @@ packages: /vite@4.2.0: resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20512,7 +20452,6 @@ packages: /vite@4.3.2(@types/node@18.15.11): resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20567,7 +20506,6 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20613,7 +20551,6 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20826,7 +20763,6 @@ packages: /webpack-dev-server@4.11.1(webpack@5.75.0): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} - hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -20901,7 +20837,6 @@ packages: /webpack@5.75.0(esbuild@0.17.8): resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} engines: {node: '>=10.13.0'} - hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -21098,14 +21033,12 @@ packages: /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} - hasBin: true dependencies: isexe: 2.0.0 /which@3.0.1: resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true dependencies: isexe: 2.0.0 dev: true @@ -21113,7 +21046,6 @@ packages: /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} - hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 @@ -21376,7 +21308,6 @@ packages: /z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} - hasBin: true dependencies: lodash.get: 4.4.2 lodash.isequal: 4.5.0 From 078fe8e883e7ce0c1b0e2da025e93e0fb7e6ed00 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:17:56 +0200 Subject: [PATCH 21/68] upgrade pnpm version on workflow --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bbbbd86d..287d85f3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -23,7 +23,7 @@ jobs: name: Install pnpm id: pnpm-install with: - version: 7 + version: 8.1.0 run_install: false - name: Get pnpm store directory From 3f2819a0e5ded44bf177439bb8e909232aaab7f2 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:26:14 +0200 Subject: [PATCH 22/68] revert pnpm version --- .github/workflows/tests.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 287d85f3..c62fb7a8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -11,19 +11,17 @@ on: jobs: build: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Use Node.js uses: actions/setup-node@v3 with: node-version: "16.19.0" - - uses: pnpm/action-setup@v2 name: Install pnpm id: pnpm-install with: - version: 8.1.0 + version: 7 run_install: false - name: Get pnpm store directory From 16e564f539aca7dc0289e148a68610d1656f0012 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:43:36 +0200 Subject: [PATCH 23/68] fix lockfile --- pnpm-lock.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d4bac6d..32d150b3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21332,6 +21332,3 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false From 7be093b930ed4f6541b6e5b380104a4125d42381 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:44:20 +0200 Subject: [PATCH 24/68] make fetch isomorphic --- packages/core/package.json | 2 +- packages/core/src/shared/http.ts | 15 ++++++++-- pnpm-lock.yaml | 50 ++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index f66d6410..70a9604e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,7 +39,7 @@ "zod": "^3.19.1" }, "dependencies": { - "cross-fetch": "^3.1.6", + "node-fetch": "^3.3.0", "ts-toolbelt": "^9.6.0" } } \ No newline at end of file diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index d901cddb..7e3d312d 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,7 +1,16 @@ import { ABBY_BASE_URL } from "./constants"; import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; -import { fetch } from "cross-fetch"; +function fetchData(url: RequestInfo | URL, init?: RequestInit) { + if (typeof window === 'undefined') { + // Running in Node.js + const fetch = require('node-fetch'); + return fetch(url) + } else { + // Running in a browser + return fetch(url); + } +} export abstract class HttpService { static async getProjectData({ projectId, @@ -13,7 +22,7 @@ export abstract class HttpService { url?: string; }) { try { - const res = await fetch( + const res = await fetchData( `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${environment ? `?environment=${environment}` : "" }` ); @@ -45,7 +54,7 @@ export abstract class HttpService { // don't send data in development return; } - return fetch(`${url ?? ABBY_BASE_URL}api/data`, { + return fetchData(`${url ?? ABBY_BASE_URL}api/data`, { method: "POST", headers: { "Content-Type": "application/json", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32d150b3..774c96ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -560,9 +560,9 @@ importers: packages/core: dependencies: - cross-fetch: - specifier: ^3.1.6 - version: 3.1.6 + node-fetch: + specifier: ^3.3.0 + version: 3.3.0 ts-toolbelt: specifier: ^9.6.0 version: 9.6.0 @@ -573,9 +573,6 @@ importers: msw: specifier: ^0.49.1 version: 0.49.1(typescript@4.9.3) - node-fetch: - specifier: ^3.3.0 - version: 3.3.0 tsconfig: specifier: workspace:* version: link:../tsconfig @@ -1368,6 +1365,7 @@ packages: /@angular/compiler-cli@15.2.0(@angular/compiler@15.2.0)(typescript@4.9.5): resolution: {integrity: sha512-ETnRBdY/LGcmDRQ9GQc9KyCd1kuRnj+Y9luq2dCTMysP+NgylmYoGDsJOsDKm6SzPo+B4PSAyHX2J4CVQFHpPg==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler': 15.2.0 typescript: '>=4.8.2 <5.0' @@ -7110,6 +7108,7 @@ packages: /@sveltejs/kit@1.15.8(svelte@3.58.0)(vite@4.3.2): resolution: {integrity: sha512-xPIF3UbFEA5BBZWFTGGUtSZ0O3DAtmzIp/yZZVdLIfzZ9+geKG3iGSVFnOUdYstjU7JcvJg12UC5MD5xoED59A==} engines: {node: ^16.14 || >=18} + hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 @@ -7137,6 +7136,7 @@ packages: /@sveltejs/package@2.0.2(svelte@3.58.0)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} + hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -9060,6 +9060,7 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -9074,6 +9075,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.21): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10145,14 +10147,6 @@ packages: postcss: 8.4.21 pretty-bytes: 5.6.0 - /cross-fetch@3.1.6: - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} - dependencies: - node-fetch: 2.6.11 - transitivePeerDependencies: - - encoding - dev: false - /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -10271,7 +10265,6 @@ packages: /data-uri-to-buffer@4.0.0: resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} engines: {node: '>= 12'} - dev: true /data-urls@2.0.0: resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} @@ -11322,6 +11315,7 @@ packages: /eslint-config-prettier@8.5.0(eslint@7.32.0): resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -12170,7 +12164,6 @@ packages: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.2.1 - dev: true /fetch-retry@5.0.4: resolution: {integrity: sha512-LXcdgpdcVedccGg0AZqg+S8lX/FCdwXD92WNZ5k5qsb0irRhSFsBOpcJt7oevyqT2/C2nEE0zSFNdBEpj3YOSw==} @@ -12372,7 +12365,6 @@ packages: engines: {node: '>=12.20.0'} dependencies: fetch-blob: 3.2.0 - dev: true /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} @@ -13989,6 +13981,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.4): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15670,6 +15663,7 @@ packages: /msw@0.49.1(typescript@4.9.3): resolution: {integrity: sha512-JpIIq4P65ofj0HVmDMkJuRwgP9s5kcdutpZ15evMTb2k91/USB7IKWRLV9J1Mzc3OqTdwNj4RwtOWJ5y/FulQQ==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15705,6 +15699,7 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15740,6 +15735,7 @@ packages: /msw@1.2.1(typescript@5.0.4): resolution: {integrity: sha512-bF7qWJQSmKn6bwGYVPXOxhexTCGD5oJSZg8yt8IBClxvo3Dx/1W0zqE1nX9BSWmzRsCKWfeGWcB/vpqV6aclpw==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 5.0.x' @@ -15876,6 +15872,7 @@ packages: /next-sitemap@3.1.55(@next/env@13.3.4)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -15901,6 +15898,7 @@ packages: /next@13.3.4(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -16012,6 +16010,7 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.0)(tslib@2.5.0)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -16084,7 +16083,6 @@ packages: /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - dev: true /node-fetch-native@1.1.0: resolution: {integrity: sha512-nl5goFCig93JZ9FIV8GHT9xpNqXbxQUzkOmKIMKmncsBH9jhg7qKex8hirpymkBFmNQ114chEEG5lS4wgK2I+Q==} @@ -16108,7 +16106,6 @@ packages: data-uri-to-buffer: 4.0.0 fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - dev: true /node-fetch@3.3.1: resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} @@ -19039,6 +19036,7 @@ packages: /svelte-check@2.10.3(@babel/core@7.21.4)(svelte@3.55.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -19212,6 +19210,7 @@ packages: /tailwindcss@3.3.1(postcss@8.4.21)(ts-node@10.9.1): resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} engines: {node: '>=12.13.0'} + hasBin: true peerDependencies: postcss: ^8.0.9 dependencies: @@ -19567,6 +19566,7 @@ packages: /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19596,6 +19596,7 @@ packages: /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19657,6 +19658,7 @@ packages: /tsup@6.5.0(typescript@4.9.3): resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} engines: {node: '>=14'} + hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -20135,6 +20137,7 @@ packages: /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -20388,6 +20391,7 @@ packages: /vite@3.2.5: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20420,6 +20424,7 @@ packages: /vite@4.2.0: resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20452,6 +20457,7 @@ packages: /vite@4.3.2(@types/node@18.15.11): resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20506,6 +20512,7 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20551,6 +20558,7 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20693,7 +20701,6 @@ packages: /web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} - dev: true /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -20763,6 +20770,7 @@ packages: /webpack-dev-server@4.11.1(webpack@5.75.0): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} + hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -20837,6 +20845,7 @@ packages: /webpack@5.75.0(esbuild@0.17.8): resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} engines: {node: '>=10.13.0'} + hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -21331,4 +21340,3 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false - From f46c9ccd4677f86646a2676f23e90541b07ec772 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Fri, 9 Jun 2023 17:17:46 +0200 Subject: [PATCH 25/68] add: test WIP --- packages/nodejs/package.json | 2 + packages/nodejs/src/abby/createAbby.ts | 80 +++++++++--------- packages/nodejs/src/express/abbyMiddleware.ts | 47 ++++++----- packages/nodejs/src/tests/abby.test.ts | 35 ++++++-- packages/nodejs/src/tests/abbyExpress.test.ts | 23 ++++++ pnpm-lock.yaml | 82 +++++++++++++++++++ 6 files changed, 198 insertions(+), 71 deletions(-) create mode 100644 packages/nodejs/src/tests/abbyExpress.test.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 4df3f6a7..0f5e3c20 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -21,9 +21,11 @@ "@types/express": "^4.17.17", "@types/jest": "^29.5.1", "@types/node": "^20.2.5", + "install": "^0.13.0", "msw": "^1.2.1", "node-fetch": "^3.3.1", "nodemon": "^2.0.22", + "supertest": "^6.3.3", "ts-node": "^10.9.1", "ts-toolbelt": "^9.6.0", "typescript": "^5.0.4", diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 5959a18a..aa95df4f 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,49 +1,43 @@ -import { ABConfig, Abby, AbbyConfig } from "@tryabby/core"; -import { F } from "ts-toolbelt" -import { Request } from "express"; -import { TestStorageService } from "./StorageService.ts"; +import { ABConfig, Abby, AbbyConfig } from '@tryabby/core'; +import { F } from 'ts-toolbelt'; +import { Request } from 'express'; +import { TestStorageService } from './StorageService.ts'; export async function createAbby< - FlagName extends string, - TestName extends string, - Tests extends Record, - ConfigType extends AbbyConfig = AbbyConfig + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig >(abbyConfig: F.Narrow>) { - const abby = new Abby( - abbyConfig, - { - get: (key: string) => { - return TestStorageService.get(abbyConfig.projectId, key); - }, - set: (key: string, value: any) => { - TestStorageService.set(abbyConfig.projectId, key, value) - }, - }, - ); + const abby = new Abby(abbyConfig, { + get: (key: string) => { + return TestStorageService.get(abbyConfig.projectId, key); + }, + set: (key: string, value: any) => { + TestStorageService.set(abbyConfig.projectId, key, value); + } + }); - //load data and initialise the abby Object - await abby.loadProjectData(); + //load data and initialise the abby Object + await abby.loadProjectData(); - /** - * @param req express request object - * @param name Name of the test that the variant should be retrieved for - * @returns Value of the currently selected variant - */ - const getABTestValue = (req: Request, name: T) => { - const value = abby.getTestVariant(name); - return value; - } - /** - * - * @param name Name of the feature flag - * @returns Value of the feature flag - */ - const getFeatureFlagValue = async [number]>( - name: F - ) => { - await abby.loadProjectData(); - return abby.getFeatureFlag(name); - }; + /** + * @param req express request object + * @param name Name of the test that the variant should be retrieved for + * @returns Value of the currently selected variant + */ + const getABTestValue = (req: Request, name: T) => { + const value = abby.getTestVariant(name); + return value; + }; + /** + * + * @param name Name of the feature flag + * @returns Value of the feature flag + */ + const getFeatureFlagValue = [number]>(name: F) => { + return abby.getFeatureFlag(name); + }; - return { getFeatureFlagValue, getABTestValue } -} \ No newline at end of file + return { getFeatureFlagValue, getABTestValue }; +} diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index a9b15096..ba8d00ed 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -1,24 +1,33 @@ /* eslint-disable react-hooks/rules-of-hooks */ //TODO fix eslint -import { getFeatureFlagValue, getABTestValue } from "../abby/abby.ts"; -import { NextFunction, Request, Response } from "express"; -import { setRequest } from "../abby/contexts/requestContext.ts"; -import { setResponse } from "../abby/contexts/responseContext.ts"; +import { getFeatureFlagValue, getABTestValue } from '../abby/abby.ts'; +import { NextFunction, Request, Response } from 'express'; +import { setRequest } from '../abby/contexts/requestContext.ts'; +import { setResponse } from '../abby/contexts/responseContext.ts'; -export const featureFlagMiddleware = async (req: Request, res: Response, name: string, next: NextFunction) => { //Todo fix types - const flagValue = await getFeatureFlagValue(name as any); //type? - console.log("hi from middleware", name, flagValue) - if (!flagValue) { - res.sendStatus(403); - return; - } - next(); -} +//TODO make types narrow like in createAbby +//TODO make abby import configurable + +export const featureFlagMiddleware = async ( + req: Request, + res: Response, + name: string, + next: NextFunction +) => { + //Todo fix types + const flagValue = getFeatureFlagValue(name as any); //type? + console.log('hi from middleware', name, flagValue); + if (!flagValue) { + res.sendStatus(403); + return; + } + next(); +}; export const AbTestMiddleware = (req: Request, res: Response, name: string, next: NextFunction) => { - setRequest(req) - setResponse(res) - const value = getABTestValue(req, name as any); - console.log(value); - next(); -} \ No newline at end of file + setRequest(req); + setResponse(res); + const value = getABTestValue(req, name as any); + console.log(value); + next(); +}; diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index a3e014ab..57188269 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -1,9 +1,26 @@ -import { expect, test, describe } from "vitest" - -describe("it works", () => { - test("test", () => { - console.log("test running") - expect(true, "ja").toBeTruthy(); - }) -} -) \ No newline at end of file +import { expect, test, describe } from 'vitest'; +import { createAbby } from '../abby/createAbby.ts'; + +describe('it works', () => { + test('getFeatureFlagValue working', async () => { + const { getABTestValue, getFeatureFlagValue } = await createAbby({ + projectId: '', + tests: {}, + flags: ['flag1', 'flag2'] + }); + + console.log(await getFeatureFlagValue('flag1')); + + expect(await getFeatureFlagValue('flag1')).toBeTruthy(); + expect(await getFeatureFlagValue('flag2')).toBeFalsy(); + }); + + test('getABTestValue working', async () => { + const { getABTestValue, getFeatureFlagValue } = await createAbby({ + projectId: '', + tests: { + 'New Test1': {} + } + }); + }); +}); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts new file mode 100644 index 00000000..aa6cac15 --- /dev/null +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -0,0 +1,23 @@ +import { expect, test, describe } from 'vitest'; +import { createAbby } from '../abby/createAbby.ts'; +import express, { request, response } from 'express'; +import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddleware.ts'; + +describe('express middleware working', () => { + let app: express.Application; + + beforeEach(() => { + app = express(); + // Add any other middlewares or routes necessary for your test + }); + + test('abTestMiddleware working', async () => { + //test cookie retrieval + //check if cookie is set + }); + + test('featureFlag Middleware working', async () => { + app.use('/', (req, res, next) => AbTestMiddleware(req, res, 'New Test3', next)); + //check if feature flag value is respected + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55a236cb..8d5d2826 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -778,6 +778,9 @@ importers: '@types/node': specifier: ^20.2.5 version: 20.2.5 + install: + specifier: ^0.13.0 + version: 0.13.0 msw: specifier: ^1.2.1 version: 1.2.1(typescript@5.0.4) @@ -787,6 +790,9 @@ importers: nodemon: specifier: ^2.0.22 version: 2.0.22 + supertest: + specifier: ^6.3.3 + version: 6.3.3 ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) @@ -9003,6 +9009,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + /assert@2.0.0: resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==} dependencies: @@ -9950,6 +9960,10 @@ packages: /commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + /component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + /compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -10081,6 +10095,10 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + /cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + dev: true + /copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} dependencies: @@ -10533,6 +10551,13 @@ packages: resolution: {integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA==} dev: true + /dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + dev: true + /di@0.0.1: resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} @@ -12141,6 +12166,10 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: true + /fastq@1.14.0: resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} dependencies: @@ -12372,6 +12401,15 @@ packages: dependencies: fetch-blob: 3.2.0 + /formidable@2.1.2: + resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + qs: 6.11.0 + dev: true + /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -12957,6 +12995,11 @@ packages: resolution: {integrity: sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA==} dev: true + /hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + dev: true + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -13314,6 +13357,11 @@ packages: wrap-ansi: 7.0.0 dev: true + /install@0.13.0: + resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==} + engines: {node: '>= 0.10'} + dev: true + /internal-slot@1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} @@ -15441,20 +15489,24 @@ packages: /mime@1.4.1: resolution: {integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==} + hasBin: true dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} + hasBin: true /mime@2.5.2: resolution: {integrity: sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==} engines: {node: '>=4.0.0'} + hasBin: true dev: true /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} + hasBin: true /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} @@ -18267,6 +18319,7 @@ packages: /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} @@ -18275,6 +18328,7 @@ packages: /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} + hasBin: true dependencies: lru-cache: 6.0.0 @@ -19004,6 +19058,24 @@ packages: pirates: 4.0.5 ts-interface-checker: 0.1.13 + /superagent@8.0.9: + resolution: {integrity: sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==} + engines: {node: '>=6.4.0 <13 || >=14'} + dependencies: + component-emitter: 1.3.0 + cookiejar: 2.1.4 + debug: 4.3.4 + fast-safe-stringify: 2.1.1 + form-data: 4.0.0 + formidable: 2.1.2 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.11.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + dev: true + /superjson@1.9.1: resolution: {integrity: sha512-oT3HA2nPKlU1+5taFgz/HDy+GEaY+CWEbLzaRJVD4gZ7zMVVC4GDNFdgvAZt6/VuIk6D2R7RtPAiCHwmdzlMmg==} engines: {node: '>=10'} @@ -19011,6 +19083,16 @@ packages: copy-anything: 3.0.3 dev: false + /supertest@6.3.3: + resolution: {integrity: sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==} + engines: {node: '>=6.4.0'} + dependencies: + methods: 1.1.2 + superagent: 8.0.9 + transitivePeerDependencies: + - supports-color + dev: true + /supports-color@4.5.0: resolution: {integrity: sha512-ycQR/UbvI9xIlEdQT1TQqwoXtEldExbCEAJgRo5YXlmSKjv6ThHnP9/vwGa1gr19Gfw+LkFd7KqYMhzrRC5JYw==} engines: {node: '>=4'} From d0a85aea8979619909f828ac4edc1be6e7adfdf5 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 13 Jun 2023 13:33:15 +0200 Subject: [PATCH 26/68] tests wip --- packages/core/src/shared/http.ts | 128 ++++++++++++++++--------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index 7e3d312d..7a840767 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,67 +1,71 @@ -import { ABBY_BASE_URL } from "./constants"; -import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; +import { ABBY_BASE_URL } from './constants'; +import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from './index'; + +// +// function fetchData(url: RequestInfo | URL, init?: RequestInit) { +// if (typeof window === 'undefined') { +// Running in Node.js +// const fetch = require('node-fetch'); +// return fetch(url); +// } else { +// Running in a browser +// return fetch(url); +// } +// } -function fetchData(url: RequestInfo | URL, init?: RequestInit) { - if (typeof window === 'undefined') { - // Running in Node.js - const fetch = require('node-fetch'); - return fetch(url) - } else { - // Running in a browser - return fetch(url); - } -} export abstract class HttpService { - static async getProjectData({ - projectId, - environment, - url, - }: { - projectId: string; - environment?: string; - url?: string; - }) { - try { - const res = await fetchData( - `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${environment ? `?environment=${environment}` : "" - }` - ); + static async getProjectData({ + projectId, + environment, + url + }: { + projectId: string; + environment?: string; + url?: string; + }) { + try { + console.log( + `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ + environment ? `?environment=${environment}` : '' + }` + ); + const res = await fetch( + `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ + environment ? `?environment=${environment}` : '' + }` + ); - if (!res.ok) return null; - const data = (await res.json()) as AbbyDataResponse; - return data; - } catch (err) { - console.error( - "[ABBY]: failed to load project data, falling back to defaults" - ); - return null; - } - } + if (!res.ok) return null; + const data = (await res.json()) as AbbyDataResponse; + return data; + } catch (err) { + console.error('[ABBY]: failed to load project data, falling back to defaults'); + console.log(err); + return null; + } + } - static sendData({ - url, - type, - data, - }: { - url?: string; - type: AbbyEventType; - data: Omit; - }) { - if ( - typeof window === "undefined" || - window.location.hostname === "localhost" - ) { - // don't send data in development - return; - } - return fetchData(`${url ?? ABBY_BASE_URL}api/data`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ type, ...data }), - // catch error and forget about them for now - // TODO: add error debugging - }).catch(() => { }); - } + static sendData({ + url, + type, + data + }: { + url?: string; + type: AbbyEventType; + data: Omit; + }) { + if (typeof window === 'undefined' || window.location.hostname === 'localhost') { + // don't send data in development + return; + } + return fetch(`${url ?? ABBY_BASE_URL}api/data`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ type, ...data }) + // catch error and forget about them for now + // TODO: add error debugging + }).catch(() => {}); + } } From b7baf02e3c5c00546bf7a978f6608603f4ac0a70 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 13 Jun 2023 13:35:00 +0200 Subject: [PATCH 27/68] tests wip --- packages/nodejs/package.json | 2 + packages/nodejs/src/abby/createAbby.ts | 2 + packages/nodejs/src/express/abbyMiddleware.ts | 4 +- packages/nodejs/src/tests/abby.test.ts | 8 +- packages/nodejs/src/tests/abbyExpress.test.ts | 23 --- .../nodejs/src/tests/abbyExpress.test2.ts | 44 +++++ packages/nodejs/src/tests/mocks/handlers.ts | 59 +++--- packages/nodejs/src/tests/mocks/server.ts | 4 +- packages/nodejs/src/tests/setup.ts | 15 ++ packages/nodejs/vite.config.ts | 11 ++ packages/svelte/src/lib/createAbby.ts | 5 +- pnpm-lock.yaml | 169 ++++++++++++++---- 12 files changed, 253 insertions(+), 93 deletions(-) delete mode 100644 packages/nodejs/src/tests/abbyExpress.test.ts create mode 100644 packages/nodejs/src/tests/abbyExpress.test2.ts create mode 100644 packages/nodejs/src/tests/setup.ts create mode 100644 packages/nodejs/vite.config.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 0f5e3c20..28a3c249 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -14,6 +14,7 @@ "license": "ISC", "dependencies": { "@tryabby/core": "workspace:^", + "@types/supertest": "^2.0.12", "axios": "^1.4.0", "express": "^4.18.2" }, @@ -29,6 +30,7 @@ "ts-node": "^10.9.1", "ts-toolbelt": "^9.6.0", "typescript": "^5.0.4", + "vite": "^4.3.9", "vitest": "^0.31.4" } } \ No newline at end of file diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index aa95df4f..651b1dff 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -21,6 +21,8 @@ export async function createAbby< //load data and initialise the abby Object await abby.loadProjectData(); + const config = abbyConfig as unknown as ConfigType; + /** * @param req express request object * @param name Name of the test that the variant should be retrieved for diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts index ba8d00ed..a9450878 100644 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ b/packages/nodejs/src/express/abbyMiddleware.ts @@ -1,6 +1,7 @@ /* eslint-disable react-hooks/rules-of-hooks */ //TODO fix eslint import { getFeatureFlagValue, getABTestValue } from '../abby/abby.ts'; +import { type ConfigType } from '../abby/createAbby.ts'; import { NextFunction, Request, Response } from 'express'; import { setRequest } from '../abby/contexts/requestContext.ts'; import { setResponse } from '../abby/contexts/responseContext.ts'; @@ -14,8 +15,9 @@ export const featureFlagMiddleware = async ( name: string, next: NextFunction ) => { + console.log('middleware'); //Todo fix types - const flagValue = getFeatureFlagValue(name as any); //type? + const flagValue = true; //getFeatureFlagValue('lol'); //type? console.log('hi from middleware', name, flagValue); if (!flagValue) { res.sendStatus(403); diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index 57188269..51eeda5b 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -3,8 +3,8 @@ import { createAbby } from '../abby/createAbby.ts'; describe('it works', () => { test('getFeatureFlagValue working', async () => { - const { getABTestValue, getFeatureFlagValue } = await createAbby({ - projectId: '', + const { getFeatureFlagValue } = await createAbby({ + projectId: '123', tests: {}, flags: ['flag1', 'flag2'] }); @@ -15,9 +15,9 @@ describe('it works', () => { expect(await getFeatureFlagValue('flag2')).toBeFalsy(); }); - test('getABTestValue working', async () => { + test.skip('getABTestValue working', async () => { const { getABTestValue, getFeatureFlagValue } = await createAbby({ - projectId: '', + projectId: '123', tests: { 'New Test1': {} } diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts deleted file mode 100644 index aa6cac15..00000000 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { expect, test, describe } from 'vitest'; -import { createAbby } from '../abby/createAbby.ts'; -import express, { request, response } from 'express'; -import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddleware.ts'; - -describe('express middleware working', () => { - let app: express.Application; - - beforeEach(() => { - app = express(); - // Add any other middlewares or routes necessary for your test - }); - - test('abTestMiddleware working', async () => { - //test cookie retrieval - //check if cookie is set - }); - - test('featureFlag Middleware working', async () => { - app.use('/', (req, res, next) => AbTestMiddleware(req, res, 'New Test3', next)); - //check if feature flag value is respected - }); -}); diff --git a/packages/nodejs/src/tests/abbyExpress.test2.ts b/packages/nodejs/src/tests/abbyExpress.test2.ts new file mode 100644 index 00000000..18864fee --- /dev/null +++ b/packages/nodejs/src/tests/abbyExpress.test2.ts @@ -0,0 +1,44 @@ +import { expect, test, describe, beforeEach } from 'vitest'; +import { createAbby } from '../abby/createAbby.ts'; +import express, { response } from 'express'; +import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddleware.ts'; +import request from 'supertest'; + +describe.skip('express middleware working', () => { + let app: express.Application; + + beforeEach(() => { + app = express(); + // Add any other middlewares or routes necessary for your test + }); + + test('abTestMiddleware working', async () => { + const result = true; + //test cookie retrieval + app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); + app.get('/', (req, res) => { + res.status(200); + res.send('hi'); + }); + + const res = await request(app).get('/'); + console.log(res.statusCode); + //check if cookie is set + expect(result).toBeFalsy(); + }); + + test('featureFlag Middleware working', async () => { + const result = true; + app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); + app.get('/', (req, res) => { + res.status(200); + res.send('hi'); + }); + + const res = await request(app).get('/'); + console.log(res.statusCode); + + expect(result).toBeFalsy(); + //check if feature flag value is respected + }); +}); diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts index 5fb79a5a..1e80961a 100644 --- a/packages/nodejs/src/tests/mocks/handlers.ts +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -1,31 +1,34 @@ -import { rest } from "msw"; -import { type AbbyDataResponse, ABBY_BASE_URL } from "@tryabby/core"; +import { rest } from 'msw'; +import { type AbbyDataResponse, ABBY_BASE_URL } from '@tryabby/core'; + +console.log('call m ock'); export const handlers = [ - rest.get(`${ABBY_BASE_URL}api/dashboard/:projectId/data`, (req, res, ctx) => { - return res( - ctx.json({ - tests: [ - { - name: "test", - weights: [1, 1, 1, 1], - }, - { - name: "test2", - weights: [1, 0], - }, - ], - flags: [ - { - name: "flag1", - isEnabled: true, - }, - { - name: "flag2", - isEnabled: false, - }, - ], - } as AbbyDataResponse) - ); - }), + rest.get(`${ABBY_BASE_URL}api/dashboard/123/data`, (req, res, ctx) => { + console.log('call mock'); + return res( + ctx.json({ + tests: [ + { + name: 'test', + weights: [1, 1, 1, 1] + }, + { + name: 'test2', + weights: [1, 0] + } + ], + flags: [ + { + name: 'flag1', + isEnabled: true + }, + { + name: 'flag2', + isEnabled: false + } + ] + } as AbbyDataResponse) + ); + }) ]; diff --git a/packages/nodejs/src/tests/mocks/server.ts b/packages/nodejs/src/tests/mocks/server.ts index 5f3117f0..e14370b2 100644 --- a/packages/nodejs/src/tests/mocks/server.ts +++ b/packages/nodejs/src/tests/mocks/server.ts @@ -1,5 +1,5 @@ -import { setupServer } from "msw/node"; -import { handlers } from "./handlers.ts"; +import { setupServer } from 'msw/node'; +import { handlers } from './handlers.ts'; // This configures a request mocking server with the given request handlers. export const server = setupServer(...handlers); diff --git a/packages/nodejs/src/tests/setup.ts b/packages/nodejs/src/tests/setup.ts new file mode 100644 index 00000000..242ad08e --- /dev/null +++ b/packages/nodejs/src/tests/setup.ts @@ -0,0 +1,15 @@ +import { expect, afterEach } from 'vitest'; + +import { server } from './mocks/server.ts'; +import fetch from 'node-fetch'; + +/// @ts-ignore +global.fetch = fetch; + +// Establish API mocking before all tests. +beforeAll(() => server.listen()); +// Reset any request handlers that we may add during the tests, +// so they don't affect other tests. +afterEach(() => server.resetHandlers()); +// Clean up after the tests are finished. +afterAll(() => server.close()); diff --git a/packages/nodejs/vite.config.ts b/packages/nodejs/vite.config.ts new file mode 100644 index 00000000..0e3c354c --- /dev/null +++ b/packages/nodejs/vite.config.ts @@ -0,0 +1,11 @@ +/// + +import { defineConfig } from 'vite'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + setupFiles: './src/tests/setup.ts' + } +}); diff --git a/packages/svelte/src/lib/createAbby.ts b/packages/svelte/src/lib/createAbby.ts index 36c45e41..237a5073 100644 --- a/packages/svelte/src/lib/createAbby.ts +++ b/packages/svelte/src/lib/createAbby.ts @@ -2,7 +2,6 @@ import { Abby, type AbbyConfig, type ABConfig } from "@tryabby/core"; import { HttpService, AbbyEventType } from "@tryabby/core"; import { derived } from "svelte/store"; import type { F } from "ts-toolbelt"; -// import type { LayoutServerLoad, LayoutServerLoadEvent } from "../routes/$types"; TODO fix import import { FlagStorageService, TestStorageService } from "./StorageService"; import AbbyProvider from "./AbbyProvider.svelte"; import AbbyDevtools from "./AbbyDevtools.svelte"; @@ -43,6 +42,7 @@ export function createAbby< const abbyConfig = config as unknown as ConfigType; + const notify = (name: N, selectedVariant: string) => { if (!name || !selectedVariant) return; HttpService.sendData({ @@ -114,7 +114,7 @@ export function createAbby< }); }; - const withAbby = (handler?: any) => { + const withAbby = (handler?: ) => { //TODO fix type import return async (evt: any) => { const data = await handler?.(evt); @@ -149,4 +149,5 @@ export function createAbby< AbbyProvider, withDevTools, }; + export type {ConfigType}; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d5d2826..581c4a6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -762,6 +762,9 @@ importers: '@tryabby/core': specifier: workspace:^ version: link:../core + '@types/supertest': + specifier: ^2.0.12 + version: 2.0.12 axios: specifier: ^1.4.0 version: 1.4.0 @@ -802,6 +805,9 @@ importers: typescript: specifier: ^5.0.4 version: 5.0.4 + vite: + specifier: ^4.3.9 + version: 4.3.9(@types/node@20.2.5) vitest: specifier: ^0.31.4 version: 0.31.4 @@ -959,7 +965,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.2(@types/node@18.15.11) + version: 4.3.2 vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.2) @@ -7064,7 +7070,7 @@ packages: fetch-retry: 5.0.4 fs-extra: 11.1.1 isomorphic-unfetch: 3.1.0 - nanoid: 3.3.4 + nanoid: 3.3.6 read-pkg-up: 7.0.1 transitivePeerDependencies: - encoding @@ -7140,7 +7146,7 @@ packages: svelte: 3.58.0 tiny-glob: 0.2.9 undici: 5.22.1 - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.2 transitivePeerDependencies: - supports-color dev: true @@ -7193,7 +7199,7 @@ packages: magic-string: 0.29.0 svelte: 3.58.0 svelte-hmr: 0.15.1(svelte@3.58.0) - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.2 vitefu: 0.2.4(vite@4.3.2) transitivePeerDependencies: - supports-color @@ -7212,7 +7218,7 @@ packages: magic-string: 0.30.0 svelte: 3.58.0 svelte-hmr: 0.15.1(svelte@3.58.0) - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.2 vitefu: 0.2.4(vite@4.3.2) transitivePeerDependencies: - supports-color @@ -7832,6 +7838,10 @@ packages: resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} dev: true + /@types/cookiejar@2.1.2: + resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} + dev: false + /@types/cors@2.8.13: resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} dependencies: @@ -8174,6 +8184,19 @@ packages: resolution: {integrity: sha512-5poJyz1QFXpi1hE2bAWy7gFMdj5Fgofm94DNCaTK9V2LeWPdhCQIaP/6qUagZwgCcTURXzih1J7f3sjXH1cOsw==} dev: false + /@types/superagent@4.1.18: + resolution: {integrity: sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==} + dependencies: + '@types/cookiejar': 2.1.2 + '@types/node': 18.15.11 + dev: false + + /@types/supertest@2.0.12: + resolution: {integrity: sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==} + dependencies: + '@types/superagent': 4.1.18 + dev: false + /@types/testing-library__jest-dom@5.14.5: resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} dependencies: @@ -10168,7 +10191,7 @@ packages: css-select: 4.3.0 parse5: 6.0.1 parse5-htmlparser2-tree-adapter: 6.0.1 - postcss: 8.4.21 + postcss: 8.4.24 pretty-bytes: 5.6.0 /cross-spawn@5.1.0: @@ -10197,12 +10220,12 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.21) - postcss-modules-local-by-default: 4.0.0(postcss@8.4.21) - postcss-modules-scope: 3.0.0(postcss@8.4.21) - postcss-modules-values: 4.0.0(postcss@8.4.21) + icss-utils: 5.1.0(postcss@8.4.24) + postcss: 8.4.24 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.24) + postcss-modules-local-by-default: 4.0.0(postcss@8.4.24) + postcss-modules-scope: 3.0.0(postcss@8.4.24) + postcss-modules-values: 4.0.0(postcss@8.4.24) postcss-value-parser: 4.2.0 semver: 7.3.8 webpack: 5.75.0(esbuild@0.17.8) @@ -11179,6 +11202,7 @@ packages: /esbuild@0.17.17: resolution: {integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.17 @@ -13202,13 +13226,13 @@ packages: dependencies: safer-buffer: 2.1.2 - /icss-utils@5.1.0(postcss@8.4.21): + /icss-utils@5.1.0(postcss@8.4.24): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.24 /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -15846,6 +15870,11 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -17025,42 +17054,42 @@ packages: semver: 7.3.8 webpack: 5.75.0(esbuild@0.17.8) - /postcss-modules-extract-imports@3.0.0(postcss@8.4.21): + /postcss-modules-extract-imports@3.0.0(postcss@8.4.24): resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.24 - /postcss-modules-local-by-default@4.0.0(postcss@8.4.21): + /postcss-modules-local-by-default@4.0.0(postcss@8.4.24): resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 + icss-utils: 5.1.0(postcss@8.4.24) + postcss: 8.4.24 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 - /postcss-modules-scope@3.0.0(postcss@8.4.21): + /postcss-modules-scope@3.0.0(postcss@8.4.24): resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.24 postcss-selector-parser: 6.0.11 - /postcss-modules-values@4.0.0(postcss@8.4.21): + /postcss-modules-values@4.0.0(postcss@8.4.24): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 + icss-utils: 5.1.0(postcss@8.4.24) + postcss: 8.4.24 /postcss-nested@6.0.0(postcss@8.4.21): resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} @@ -17106,7 +17135,7 @@ packages: resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.4 + nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 @@ -17118,6 +17147,14 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.24: + resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + /preact-render-to-string@5.2.6(preact@10.11.3): resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: @@ -18047,7 +18084,7 @@ packages: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.4.21 + postcss: 8.4.24 source-map: 0.6.1 /resolve@1.19.0: @@ -18131,6 +18168,7 @@ packages: /rollup@3.21.6: resolution: {integrity: sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -20419,7 +20457,7 @@ packages: mlly: 1.3.0 pathe: 1.1.0 picocolors: 1.0.0 - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.9(@types/node@18.15.11) transitivePeerDependencies: - '@types/node' - less @@ -20469,7 +20507,7 @@ packages: kolorist: 1.7.0 magic-string: 0.29.0 ts-morph: 18.0.0 - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.2 transitivePeerDependencies: - '@types/node' - rollup @@ -20542,7 +20580,7 @@ packages: fsevents: 2.3.2 dev: true - /vite@4.3.2(@types/node@18.15.11): + /vite@4.3.2: resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -20567,7 +20605,6 @@ packages: terser: optional: true dependencies: - '@types/node': 18.15.11 esbuild: 0.17.17 postcss: 8.4.21 rollup: 3.21.6 @@ -20575,6 +20612,72 @@ packages: fsevents: 2.3.2 dev: true + /vite@4.3.9(@types/node@18.15.11): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.15.11 + esbuild: 0.17.17 + postcss: 8.4.24 + rollup: 3.21.6 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite@4.3.9(@types/node@20.2.5): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.2.5 + esbuild: 0.17.17 + postcss: 8.4.24 + rollup: 3.21.6 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vitefu@0.2.4(vite@4.2.0): resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} peerDependencies: @@ -20594,7 +20697,7 @@ packages: vite: optional: true dependencies: - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.2 dev: true /vitest@0.25.8(jsdom@20.0.3): @@ -20633,7 +20736,7 @@ packages: tinybench: 2.4.0 tinypool: 0.3.1 tinyspy: 1.1.1 - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.9(@types/node@18.15.11) transitivePeerDependencies: - less - sass @@ -20696,7 +20799,7 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.5.0 - vite: 4.3.2(@types/node@18.15.11) + vite: 4.3.9(@types/node@18.15.11) vite-node: 0.31.4(@types/node@18.15.11) why-is-node-running: 2.2.2 transitivePeerDependencies: From 39086adb427972e347242ec52e2b4d104e2f1c00 Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Tue, 13 Jun 2023 23:18:46 +0200 Subject: [PATCH 28/68] downgrade msw version, revert httpService debug changes --- packages/nodejs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 28a3c249..d79e23c0 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -23,7 +23,7 @@ "@types/jest": "^29.5.1", "@types/node": "^20.2.5", "install": "^0.13.0", - "msw": "^1.2.1", + "msw": "^0.49.1", "node-fetch": "^3.3.1", "nodemon": "^2.0.22", "supertest": "^6.3.3", From 06340c99ac474ed250c4b580373cda786c6f085d Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Tue, 13 Jun 2023 23:19:07 +0200 Subject: [PATCH 29/68] downgrade msw version, revert httpService debug changes --- packages/core/src/shared/http.ts | 124 +++++++++++++++---------------- pnpm-lock.yaml | 79 +++++++++++--------- 2 files changed, 106 insertions(+), 97 deletions(-) diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index 7a840767..3fa0be3b 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,71 +1,69 @@ -import { ABBY_BASE_URL } from './constants'; -import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from './index'; +import { ABBY_BASE_URL } from "./constants"; +import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; -// // function fetchData(url: RequestInfo | URL, init?: RequestInit) { -// if (typeof window === 'undefined') { -// Running in Node.js -// const fetch = require('node-fetch'); -// return fetch(url); -// } else { -// Running in a browser -// return fetch(url); -// } +// if (typeof window === "undefined") { +// // Running in Node.js +// const fetch = require("node-fetch"); +// return fetch(url); +// } else { +// // Running in a browser +// return fetch(url); +// } // } export abstract class HttpService { - static async getProjectData({ - projectId, - environment, - url - }: { - projectId: string; - environment?: string; - url?: string; - }) { - try { - console.log( - `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ - environment ? `?environment=${environment}` : '' - }` - ); - const res = await fetch( - `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ - environment ? `?environment=${environment}` : '' - }` - ); + static async getProjectData({ + projectId, + environment, + url, + }: { + projectId: string; + environment?: string; + url?: string; + }) { + try { + const res = await fetch( + `${url ?? ABBY_BASE_URL}api/dashboard/${projectId}/data${ + environment ? `?environment=${environment}` : "" + }` + ); - if (!res.ok) return null; - const data = (await res.json()) as AbbyDataResponse; - return data; - } catch (err) { - console.error('[ABBY]: failed to load project data, falling back to defaults'); - console.log(err); - return null; - } - } + if (!res.ok) return null; + const data = (await res.json()) as AbbyDataResponse; + return data; + } catch (err) { + console.error( + "[ABBY]: failed to load project data, falling back to defaults" + ); + return null; + } + } - static sendData({ - url, - type, - data - }: { - url?: string; - type: AbbyEventType; - data: Omit; - }) { - if (typeof window === 'undefined' || window.location.hostname === 'localhost') { - // don't send data in development - return; - } - return fetch(`${url ?? ABBY_BASE_URL}api/data`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ type, ...data }) - // catch error and forget about them for now - // TODO: add error debugging - }).catch(() => {}); - } + static sendData({ + url, + type, + data, + }: { + url?: string; + type: AbbyEventType; + data: Omit; + }) { + if ( + typeof window === "undefined" || + window.location.hostname === "localhost" + ) { + // don't send data in development + return; + } + return fetch(`${url ?? ABBY_BASE_URL}api/data`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ type, ...data }), + // catch error and forget about them for now + // TODO: add error debugging + }).catch(() => {}); + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 581c4a6e..00431bc2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: version: 2.8.8 turbo: specifier: latest - version: 1.10.2 + version: 1.9.5 apps/angular-example: dependencies: @@ -678,7 +678,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.2(eslint@7.32.0) + version: 1.9.5(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -785,8 +785,8 @@ importers: specifier: ^0.13.0 version: 0.13.0 msw: - specifier: ^1.2.1 - version: 1.2.1(typescript@5.0.4) + specifier: ^0.49.1 + version: 0.49.3(typescript@5.0.4) node-fetch: specifier: ^3.3.1 version: 3.3.1 @@ -8744,6 +8744,7 @@ packages: /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} + hasBin: true /acorn@8.8.1: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} @@ -8752,6 +8753,7 @@ packages: /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} + hasBin: true /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} @@ -11173,6 +11175,7 @@ packages: /esbuild@0.15.18: resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.15.18 @@ -11377,13 +11380,13 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.10.2(eslint@7.32.0): - resolution: {integrity: sha512-BaCnpn2GM0rTFLuTVplqY8n+3ttWcu/vEmfjJ2BNBVmwX6ALZoJQfL26ZW6VucRk0psTUJALeo+aPrf3VKEJXA==} + /eslint-config-turbo@1.9.5(eslint@7.32.0): + resolution: {integrity: sha512-mV52KGcx65xQGckAqIC44kKA9Iv9B0QVHeFbl5ZoJ0SwyBJwug2bkdhnWh/KU/t3Wc3+5TpBHU8u2ygmB0nBbg==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.10.2(eslint@7.32.0) + eslint-plugin-turbo: 1.9.5(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -11670,8 +11673,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.10.2(eslint@7.32.0): - resolution: {integrity: sha512-Kxsy4zlKLrGkEqZgcAQtu16YqU/g0mV1vYa9/VweF+MSnWWQsEzsJ1qlzTfXV6N9VqGmkuLiyWOA84sRUklOOg==} + /eslint-plugin-turbo@1.9.5(eslint@7.32.0): + resolution: {integrity: sha512-fJW2uLWuv7J3tqJckjDKcApMNcqseV92kQoFMTZwSL5B1g8wJx0sAx9FcDpWgElFnqe2k63Iqz/DMZjdXI72aw==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -15814,13 +15817,13 @@ packages: - supports-color dev: true - /msw@1.2.1(typescript@5.0.4): - resolution: {integrity: sha512-bF7qWJQSmKn6bwGYVPXOxhexTCGD5oJSZg8yt8IBClxvo3Dx/1W0zqE1nX9BSWmzRsCKWfeGWcB/vpqV6aclpw==} + /msw@0.49.3(typescript@5.0.4): + resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} hasBin: true requiresBuild: true peerDependencies: - typescript: '>= 4.4.x <= 5.0.x' + typescript: '>= 4.4.x <= 4.9.x' peerDependenciesMeta: typescript: optional: true @@ -16158,6 +16161,7 @@ packages: /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + requiresBuild: true optional: true /node-dir@0.1.17: @@ -16209,6 +16213,7 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + requiresBuild: true optional: true /node-gyp@9.3.1: @@ -18096,6 +18101,7 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18103,6 +18109,7 @@ packages: /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18161,6 +18168,7 @@ packages: /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -18361,6 +18369,7 @@ packages: /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + hasBin: true dev: true /semver@7.3.8: @@ -19740,7 +19749,7 @@ packages: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 '@types/node': 20.2.5 - acorn: 8.8.2 + acorn: 8.8.1 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 @@ -19860,65 +19869,65 @@ packages: - supports-color dev: true - /turbo-darwin-64@1.10.2: - resolution: {integrity: sha512-sVLpVVANByfMgqf7OYPcZM4KiDnjGu7ITvAzBSa9Iwe14yoWLn8utrNsWCRaQEB6kEqBGLPmvL7AKwkl8M2Gqg==} + /turbo-darwin-64@1.9.5: + resolution: {integrity: sha512-rtVuXm4QH5oA+BU/Vv7mfu9y4ok2zmpqQJEnV3Fn+h+BNgFaPU5HOOEZNiBLVHvpefO9uUB7maU5IVc76w4VPA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.2: - resolution: {integrity: sha512-TKG91DSoYQjsCft4XBx4lYycVT5n3UQB/nOKgv/WJCSfwshLWulya3yhP8JT5erv9rPF8gwgnx87lrCmT4EAVA==} + /turbo-darwin-arm64@1.9.5: + resolution: {integrity: sha512-KH01n3GwpphOf3mx9pZoRBt0r9zZi0s5omDJorenN9hKDudTCLRhitbHyfCE9v/2x4hiX1zz8y/zET950YYCEw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.2: - resolution: {integrity: sha512-ZIzAkfrzjJFkSM/uEfxU6JjseCsT5PHRu0s0lmYce37ApQbv/HC7tI0cFhuosI30+O8109/mkyZykKE7AQfgqA==} + /turbo-linux-64@1.9.5: + resolution: {integrity: sha512-b1XXy/NReTe/sNiohCDcl8YTDe/WSnz+DPA9jPoBfKH4crF8QlIuPUDFHYFmBflAYdItD4htKxy+47ReCoES1w==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.2: - resolution: {integrity: sha512-G4uZA+RBQ5S1X/oUxO5KoLL2NDMkrrBZF52+00jQv6UEb9lWDgwzqSwoAGjdXxeDCrqMW5rBVwb/IBIF2/yhwA==} + /turbo-linux-arm64@1.9.5: + resolution: {integrity: sha512-0tlgIsjNChtyPlPCnB6k9oh2WCoO80D4nEj9zdU1D3xBL30qlsC1dAEOouGi0uK6Sh2GJLrEiRaeBh+/M9h68w==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.2: - resolution: {integrity: sha512-ObfQO37kGu1jBzFs/L+hybrCXBwdnimotJwzg7pCoSyGijKITlugrpJoPDKlg0eMr3/1Y6KUeHy26vZaDXrbuQ==} + /turbo-windows-64@1.9.5: + resolution: {integrity: sha512-HO8Bh4zoViQ3BE8TKG6XJGQyUnCR4ljejWj+soCCZnmgg0rYUgRPKVTDmLA/9wV58b4QWsaEOWN9sWApydDrkg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.2: - resolution: {integrity: sha512-7S6dx4738R/FIT2cxbsunqgHN5LelXzuzkcaZgdkU33oswRf/6KOfOABzQLdTX7Uos59cBSdwayf6KQJxuOXUg==} + /turbo-windows-arm64@1.9.5: + resolution: {integrity: sha512-XNpxXggn7JtqfLUHOj/hgLMwhTGEVVBix42N4gBMVOgo2GLA5AngTf0dt8ZGKkOFXA75zHn+iHA3sq+lrCRT/g==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.2: - resolution: {integrity: sha512-m9sR5XHhuzxUQACf0vI2qCG5OqDYAZiPTaAsTwECnwUF4/cXwEmcYddbLJnO+K9orNvcnjjent5oBNBVQ/o0ow==} + /turbo@1.9.5: + resolution: {integrity: sha512-ipfHCxx4/DOoEcdp8eItqfQ878NbCJrfAQ28EJdMUUS85sDbftn6XzGQULYdfJDp4q+Wwvu3m4tMNRjZSWZz5Q==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.2 - turbo-darwin-arm64: 1.10.2 - turbo-linux-64: 1.10.2 - turbo-linux-arm64: 1.10.2 - turbo-windows-64: 1.10.2 - turbo-windows-arm64: 1.10.2 + turbo-darwin-64: 1.9.5 + turbo-darwin-arm64: 1.9.5 + turbo-linux-64: 1.9.5 + turbo-linux-arm64: 1.9.5 + turbo-windows-64: 1.9.5 + turbo-windows-arm64: 1.9.5 dev: true /type-check@0.3.2: @@ -20451,6 +20460,7 @@ packages: /vite-node@0.31.4(@types/node@18.15.11): resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} engines: {node: '>=v14.18.0'} + hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 @@ -20540,7 +20550,7 @@ packages: optional: true dependencies: esbuild: 0.15.18 - postcss: 8.4.21 + postcss: 8.4.24 resolve: 1.22.1 rollup: 2.79.1 optionalDependencies: @@ -21246,6 +21256,7 @@ packages: /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} + hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 From 8e5d3c0659949412a20413988d837b32c1e666e2 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 12:30:05 +0200 Subject: [PATCH 30/68] add tests for getABTestValue , getFeatureFlagValue --- packages/nodejs/src/abby/createAbby.ts | 3 +- packages/nodejs/src/tests/abby.test.ts | 31 +++++++++++++++++---- packages/nodejs/src/tests/mocks/handlers.ts | 3 -- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 651b1dff..6d6dc401 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -24,11 +24,10 @@ export async function createAbby< const config = abbyConfig as unknown as ConfigType; /** - * @param req express request object * @param name Name of the test that the variant should be retrieved for * @returns Value of the currently selected variant */ - const getABTestValue = (req: Request, name: T) => { + const getABTestValue = (name: T) => { const value = abby.getTestVariant(name); return value; }; diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index 51eeda5b..110f73d5 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -9,18 +9,39 @@ describe('it works', () => { flags: ['flag1', 'flag2'] }); - console.log(await getFeatureFlagValue('flag1')); - expect(await getFeatureFlagValue('flag1')).toBeTruthy(); expect(await getFeatureFlagValue('flag2')).toBeFalsy(); }); - test.skip('getABTestValue working', async () => { - const { getABTestValue, getFeatureFlagValue } = await createAbby({ + test('it returns a correct variant', async () => { + const variants = ['A', 'B', 'C', 'D']; + const { getABTestValue } = await createAbby({ projectId: '123', tests: { - 'New Test1': {} + test: { + variants + } } }); + + const variant = getABTestValue('test'); + + expect(variant).toContain(variant); + }); + + test('it returns a correct variant with respect to the weights', async () => { + const variants = ['A', 'B']; + const { getABTestValue } = await createAbby({ + projectId: '123', + tests: { + test: { + variants + } + } + }); + + const variant = getABTestValue('test'); + + expect(variant).toBe('A'); }); }); diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts index 1e80961a..d6990da7 100644 --- a/packages/nodejs/src/tests/mocks/handlers.ts +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -1,11 +1,8 @@ import { rest } from 'msw'; import { type AbbyDataResponse, ABBY_BASE_URL } from '@tryabby/core'; -console.log('call m ock'); - export const handlers = [ rest.get(`${ABBY_BASE_URL}api/dashboard/123/data`, (req, res, ctx) => { - console.log('call mock'); return res( ctx.json({ tests: [ From 3b4f24a946762c552b52cefd46ac98704db7af22 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:35:10 +0200 Subject: [PATCH 31/68] add abbyExpressMiddleWareFactory --- packages/nodejs/package.json | 9 ++- packages/nodejs/src/express/abbyMiddleware.ts | 35 --------- .../src/express/abbyMiddlewareFactory.ts | 72 +++++++++++++++++++ pnpm-lock.yaml | 54 +++++++------- 4 files changed, 103 insertions(+), 67 deletions(-) delete mode 100644 packages/nodejs/src/express/abbyMiddleware.ts create mode 100644 packages/nodejs/src/express/abbyMiddlewareFactory.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index d79e23c0..7fa138f7 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -14,9 +14,8 @@ "license": "ISC", "dependencies": { "@tryabby/core": "workspace:^", - "@types/supertest": "^2.0.12", - "axios": "^1.4.0", - "express": "^4.18.2" + "express": "^4.18.2", + "ts-toolbelt": "^9.6.0" }, "devDependencies": { "@types/express": "^4.17.17", @@ -28,9 +27,9 @@ "nodemon": "^2.0.22", "supertest": "^6.3.3", "ts-node": "^10.9.1", - "ts-toolbelt": "^9.6.0", "typescript": "^5.0.4", "vite": "^4.3.9", - "vitest": "^0.31.4" + "vitest": "^0.31.4", + "@types/supertest": "^2.0.12" } } \ No newline at end of file diff --git a/packages/nodejs/src/express/abbyMiddleware.ts b/packages/nodejs/src/express/abbyMiddleware.ts deleted file mode 100644 index a9450878..00000000 --- a/packages/nodejs/src/express/abbyMiddleware.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable react-hooks/rules-of-hooks */ -//TODO fix eslint -import { getFeatureFlagValue, getABTestValue } from '../abby/abby.ts'; -import { type ConfigType } from '../abby/createAbby.ts'; -import { NextFunction, Request, Response } from 'express'; -import { setRequest } from '../abby/contexts/requestContext.ts'; -import { setResponse } from '../abby/contexts/responseContext.ts'; - -//TODO make types narrow like in createAbby -//TODO make abby import configurable - -export const featureFlagMiddleware = async ( - req: Request, - res: Response, - name: string, - next: NextFunction -) => { - console.log('middleware'); - //Todo fix types - const flagValue = true; //getFeatureFlagValue('lol'); //type? - console.log('hi from middleware', name, flagValue); - if (!flagValue) { - res.sendStatus(403); - return; - } - next(); -}; - -export const AbTestMiddleware = (req: Request, res: Response, name: string, next: NextFunction) => { - setRequest(req); - setResponse(res); - const value = getABTestValue(req, name as any); - console.log(value); - next(); -}; diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts new file mode 100644 index 00000000..18f52d05 --- /dev/null +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -0,0 +1,72 @@ +import { NextFunction, Request, Response } from 'express'; +import { setRequest } from '../abby/contexts/requestContext.ts'; +import { setResponse } from '../abby/contexts/responseContext.ts'; +import { AbbyConfig, ABConfig } from '@tryabby/core'; +import { createAbby } from '../abby/createAbby.ts'; +import { F } from 'ts-toolbelt'; + +type abbyMiddlewareConfig = {}; + +export const abbyMiddlewareFactory = async < + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig +>({ + abbyConfig, + config: abbyMiddlewarreConfig +}: { + abbyConfig: F.Narrow>; + config?: abbyMiddlewareConfig; +}) => { + const config = abbyConfig as unknown as ConfigType; + const abby = await createAbby(abbyConfig); + + const featureFlagMiddleware = [number]>( + name: F, + req: Request, + res: Response, + next: NextFunction + ) => { + const flagValue = abby.getFeatureFlagValue(name); + if (!flagValue) { + res.sendStatus(403); + return; + } + next(); + }; + + const AbTestMiddleware = ( + name: T, + req: Request, + res: Response, + next: NextFunction + ) => { + setRequest(req); + setResponse(res); + const value = abby.getABTestValue(name); + next(); + }; + + return { featureFlagMiddleware, AbTestMiddleware }; +}; + +const x = await abbyMiddlewareFactory({ + abbyConfig: { + projectId: 'clfn3hs1t0002kx08x3kidi80', + currentEnvironment: process.env.NODE_ENV, + tests: { + 'New Test3': { + variants: ['A', 'B'] + } + }, + flags: ['lol', 'test3', 'testAbby'], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1 + } + }, + config: {} +}); + +x.AbTestMiddleware(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00431bc2..97b5a2f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: version: 2.8.8 turbo: specifier: latest - version: 1.9.5 + version: 1.10.2 apps/angular-example: dependencies: @@ -678,7 +678,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.9.5(eslint@7.32.0) + version: 1.10.2(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -11380,13 +11380,13 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.9.5(eslint@7.32.0): - resolution: {integrity: sha512-mV52KGcx65xQGckAqIC44kKA9Iv9B0QVHeFbl5ZoJ0SwyBJwug2bkdhnWh/KU/t3Wc3+5TpBHU8u2ygmB0nBbg==} + /eslint-config-turbo@1.10.2(eslint@7.32.0): + resolution: {integrity: sha512-BaCnpn2GM0rTFLuTVplqY8n+3ttWcu/vEmfjJ2BNBVmwX6ALZoJQfL26ZW6VucRk0psTUJALeo+aPrf3VKEJXA==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.9.5(eslint@7.32.0) + eslint-plugin-turbo: 1.10.2(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -11673,8 +11673,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.9.5(eslint@7.32.0): - resolution: {integrity: sha512-fJW2uLWuv7J3tqJckjDKcApMNcqseV92kQoFMTZwSL5B1g8wJx0sAx9FcDpWgElFnqe2k63Iqz/DMZjdXI72aw==} + /eslint-plugin-turbo@1.10.2(eslint@7.32.0): + resolution: {integrity: sha512-Kxsy4zlKLrGkEqZgcAQtu16YqU/g0mV1vYa9/VweF+MSnWWQsEzsJ1qlzTfXV6N9VqGmkuLiyWOA84sRUklOOg==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -19869,65 +19869,65 @@ packages: - supports-color dev: true - /turbo-darwin-64@1.9.5: - resolution: {integrity: sha512-rtVuXm4QH5oA+BU/Vv7mfu9y4ok2zmpqQJEnV3Fn+h+BNgFaPU5HOOEZNiBLVHvpefO9uUB7maU5IVc76w4VPA==} + /turbo-darwin-64@1.10.2: + resolution: {integrity: sha512-sVLpVVANByfMgqf7OYPcZM4KiDnjGu7ITvAzBSa9Iwe14yoWLn8utrNsWCRaQEB6kEqBGLPmvL7AKwkl8M2Gqg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.9.5: - resolution: {integrity: sha512-KH01n3GwpphOf3mx9pZoRBt0r9zZi0s5omDJorenN9hKDudTCLRhitbHyfCE9v/2x4hiX1zz8y/zET950YYCEw==} + /turbo-darwin-arm64@1.10.2: + resolution: {integrity: sha512-TKG91DSoYQjsCft4XBx4lYycVT5n3UQB/nOKgv/WJCSfwshLWulya3yhP8JT5erv9rPF8gwgnx87lrCmT4EAVA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.9.5: - resolution: {integrity: sha512-b1XXy/NReTe/sNiohCDcl8YTDe/WSnz+DPA9jPoBfKH4crF8QlIuPUDFHYFmBflAYdItD4htKxy+47ReCoES1w==} + /turbo-linux-64@1.10.2: + resolution: {integrity: sha512-ZIzAkfrzjJFkSM/uEfxU6JjseCsT5PHRu0s0lmYce37ApQbv/HC7tI0cFhuosI30+O8109/mkyZykKE7AQfgqA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.9.5: - resolution: {integrity: sha512-0tlgIsjNChtyPlPCnB6k9oh2WCoO80D4nEj9zdU1D3xBL30qlsC1dAEOouGi0uK6Sh2GJLrEiRaeBh+/M9h68w==} + /turbo-linux-arm64@1.10.2: + resolution: {integrity: sha512-G4uZA+RBQ5S1X/oUxO5KoLL2NDMkrrBZF52+00jQv6UEb9lWDgwzqSwoAGjdXxeDCrqMW5rBVwb/IBIF2/yhwA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.9.5: - resolution: {integrity: sha512-HO8Bh4zoViQ3BE8TKG6XJGQyUnCR4ljejWj+soCCZnmgg0rYUgRPKVTDmLA/9wV58b4QWsaEOWN9sWApydDrkg==} + /turbo-windows-64@1.10.2: + resolution: {integrity: sha512-ObfQO37kGu1jBzFs/L+hybrCXBwdnimotJwzg7pCoSyGijKITlugrpJoPDKlg0eMr3/1Y6KUeHy26vZaDXrbuQ==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.9.5: - resolution: {integrity: sha512-XNpxXggn7JtqfLUHOj/hgLMwhTGEVVBix42N4gBMVOgo2GLA5AngTf0dt8ZGKkOFXA75zHn+iHA3sq+lrCRT/g==} + /turbo-windows-arm64@1.10.2: + resolution: {integrity: sha512-7S6dx4738R/FIT2cxbsunqgHN5LelXzuzkcaZgdkU33oswRf/6KOfOABzQLdTX7Uos59cBSdwayf6KQJxuOXUg==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.9.5: - resolution: {integrity: sha512-ipfHCxx4/DOoEcdp8eItqfQ878NbCJrfAQ28EJdMUUS85sDbftn6XzGQULYdfJDp4q+Wwvu3m4tMNRjZSWZz5Q==} + /turbo@1.10.2: + resolution: {integrity: sha512-m9sR5XHhuzxUQACf0vI2qCG5OqDYAZiPTaAsTwECnwUF4/cXwEmcYddbLJnO+K9orNvcnjjent5oBNBVQ/o0ow==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.9.5 - turbo-darwin-arm64: 1.9.5 - turbo-linux-64: 1.9.5 - turbo-linux-arm64: 1.9.5 - turbo-windows-64: 1.9.5 - turbo-windows-arm64: 1.9.5 + turbo-darwin-64: 1.10.2 + turbo-darwin-arm64: 1.10.2 + turbo-linux-64: 1.10.2 + turbo-linux-arm64: 1.10.2 + turbo-windows-64: 1.10.2 + turbo-windows-arm64: 1.10.2 dev: true /type-check@0.3.2: From 6f15e9be6c94fcce10caba0dfcd2267d4c4ac128 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:36:04 +0200 Subject: [PATCH 32/68] fix tests --- packages/nodejs/src/abby/abby.ts | 28 ++++++++++--------- packages/nodejs/src/index.ts | 10 +++---- packages/nodejs/src/tests/abby.test.ts | 4 +-- ...byExpress.test2.ts => abbyExpress.test.ts} | 6 ++-- packages/nodejs/src/tests/mocks/handlers.ts | 27 ++++++++++++++++++ 5 files changed, 52 insertions(+), 23 deletions(-) rename packages/nodejs/src/tests/{abbyExpress.test2.ts => abbyExpress.test.ts} (86%) diff --git a/packages/nodejs/src/abby/abby.ts b/packages/nodejs/src/abby/abby.ts index 0a168155..d5d33eba 100644 --- a/packages/nodejs/src/abby/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -1,16 +1,18 @@ -import { createAbby } from "./createAbby.ts"; +import { createAbby } from './createAbby.ts'; export const { getFeatureFlagValue, getABTestValue } = await createAbby({ - projectId: "clfn3hs1t0002kx08x3kidi80", - currentEnvironment: process.env.NODE_ENV, - tests: { - "New Test3": { - variants: ["A", "B"], - }, - }, - flags: ["lol", "test3", "testAbby"], - flagCacheConfig: { - refetchFlags: true, - timeToLive: 1 - } + projectId: 'clfn3hs1t0002kx08x3kidi80', + currentEnvironment: process.env.NODE_ENV, + tests: { + 'New Test3': { + variants: ['A', 'B'] + } + }, + flags: ['lol', 'test3', 'testAbby'], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1 + } }); + +export const abby = { getFeatureFlagValue, getABTestValue }; diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index a3600001..4bd03e14 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,14 +1,14 @@ -import express from "express" -import { featureFlagMiddleware, AbTestMiddleware } from "./express/abbyMiddleware.ts"; +import express from 'express'; +import { featureFlagMiddleware, AbTestMiddleware } from './express/abbyMiddlewareFactory.ts'; const app = express(); const port = 3000; -app.use("/", (req, res, next) => AbTestMiddleware(req, res, "New Test3", next)) +app.use('/', (req, res, next) => AbTestMiddleware(req, res, 'New Test3', next)); // app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) app.get('/', async (req, res) => { - res.send("very nice content that needs to be protected") + res.send('very nice content that needs to be protected'); }); -app.listen(port, () => console.log(`Express app running on port ${port}!`)); \ No newline at end of file +app.listen(port, () => console.log(`Express app running on port ${port}!`)); diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index 110f73d5..5eed0df9 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -34,13 +34,13 @@ describe('it works', () => { const { getABTestValue } = await createAbby({ projectId: '123', tests: { - test: { + test2: { variants } } }); - const variant = getABTestValue('test'); + const variant = getABTestValue('test2'); expect(variant).toBe('A'); }); diff --git a/packages/nodejs/src/tests/abbyExpress.test2.ts b/packages/nodejs/src/tests/abbyExpress.test.ts similarity index 86% rename from packages/nodejs/src/tests/abbyExpress.test2.ts rename to packages/nodejs/src/tests/abbyExpress.test.ts index 18864fee..79f1f74c 100644 --- a/packages/nodejs/src/tests/abbyExpress.test2.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,7 +1,7 @@ import { expect, test, describe, beforeEach } from 'vitest'; import { createAbby } from '../abby/createAbby.ts'; import express, { response } from 'express'; -import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddleware.ts'; +import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddlewareFactory.ts'; import request from 'supertest'; describe.skip('express middleware working', () => { @@ -15,7 +15,7 @@ describe.skip('express middleware working', () => { test('abTestMiddleware working', async () => { const result = true; //test cookie retrieval - app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); + // app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); app.get('/', (req, res) => { res.status(200); res.send('hi'); @@ -27,7 +27,7 @@ describe.skip('express middleware working', () => { expect(result).toBeFalsy(); }); - test('featureFlag Middleware working', async () => { + test.skip('featureFlag Middleware working', async () => { const result = true; app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); app.get('/', (req, res) => { diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts index d6990da7..4bd16651 100644 --- a/packages/nodejs/src/tests/mocks/handlers.ts +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -27,5 +27,32 @@ export const handlers = [ ] } as AbbyDataResponse) ); + }), + + rest.get(`${ABBY_BASE_URL}api/dashboard/clfn3hs1t0002kx08x3kidi80/data`, (req, res, ctx) => { + return res( + ctx.json({ + tests: [ + { + name: 'test', + weights: [1, 1, 1, 1] + }, + { + name: 'test2', + weights: [1, 0] + } + ], + flags: [ + { + name: 'lol', + isEnabled: true + }, + { + name: 'test3', + isEnabled: false + } + ] + } as AbbyDataResponse) + ); }) ]; From ec228f5e0579e14ae24d865ac6917a33f4471b74 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:39:10 +0200 Subject: [PATCH 33/68] fix lockfile --- pnpm-lock.yaml | 80 +++++++------------------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97b5a2f1..88699c0f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -762,15 +762,12 @@ importers: '@tryabby/core': specifier: workspace:^ version: link:../core - '@types/supertest': - specifier: ^2.0.12 - version: 2.0.12 - axios: - specifier: ^1.4.0 - version: 1.4.0 express: specifier: ^4.18.2 version: 4.18.2 + ts-toolbelt: + specifier: ^9.6.0 + version: 9.6.0 devDependencies: '@types/express': specifier: ^4.17.17 @@ -781,6 +778,9 @@ importers: '@types/node': specifier: ^20.2.5 version: 20.2.5 + '@types/supertest': + specifier: ^2.0.12 + version: 2.0.12 install: specifier: ^0.13.0 version: 0.13.0 @@ -799,9 +799,6 @@ importers: ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) - ts-toolbelt: - specifier: ^9.6.0 - version: 9.6.0 typescript: specifier: ^5.0.4 version: 5.0.4 @@ -1383,7 +1380,6 @@ packages: /@angular/compiler-cli@15.2.0(@angular/compiler@15.2.0)(typescript@4.9.5): resolution: {integrity: sha512-ETnRBdY/LGcmDRQ9GQc9KyCd1kuRnj+Y9luq2dCTMysP+NgylmYoGDsJOsDKm6SzPo+B4PSAyHX2J4CVQFHpPg==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler': 15.2.0 typescript: '>=4.8.2 <5.0' @@ -7126,7 +7122,6 @@ packages: /@sveltejs/kit@1.15.8(svelte@3.58.0)(vite@4.3.2): resolution: {integrity: sha512-xPIF3UbFEA5BBZWFTGGUtSZ0O3DAtmzIp/yZZVdLIfzZ9+geKG3iGSVFnOUdYstjU7JcvJg12UC5MD5xoED59A==} engines: {node: ^16.14 || >=18} - hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 @@ -7154,7 +7149,6 @@ packages: /@sveltejs/package@2.0.2(svelte@3.58.0)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} - hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -7840,7 +7834,7 @@ packages: /@types/cookiejar@2.1.2: resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} - dev: false + dev: true /@types/cors@2.8.13: resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} @@ -8189,13 +8183,13 @@ packages: dependencies: '@types/cookiejar': 2.1.2 '@types/node': 18.15.11 - dev: false + dev: true /@types/supertest@2.0.12: resolution: {integrity: sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==} dependencies: '@types/superagent': 4.1.18 - dev: false + dev: true /@types/testing-library__jest-dom@5.14.5: resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} @@ -8744,7 +8738,6 @@ packages: /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} - hasBin: true /acorn@8.8.1: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} @@ -8753,7 +8746,6 @@ packages: /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} - hasBin: true /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} @@ -9101,7 +9093,6 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -9116,7 +9107,6 @@ packages: /autoprefixer@10.4.14(postcss@8.4.21): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -9146,16 +9136,6 @@ packages: - debug dev: false - /axios@1.4.0: - resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} - dependencies: - follow-redirects: 1.15.2(debug@4.3.2) - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - /axobject-query@2.2.0: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} @@ -11175,7 +11155,6 @@ packages: /esbuild@0.15.18: resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.15.18 @@ -11205,7 +11184,6 @@ packages: /esbuild@0.17.17: resolution: {integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.17 @@ -11373,7 +11351,6 @@ packages: /eslint-config-prettier@8.5.0(eslint@7.32.0): resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -14062,7 +14039,6 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.4): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15516,24 +15492,20 @@ packages: /mime@1.4.1: resolution: {integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==} - hasBin: true dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} - hasBin: true /mime@2.5.2: resolution: {integrity: sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==} engines: {node: '>=4.0.0'} - hasBin: true dev: true /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} - hasBin: true /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} @@ -15748,7 +15720,6 @@ packages: /msw@0.49.1(typescript@4.9.3): resolution: {integrity: sha512-JpIIq4P65ofj0HVmDMkJuRwgP9s5kcdutpZ15evMTb2k91/USB7IKWRLV9J1Mzc3OqTdwNj4RwtOWJ5y/FulQQ==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15784,7 +15755,6 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15820,7 +15790,6 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15876,7 +15845,6 @@ packages: /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -15962,7 +15930,6 @@ packages: /next-sitemap@3.1.55(@next/env@13.3.4)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -15988,7 +15955,6 @@ packages: /next@13.3.4(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -16100,7 +16066,6 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.0)(tslib@2.5.0)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -16161,7 +16126,6 @@ packages: /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - requiresBuild: true optional: true /node-dir@0.1.17: @@ -16213,7 +16177,6 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} - requiresBuild: true optional: true /node-gyp@9.3.1: @@ -17480,6 +17443,7 @@ packages: /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} @@ -18101,7 +18065,6 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18109,7 +18072,6 @@ packages: /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} - hasBin: true dependencies: is-core-module: 2.11.0 path-parse: 1.0.7 @@ -18168,7 +18130,6 @@ packages: /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} - hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -18176,7 +18137,6 @@ packages: /rollup@3.21.6: resolution: {integrity: sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -18365,17 +18325,14 @@ packages: /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} - hasBin: true dev: true /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} - hasBin: true dependencies: lru-cache: 6.0.0 @@ -19171,7 +19128,6 @@ packages: /svelte-check@2.10.3(@babel/core@7.21.4)(svelte@3.55.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} - hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -19345,7 +19301,6 @@ packages: /tailwindcss@3.3.1(postcss@8.4.21)(ts-node@10.9.1): resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} engines: {node: '>=12.13.0'} - hasBin: true peerDependencies: postcss: ^8.0.9 dependencies: @@ -19701,7 +19656,6 @@ packages: /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19731,7 +19685,6 @@ packages: /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19793,7 +19746,6 @@ packages: /tsup@6.5.0(typescript@4.9.3): resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} engines: {node: '>=14'} - hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -20272,7 +20224,6 @@ packages: /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -20460,7 +20411,6 @@ packages: /vite-node@0.31.4(@types/node@18.15.11): resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} engines: {node: '>=v14.18.0'} - hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 @@ -20527,7 +20477,6 @@ packages: /vite@3.2.5: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20560,7 +20509,6 @@ packages: /vite@4.2.0: resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20593,7 +20541,6 @@ packages: /vite@4.3.2: resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20625,7 +20572,6 @@ packages: /vite@4.3.9(@types/node@18.15.11): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20658,7 +20604,6 @@ packages: /vite@4.3.9(@types/node@20.2.5): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20713,7 +20658,6 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20759,7 +20703,6 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20971,7 +20914,6 @@ packages: /webpack-dev-server@4.11.1(webpack@5.75.0): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} - hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -21046,7 +20988,6 @@ packages: /webpack@5.75.0(esbuild@0.17.8): resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} engines: {node: '>=10.13.0'} - hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -21256,7 +21197,6 @@ packages: /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} - hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 From 69ae44608eca502ec6666d68f42deaf565321937 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:11:46 +0200 Subject: [PATCH 34/68] fix build --- packages/nodejs/src/tests/abbyExpress.test.ts | 48 ++-- packages/svelte/src/lib/createAbby.ts | 266 +++++++++--------- 2 files changed, 155 insertions(+), 159 deletions(-) diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 79f1f74c..228431da 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,44 +1,46 @@ import { expect, test, describe, beforeEach } from 'vitest'; -import { createAbby } from '../abby/createAbby.ts'; import express, { response } from 'express'; -import { AbTestMiddleware, featureFlagMiddleware } from '../express/abbyMiddlewareFactory.ts'; import request from 'supertest'; +import { abbyMiddlewareFactory } from '../express/abbyMiddlewareFactory.ts'; -describe.skip('express middleware working', () => { +describe('express middleware working', () => { let app: express.Application; - beforeEach(() => { + beforeEach(async () => { + const { AbTestMiddleware, featureFlagMiddleware } = await abbyMiddlewareFactory({ + abbyConfig: { + projectId: 'clfn3hs1t0002kx08x3kidi80', + currentEnvironment: process.env.NODE_ENV, + tests: { + 'New Test3': { + variants: ['A', 'B'] + } + }, + flags: ['lol', 'test3', 'testAbby'], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1 + } + } + }); app = express(); // Add any other middlewares or routes necessary for your test + app.use('/featureflagTest', (req, res, next) => featureFlagMiddleware('test2', req, res, next)); + app.get('/', (req, res) => { + res.send('hiadsa'); + }); }); test('abTestMiddleware working', async () => { - const result = true; //test cookie retrieval - // app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); - app.get('/', (req, res) => { - res.status(200); - res.send('hi'); - }); const res = await request(app).get('/'); - console.log(res.statusCode); + + console.log(res.text); //check if cookie is set - expect(result).toBeFalsy(); }); test.skip('featureFlag Middleware working', async () => { - const result = true; - app.use('/', (req, res, next) => AbTestMiddleware(req, res, '', next)); - app.get('/', (req, res) => { - res.status(200); - res.send('hi'); - }); - - const res = await request(app).get('/'); - console.log(res.statusCode); - - expect(result).toBeFalsy(); //check if feature flag value is respected }); }); diff --git a/packages/svelte/src/lib/createAbby.ts b/packages/svelte/src/lib/createAbby.ts index 237a5073..7c00f27b 100644 --- a/packages/svelte/src/lib/createAbby.ts +++ b/packages/svelte/src/lib/createAbby.ts @@ -1,153 +1,147 @@ -import { Abby, type AbbyConfig, type ABConfig } from "@tryabby/core"; -import { HttpService, AbbyEventType } from "@tryabby/core"; -import { derived } from "svelte/store"; -import type { F } from "ts-toolbelt"; -import { FlagStorageService, TestStorageService } from "./StorageService"; -import AbbyProvider from "./AbbyProvider.svelte"; -import AbbyDevtools from "./AbbyDevtools.svelte"; +import { Abby, type AbbyConfig, type ABConfig } from '@tryabby/core'; +import { HttpService, AbbyEventType } from '@tryabby/core'; +import { derived } from 'svelte/store'; +import type { F } from 'ts-toolbelt'; +import { FlagStorageService, TestStorageService } from './StorageService'; +import AbbyProvider from './AbbyProvider.svelte'; +import AbbyDevtools from './AbbyDevtools.svelte'; export function createAbby< - FlagName extends string, - TestName extends string, - Tests extends Record, - ConfigType extends AbbyConfig = AbbyConfig + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig >(config: F.Narrow>) { - const abby = new Abby( - config, - { - get: (key: string) => { - if (typeof window === "undefined") return null; - return TestStorageService.get(config.projectId, key); - }, - set: (key: string, value: any) => { - if (typeof window === "undefined") return; - TestStorageService.set(config.projectId, key, value); - }, - }, - { - get: (key: string) => { - if (typeof window === "undefined") return null; - return FlagStorageService.get(config.projectId, key); - }, - set: (key: string, value: any) => { - if (typeof window === "undefined") return; - FlagStorageService.set(config.projectId, key, value); - }, - } - ); + const abby = new Abby( + config, + { + get: (key: string) => { + if (typeof window === 'undefined') return null; + return TestStorageService.get(config.projectId, key); + }, + set: (key: string, value: any) => { + if (typeof window === 'undefined') return; + TestStorageService.set(config.projectId, key, value); + } + }, + { + get: (key: string) => { + if (typeof window === 'undefined') return null; + return FlagStorageService.get(config.projectId, key); + }, + set: (key: string, value: any) => { + if (typeof window === 'undefined') return; + FlagStorageService.set(config.projectId, key, value); + } + } + ); - const abbyStore = derived(abby, ($v) => { - return abby; - }); + const abbyStore = derived(abby, ($v) => { + return abby; + }); - const abbyConfig = config as unknown as ConfigType; + const abbyConfig = config as unknown as ConfigType; + const notify = (name: N, selectedVariant: string) => { + if (!name || !selectedVariant) return; + HttpService.sendData({ + url: config.apiUrl, + type: AbbyEventType.PING, + data: { + projectId: config.projectId, + selectedVariant, + testName: name as string + } + }); + }; - const notify = (name: N, selectedVariant: string) => { - if (!name || !selectedVariant) return; - HttpService.sendData({ - url: config.apiUrl, - type: AbbyEventType.PING, - data: { - projectId: config.projectId, - selectedVariant, - testName: name as string, - }, - }); - }; + const useAbby = (testName: K) => { + const variant = derived(abby, ($v) => { + return abby.getTestVariant(testName); + }); + let selectedVariant: string = ''; + variant.subscribe((data) => { + selectedVariant = data; + }); + const onAct = () => { + HttpService.sendData({ + url: config.apiUrl, + type: AbbyEventType.ACT, + data: { + projectId: config.projectId, + selectedVariant, + testName: testName as string + } + }); + }; + notify(testName, selectedVariant); + return { variant, onAct }; + }; - const useAbby = (testName: K) => { - const variant = derived(abby, ($v) => { - return abby.getTestVariant(testName); - }); - let selectedVariant: string = ""; - variant.subscribe((data) => { - selectedVariant = data; - }); - const onAct = () => { - HttpService.sendData({ - url: config.apiUrl, - type: AbbyEventType.ACT, - data: { - projectId: config.projectId, - selectedVariant, - testName: testName as string, - }, - }); - }; - notify(testName, selectedVariant); - return { variant, onAct }; - }; + const getVariants = (testName: T) => { + return derived>(abby, ($v) => { + return abby.getVariants(testName); + }); + }; - const getVariants = (testName: T) => { - return derived>(abby, ($v) => { - return abby.getVariants(testName); - }); - }; + /** + * helper function to reset an Ab Test + */ + const getABResetFunction = (testName: T) => { + return () => { + TestStorageService.remove(config.projectId, testName as string); + }; + }; - /** - * helper function to reset an Ab Test - */ - const getABResetFunction = (testName: T) => { - return () => { - TestStorageService.remove(config.projectId, testName as string); - }; - }; + const getABTestValue = (testName: T) => { + return abby.getTestVariant(testName); + }; - const getABTestValue = (testName: T) => { - return abby.getTestVariant(testName); - }; + const getFeatureFlagValue = [number]>( + featureFlagName: F + ) => { + return abby.getFeatureFlag(featureFlagName); + }; - const getFeatureFlagValue = < - F extends NonNullable[number] - >( - featureFlagName: F - ) => { - return abby.getFeatureFlag(featureFlagName); - }; + const useFeatureFlag = [number]>(flagName: F) => { + return derived(abby, ($v) => { + return abby.getFeatureFlag(flagName); + }); + }; - const useFeatureFlag = [number]>( - flagName: F - ) => { - return derived(abby, ($v) => { - return abby.getFeatureFlag(flagName); - }); - }; + const withAbby = (handler?: any) => { + //TODO fix type import + return async (evt: any) => { + const data = await handler?.(evt); + const __abby__data = await HttpService.getProjectData({ + url: config.apiUrl, + projectId: config.projectId, + environment: config.currentEnvironment + }); - const withAbby = (handler?: ) => { - //TODO fix type import - return async (evt: any) => { - const data = await handler?.(evt); - const __abby__data = await HttpService.getProjectData({ - url: config.apiUrl, - projectId: config.projectId, - environment: config.currentEnvironment, - }); + return { + ...data, + __abby__data, + __abby_cookie: evt?.request.headers.get('cookie') + }; + }; + }; - return { - ...data, - __abby__data, - __abby_cookie: evt?.request.headers.get("cookie"), - }; - }; - }; + const withDevTools = () => { + return AbbyDevtools; + }; - const withDevTools = () => { - return AbbyDevtools; - }; - - return { - useAbby, - useFeatureFlag, - getFeatureFlagValue, - getABTestValue, - __abby__: abby, - getABResetFunction, - getVariants, - abbyStore, - withAbby, - AbbyProvider, - withDevTools, - }; - export type {ConfigType}; + return { + useAbby, + useFeatureFlag, + getFeatureFlagValue, + getABTestValue, + __abby__: abby, + getABResetFunction, + getVariants, + abbyStore, + withAbby, + AbbyProvider, + withDevTools + }; } From d9dd7784263213c84eee15295258a6f12430b2fa Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 21:49:55 +0200 Subject: [PATCH 35/68] add express test middleware setting cookie --- packages/nodejs/src/abby/createAbby.ts | 76 +++++++------ .../src/express/abbyMiddlewareFactory.ts | 104 ++++++++---------- packages/nodejs/src/tests/abbyExpress.test.ts | 89 ++++++++------- 3 files changed, 133 insertions(+), 136 deletions(-) diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 6d6dc401..d929681c 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,44 +1,48 @@ -import { ABConfig, Abby, AbbyConfig } from '@tryabby/core'; -import { F } from 'ts-toolbelt'; -import { Request } from 'express'; -import { TestStorageService } from './StorageService.ts'; +import { ABConfig, Abby, AbbyConfig } from "@tryabby/core"; +import { F } from "ts-toolbelt"; +import { Request } from "express"; +import { TestStorageService } from "./StorageService.ts"; export async function createAbby< - FlagName extends string, - TestName extends string, - Tests extends Record, - ConfigType extends AbbyConfig = AbbyConfig + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig >(abbyConfig: F.Narrow>) { - const abby = new Abby(abbyConfig, { - get: (key: string) => { - return TestStorageService.get(abbyConfig.projectId, key); - }, - set: (key: string, value: any) => { - TestStorageService.set(abbyConfig.projectId, key, value); - } - }); + const abby = new Abby(abbyConfig, { + get: (key: string) => { + return TestStorageService.get(abbyConfig.projectId, key); + }, + set: (key: string, value: any) => { + TestStorageService.set(abbyConfig.projectId, key, value); + }, + }); - //load data and initialise the abby Object - await abby.loadProjectData(); + //load data and initialise the abby Object + await abby.loadProjectData(); - const config = abbyConfig as unknown as ConfigType; + const config = abbyConfig as unknown as ConfigType; - /** - * @param name Name of the test that the variant should be retrieved for - * @returns Value of the currently selected variant - */ - const getABTestValue = (name: T) => { - const value = abby.getTestVariant(name); - return value; - }; - /** - * - * @param name Name of the feature flag - * @returns Value of the feature flag - */ - const getFeatureFlagValue = [number]>(name: F) => { - return abby.getFeatureFlag(name); - }; + /** + * @param name Name of the test that the variant should be retrieved for + * @returns Value of the currently selected variant + */ + const getABTestValue = (name: T) => { + const value = abby.getTestVariant(name); + return value; + }; + /** + * + * @param name Name of the feature flag + * @returns Value of the feature flag + */ + const getFeatureFlagValue = < + F extends NonNullable[number] + >( + name: F + ) => { + return abby.getFeatureFlag(name); + }; - return { getFeatureFlagValue, getABTestValue }; + return { getFeatureFlagValue, getABTestValue }; } diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index 18f52d05..a7a6c58a 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -1,72 +1,54 @@ -import { NextFunction, Request, Response } from 'express'; -import { setRequest } from '../abby/contexts/requestContext.ts'; -import { setResponse } from '../abby/contexts/responseContext.ts'; -import { AbbyConfig, ABConfig } from '@tryabby/core'; -import { createAbby } from '../abby/createAbby.ts'; -import { F } from 'ts-toolbelt'; +import { NextFunction, Request, Response } from "express"; +import { setRequest } from "../abby/contexts/requestContext.ts"; +import { setResponse } from "../abby/contexts/responseContext.ts"; +import { AbbyConfig, ABConfig } from "@tryabby/core"; +import { createAbby } from "../abby/createAbby.ts"; +import { F } from "ts-toolbelt"; type abbyMiddlewareConfig = {}; export const abbyMiddlewareFactory = async < - FlagName extends string, - TestName extends string, - Tests extends Record, - ConfigType extends AbbyConfig = AbbyConfig + FlagName extends string, + TestName extends string, + Tests extends Record, + ConfigType extends AbbyConfig = AbbyConfig >({ - abbyConfig, - config: abbyMiddlewarreConfig + abbyConfig, + config: abbyMiddlewarreConfig, }: { - abbyConfig: F.Narrow>; - config?: abbyMiddlewareConfig; + abbyConfig: F.Narrow>; + config?: abbyMiddlewareConfig; }) => { - const config = abbyConfig as unknown as ConfigType; - const abby = await createAbby(abbyConfig); + const config = abbyConfig as unknown as ConfigType; + const abby = await createAbby(abbyConfig); - const featureFlagMiddleware = [number]>( - name: F, - req: Request, - res: Response, - next: NextFunction - ) => { - const flagValue = abby.getFeatureFlagValue(name); - if (!flagValue) { - res.sendStatus(403); - return; - } - next(); - }; + const featureFlagMiddleware = < + F extends NonNullable[number] + >( + name: F, + req: Request, + res: Response, + next: NextFunction + ) => { + const flagValue = abby.getFeatureFlagValue(name); + if (!flagValue) { + res.sendStatus(403); + return; + } + next(); + }; - const AbTestMiddleware = ( - name: T, - req: Request, - res: Response, - next: NextFunction - ) => { - setRequest(req); - setResponse(res); - const value = abby.getABTestValue(name); - next(); - }; + const AbTestMiddleware = ( + name: T, + req: Request, + res: Response, + next: NextFunction + ) => { + setRequest(req); + setResponse(res); + const value = abby.getABTestValue(name); + next(); + }; - return { featureFlagMiddleware, AbTestMiddleware }; + return { featureFlagMiddleware, AbTestMiddleware }; }; - -const x = await abbyMiddlewareFactory({ - abbyConfig: { - projectId: 'clfn3hs1t0002kx08x3kidi80', - currentEnvironment: process.env.NODE_ENV, - tests: { - 'New Test3': { - variants: ['A', 'B'] - } - }, - flags: ['lol', 'test3', 'testAbby'], - flagCacheConfig: { - refetchFlags: true, - timeToLive: 1 - } - }, - config: {} -}); - -x.AbTestMiddleware(); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 228431da..6472f039 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,46 +1,57 @@ -import { expect, test, describe, beforeEach } from 'vitest'; -import express, { response } from 'express'; -import request from 'supertest'; -import { abbyMiddlewareFactory } from '../express/abbyMiddlewareFactory.ts'; +import { expect, test, describe, beforeEach } from "vitest"; +import express, { response } from "express"; +import request, { Response, Request } from "supertest"; +import { abbyMiddlewareFactory } from "../express/abbyMiddlewareFactory.ts"; -describe('express middleware working', () => { - let app: express.Application; +describe("express middleware working", () => { + let app: express.Application; - beforeEach(async () => { - const { AbTestMiddleware, featureFlagMiddleware } = await abbyMiddlewareFactory({ - abbyConfig: { - projectId: 'clfn3hs1t0002kx08x3kidi80', - currentEnvironment: process.env.NODE_ENV, - tests: { - 'New Test3': { - variants: ['A', 'B'] - } - }, - flags: ['lol', 'test3', 'testAbby'], - flagCacheConfig: { - refetchFlags: true, - timeToLive: 1 - } - } - }); - app = express(); - // Add any other middlewares or routes necessary for your test - app.use('/featureflagTest', (req, res, next) => featureFlagMiddleware('test2', req, res, next)); - app.get('/', (req, res) => { - res.send('hiadsa'); - }); - }); + beforeEach(async () => { + const { AbTestMiddleware, featureFlagMiddleware } = + await abbyMiddlewareFactory({ + abbyConfig: { + projectId: "123", + currentEnvironment: process.env.NODE_ENV, + tests: { + test: { + variants: ["A", "B", "C", "D"], + }, + test2: { + variants: ["A", "B"], + }, + }, + flags: ["flag1", "flag2"], + }, + }); + app = express(); + // Add any other middlewares or routes necessary for your test + app.use("/featureFlagEnabled", (req, res, next) => + featureFlagMiddleware("flag1", req, res, next) + ); + app.use("/featureFlagDisabled", (req, res, next) => + featureFlagMiddleware("flag2", req, res, next) + ); + app.use("/cookieNeedToBeSet", (req, res, next) => + AbTestMiddleware("test2", req, res, next) + ); + app.get("/cookieSet", (req, res) => { + res.send("hiadsa"); + }); + }); - test('abTestMiddleware working', async () => { - //test cookie retrieval + test.skip("abTestMiddleware respects the set cookie", async () => { + //test cookie retrieval - const res = await request(app).get('/'); + const res = await request(app).get("/"); + }); - console.log(res.text); - //check if cookie is set - }); + test("abTestMiddleware sets the right cookie", async () => { + const res = await request(app).get("/cookieNeedToBeSet"); + const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull + expect(cookies[0]).toBe("__abby__ab__123_test2=A; Path=/"); + }); - test.skip('featureFlag Middleware working', async () => { - //check if feature flag value is respected - }); + test.skip("featureFlag Middleware working", async () => { + //check if feature flag value is respected + }); }); From 0191e54976fe37c5c4d4353d0dbd47a74fd37a9d Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 22:42:29 +0200 Subject: [PATCH 36/68] chore: add prettier settings --- .prettierrc.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .prettierrc.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..451f0854 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": false, + "trailingComma": "es5", + "printWidth": 100 + } \ No newline at end of file From 83a1bcdb3c9c77760ec994389eafb07d2bb49d19 Mon Sep 17 00:00:00 2001 From: Tim <82676248+Tim-53@users.noreply.github.com> Date: Wed, 14 Jun 2023 23:37:54 +0200 Subject: [PATCH 37/68] add feature flag middleware tests --- .../src/express/abbyMiddlewareFactory.ts | 5 +-- packages/nodejs/src/tests/abbyExpress.test.ts | 45 ++++++++++--------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index a7a6c58a..98f28548 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -22,9 +22,7 @@ export const abbyMiddlewareFactory = async < const config = abbyConfig as unknown as ConfigType; const abby = await createAbby(abbyConfig); - const featureFlagMiddleware = < - F extends NonNullable[number] - >( + const featureFlagMiddleware = [number]>( name: F, req: Request, res: Response, @@ -33,6 +31,7 @@ export const abbyMiddlewareFactory = async < const flagValue = abby.getFeatureFlagValue(name); if (!flagValue) { res.sendStatus(403); + console.log("return"); return; } next(); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 6472f039..e3e47bc4 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,28 +1,29 @@ import { expect, test, describe, beforeEach } from "vitest"; -import express, { response } from "express"; +import express from "express"; import request, { Response, Request } from "supertest"; import { abbyMiddlewareFactory } from "../express/abbyMiddlewareFactory.ts"; +import { A } from "ts-toolbelt"; describe("express middleware working", () => { let app: express.Application; beforeEach(async () => { - const { AbTestMiddleware, featureFlagMiddleware } = - await abbyMiddlewareFactory({ - abbyConfig: { - projectId: "123", - currentEnvironment: process.env.NODE_ENV, - tests: { - test: { - variants: ["A", "B", "C", "D"], - }, - test2: { - variants: ["A", "B"], - }, + const { AbTestMiddleware, featureFlagMiddleware } = await abbyMiddlewareFactory({ + abbyConfig: { + projectId: "123", + currentEnvironment: process.env.NODE_ENV, + tests: { + test: { + variants: ["A", "B", "C", "D"], + }, + test2: { + variants: ["A", "B"], }, - flags: ["flag1", "flag2"], }, - }); + flags: ["flag1", "flag2"], + }, + }); + app = express(); // Add any other middlewares or routes necessary for your test app.use("/featureFlagEnabled", (req, res, next) => @@ -31,9 +32,10 @@ describe("express middleware working", () => { app.use("/featureFlagDisabled", (req, res, next) => featureFlagMiddleware("flag2", req, res, next) ); - app.use("/cookieNeedToBeSet", (req, res, next) => - AbTestMiddleware("test2", req, res, next) - ); + app.get("/featureFlagEnabled", (req, res) => res.send("")); + app.get("/featureFlagDisabled", (req, res) => res.send("")); + + app.use("/cookieNeedToBeSet", (req, res, next) => AbTestMiddleware("test2", req, res, next)); app.get("/cookieSet", (req, res) => { res.send("hiadsa"); }); @@ -41,8 +43,6 @@ describe("express middleware working", () => { test.skip("abTestMiddleware respects the set cookie", async () => { //test cookie retrieval - - const res = await request(app).get("/"); }); test("abTestMiddleware sets the right cookie", async () => { @@ -53,5 +53,10 @@ describe("express middleware working", () => { test.skip("featureFlag Middleware working", async () => { //check if feature flag value is respected + + const succesFullResponse = await request(app).get("/featureFlagEnabled"); + const forbiddenResponse = await request(app).get("/featureFlagDisabled"); + expect(succesFullResponse.statusCode).toBe(200); + expect(forbiddenResponse.statusCode).toBe(403); }); }); From d4fc5ea5c04b38051bd9d3be9030592359e66744 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:59:22 +0200 Subject: [PATCH 38/68] complete express middleware tests --- .../src/express/abbyMiddlewareFactory.ts | 7 ++- packages/nodejs/src/tests/abbyExpress.test.ts | 55 ++++++++++++------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index 98f28548..bc3071e8 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -30,8 +30,7 @@ export const abbyMiddlewareFactory = async < ) => { const flagValue = abby.getFeatureFlagValue(name); if (!flagValue) { - res.sendStatus(403); - console.log("return"); + res.status(403).json({}); return; } next(); @@ -46,6 +45,10 @@ export const abbyMiddlewareFactory = async < setRequest(req); setResponse(res); const value = abby.getABTestValue(name); + //make sure body is defined + req.body = req.body ?? {}; + // appends test to body + req.body.ABBY = value; next(); }; diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index e3e47bc4..88788414 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,13 +1,12 @@ -import { expect, test, describe, beforeEach } from "vitest"; +import { expect, test, describe, beforeAll } from "vitest"; import express from "express"; -import request, { Response, Request } from "supertest"; +import request from "supertest"; import { abbyMiddlewareFactory } from "../express/abbyMiddlewareFactory.ts"; -import { A } from "ts-toolbelt"; describe("express middleware working", () => { let app: express.Application; - beforeEach(async () => { + beforeAll(async () => { const { AbTestMiddleware, featureFlagMiddleware } = await abbyMiddlewareFactory({ abbyConfig: { projectId: "123", @@ -26,37 +25,51 @@ describe("express middleware working", () => { app = express(); // Add any other middlewares or routes necessary for your test - app.use("/featureFlagEnabled", (req, res, next) => + app.use("/featureFlag/Enabled", (req, res, next) => featureFlagMiddleware("flag1", req, res, next) ); - app.use("/featureFlagDisabled", (req, res, next) => + app.use("/featureFlag/Disabled", (req, res, next) => featureFlagMiddleware("flag2", req, res, next) ); - app.get("/featureFlagEnabled", (req, res) => res.send("")); - app.get("/featureFlagDisabled", (req, res) => res.send("")); + app.get("/featureFlag/Enabled", (req, res) => res.send("")); + app.get("/featureFlag/Disabled", (req, res) => res.send("")); - app.use("/cookieNeedToBeSet", (req, res, next) => AbTestMiddleware("test2", req, res, next)); - app.get("/cookieSet", (req, res) => { + app.use("/cookie", (req, res, next) => AbTestMiddleware("test2", req, res, next)); + app.get("/cookie/notSet", (req, res) => { + const variant = req.body.ABBY; + if (variant) { + res.send(variant); + return; + } + res.sendStatus(404); + }); + app.get("/cookie/Set", (req, res) => { res.send("hiadsa"); }); }); - test.skip("abTestMiddleware respects the set cookie", async () => { + //TODO for whatever reason middleware tests need to be executed first, else it does not work + test("featureFlag Middleware working", async () => { + //check if feature flag value is respected + + const succesFullResponse = await request(app).get("/featureFlag/Enabled"); + const forbiddenResponse = await request(app).get("/featureFlag/Disabled"); + expect(succesFullResponse.statusCode).toBe(200); + expect(forbiddenResponse.statusCode).toBe(403); + }); + test("abTestMiddleware respects the set cookie", async () => { + const cookieVariant = "D"; //test cookie retrieval + const response = await request(app) + .get("/cookie/notSet") + .set("Cookie", [`__abby__ab__123_test2=${cookieVariant}; Path=/`]); + + expect(response.text).toBe(cookieVariant); }); test("abTestMiddleware sets the right cookie", async () => { - const res = await request(app).get("/cookieNeedToBeSet"); + const res = await request(app).get("/cookie/Set"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull expect(cookies[0]).toBe("__abby__ab__123_test2=A; Path=/"); }); - - test.skip("featureFlag Middleware working", async () => { - //check if feature flag value is respected - - const succesFullResponse = await request(app).get("/featureFlagEnabled"); - const forbiddenResponse = await request(app).get("/featureFlagDisabled"); - expect(succesFullResponse.statusCode).toBe(200); - expect(forbiddenResponse.statusCode).toBe(403); - }); }); From 498315f366db145c52d1aeb3dafceb427ffe99ad Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 15 Jun 2023 14:03:04 +0200 Subject: [PATCH 39/68] disabled msw warnings for calls to express --- packages/nodejs/src/tests/setup.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/nodejs/src/tests/setup.ts b/packages/nodejs/src/tests/setup.ts index 242ad08e..e1c80da3 100644 --- a/packages/nodejs/src/tests/setup.ts +++ b/packages/nodejs/src/tests/setup.ts @@ -1,13 +1,25 @@ -import { expect, afterEach } from 'vitest'; +import { expect, afterEach } from "vitest"; -import { server } from './mocks/server.ts'; -import fetch from 'node-fetch'; +import { server } from "./mocks/server.ts"; +import fetch from "node-fetch"; /// @ts-ignore global.fetch = fetch; // Establish API mocking before all tests. -beforeAll(() => server.listen()); +beforeAll(() => + server.listen({ + onUnhandledRequest(req) { + //requests to express should not be intercepted and there should be no warning + const excludedRoutes = ["/cookie", "/featureFlag"]; + const routeIsExcluded = excludedRoutes.some((route) => req.url.pathname.includes(route)); + if (routeIsExcluded) { + return; + } + console.error("Found an unhandled %s request to %s", req.method, req.url.href); + }, + }) +); // Reset any request handlers that we may add during the tests, // so they don't affect other tests. afterEach(() => server.resetHandlers()); From 3f400ebd7f9acdafa14d265045b41334d9e80197 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 21 Jun 2023 13:45:11 +0200 Subject: [PATCH 40/68] add build script, tsup and exports --- packages/core/src/shared/http.ts | 20 +------- packages/nodejs/package.json | 21 ++++++-- .../src/abby/contexts/requestContext.ts | 7 ++- packages/nodejs/src/abby/index.ts | 0 packages/nodejs/src/index.ts | 16 +++++-- packages/nodejs/tsup.config.ts | 12 +++++ pnpm-lock.yaml | 48 +++++++++++++++++-- 7 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 packages/nodejs/src/abby/index.ts create mode 100644 packages/nodejs/tsup.config.ts diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index 3fa0be3b..138588a2 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,17 +1,6 @@ import { ABBY_BASE_URL } from "./constants"; import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; -// function fetchData(url: RequestInfo | URL, init?: RequestInit) { -// if (typeof window === "undefined") { -// // Running in Node.js -// const fetch = require("node-fetch"); -// return fetch(url); -// } else { -// // Running in a browser -// return fetch(url); -// } -// } - export abstract class HttpService { static async getProjectData({ projectId, @@ -33,9 +22,7 @@ export abstract class HttpService { const data = (await res.json()) as AbbyDataResponse; return data; } catch (err) { - console.error( - "[ABBY]: failed to load project data, falling back to defaults" - ); + console.error("[ABBY]: failed to load project data, falling back to defaults"); return null; } } @@ -49,10 +36,7 @@ export abstract class HttpService { type: AbbyEventType; data: Omit; }) { - if ( - typeof window === "undefined" || - window.location.hostname === "localhost" - ) { + if (typeof window === "undefined" || window.location.hostname === "localhost") { // don't send data in development return; } diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 7fa138f7..d1317052 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -2,13 +2,27 @@ "name": "my-express-app", "version": "1.0.0", "description": "", - "main": "index.js", "type": "module", "scripts": { "test": "vitest ", + "build": "tsup src/index.ts src/abby/createAbby.ts src/express/abbyMiddlewareFactory.ts", "dev": "nodemon ./src/index.ts", "dev:debugger": "nodemon ./src/index.ts --inspect" }, + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "express": { + "import": "./dist/express/abbyMiddlewareFactory.js", + "require": "./dist/express/abbyMiddlewareFactory.cjs" + }, + "node": { + "import": "./dist/abby/createAbby.js", + "require": "./dist/abby/createAbby.cjs" + } + }, "keywords": [], "author": "", "license": "ISC", @@ -21,15 +35,16 @@ "@types/express": "^4.17.17", "@types/jest": "^29.5.1", "@types/node": "^20.2.5", + "@types/supertest": "^2.0.12", "install": "^0.13.0", "msw": "^0.49.1", "node-fetch": "^3.3.1", "nodemon": "^2.0.22", "supertest": "^6.3.3", "ts-node": "^10.9.1", + "tsup": "^6.5.0", "typescript": "^5.0.4", "vite": "^4.3.9", - "vitest": "^0.31.4", - "@types/supertest": "^2.0.12" + "vitest": "^0.31.4" } } \ No newline at end of file diff --git a/packages/nodejs/src/abby/contexts/requestContext.ts b/packages/nodejs/src/abby/contexts/requestContext.ts index 30443309..770a0a9b 100644 --- a/packages/nodejs/src/abby/contexts/requestContext.ts +++ b/packages/nodejs/src/abby/contexts/requestContext.ts @@ -3,10 +3,9 @@ import { Request } from "express"; let req: Request | null = null; export function setRequest(request: Request) { - req = request; + req = request; } -export function getRequest() { - return req; +export function getRequest(): Request | null { + return req; } - diff --git a/packages/nodejs/src/abby/index.ts b/packages/nodejs/src/abby/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 4bd03e14..477120aa 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,14 +1,20 @@ -import express from 'express'; -import { featureFlagMiddleware, AbTestMiddleware } from './express/abbyMiddlewareFactory.ts'; +import express from "express"; +// import { featureFlagMiddleware, AbTestMiddleware } from "./express/abbyMiddlewareFactory.ts"; +import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory.ts"; +import { createAbby } from "./abby/createAbby.ts"; const app = express(); const port = 3000; -app.use('/', (req, res, next) => AbTestMiddleware(req, res, 'New Test3', next)); +// app.use("/", (req, res, next) => AbTestMiddleware(req, res, "New Test3", next)); // app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) -app.get('/', async (req, res) => { - res.send('very nice content that needs to be protected'); +app.get("/", async (req, res) => { + res.send("very nice content that needs to be protected"); }); app.listen(port, () => console.log(`Express app running on port ${port}!`)); + +const exportObj: any = { expressMiddlware: abbyMiddlewareFactory, NodeJsStandAlone: createAbby }; + +export default exportObj; diff --git a/packages/nodejs/tsup.config.ts b/packages/nodejs/tsup.config.ts new file mode 100644 index 00000000..2521d3f3 --- /dev/null +++ b/packages/nodejs/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + dts: true, + // we want to bundle the shared package because it's not published to npm + // it's hacky :) + noExternal: ["shared/src/types"], + clean: true, + sourcemap: true, + treeshake: true, + format: ["esm", "cjs"], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88699c0f..141f3304 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -584,7 +584,7 @@ importers: version: link:../tsconfig tsup: specifier: ^6.5.0 - version: 6.5.0(typescript@4.9.3) + version: 6.5.0(ts-node@10.9.1)(typescript@5.0.4) typescript: specifier: ^4.9.3 version: 4.9.3 @@ -746,7 +746,7 @@ importers: version: link:../tsconfig tsup: specifier: ^6.5.0 - version: 6.5.0(typescript@4.9.3) + version: 6.5.0(ts-node@10.9.1)(typescript@5.0.4) typescript: specifier: ^4.9.3 version: 4.9.3 @@ -799,6 +799,9 @@ importers: ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.2.5)(typescript@5.0.4) + tsup: + specifier: ^6.5.0 + version: 6.5.0(ts-node@10.9.1)(typescript@5.0.4) typescript: specifier: ^5.0.4 version: 5.0.4 @@ -865,7 +868,7 @@ importers: version: link:../tsconfig tsup: specifier: ^6.5.0 - version: 6.5.0(typescript@4.9.3) + version: 6.5.0(ts-node@10.9.1)(typescript@5.0.4) typescript: specifier: ^4.9.3 version: 4.9.3 @@ -1380,6 +1383,7 @@ packages: /@angular/compiler-cli@15.2.0(@angular/compiler@15.2.0)(typescript@4.9.5): resolution: {integrity: sha512-ETnRBdY/LGcmDRQ9GQc9KyCd1kuRnj+Y9luq2dCTMysP+NgylmYoGDsJOsDKm6SzPo+B4PSAyHX2J4CVQFHpPg==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler': 15.2.0 typescript: '>=4.8.2 <5.0' @@ -7122,6 +7126,7 @@ packages: /@sveltejs/kit@1.15.8(svelte@3.58.0)(vite@4.3.2): resolution: {integrity: sha512-xPIF3UbFEA5BBZWFTGGUtSZ0O3DAtmzIp/yZZVdLIfzZ9+geKG3iGSVFnOUdYstjU7JcvJg12UC5MD5xoED59A==} engines: {node: ^16.14 || >=18} + hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 @@ -7149,6 +7154,7 @@ packages: /@sveltejs/package@2.0.2(svelte@3.58.0)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} + hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -9093,6 +9099,7 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -9107,6 +9114,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.21): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -11155,6 +11163,7 @@ packages: /esbuild@0.15.18: resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.15.18 @@ -11351,6 +11360,7 @@ packages: /eslint-config-prettier@8.5.0(eslint@7.32.0): resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -12687,6 +12697,7 @@ packages: /glob@10.2.3: resolution: {integrity: sha512-Kb4rfmBVE3eQTAimgmeqc2LwSnN0wIOkkUL6HmxEFxNJ4fHghYHVbFba/HcGcRjE6s9KoMNK3rSOwkL4PioZjg==} engines: {node: '>=16 || 14 >=14.17'} + hasBin: true dependencies: foreground-child: 3.1.1 jackspeak: 2.2.0 @@ -14039,6 +14050,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.4): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15720,6 +15732,7 @@ packages: /msw@0.49.1(typescript@4.9.3): resolution: {integrity: sha512-JpIIq4P65ofj0HVmDMkJuRwgP9s5kcdutpZ15evMTb2k91/USB7IKWRLV9J1Mzc3OqTdwNj4RwtOWJ5y/FulQQ==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15755,6 +15768,7 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15790,6 +15804,7 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -15930,6 +15945,7 @@ packages: /next-sitemap@3.1.55(@next/env@13.3.4)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -15955,6 +15971,7 @@ packages: /next@13.3.4(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -16066,6 +16083,7 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.0)(tslib@2.5.0)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -18137,6 +18155,7 @@ packages: /rollup@3.21.6: resolution: {integrity: sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -19054,6 +19073,7 @@ packages: /sucrase@3.29.0: resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==} engines: {node: '>=8'} + hasBin: true dependencies: commander: 4.1.1 glob: 7.1.6 @@ -19128,6 +19148,7 @@ packages: /svelte-check@2.10.3(@babel/core@7.21.4)(svelte@3.55.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -19301,6 +19322,7 @@ packages: /tailwindcss@3.3.1(postcss@8.4.21)(ts-node@10.9.1): resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} engines: {node: '>=12.13.0'} + hasBin: true peerDependencies: postcss: ^8.0.9 dependencies: @@ -19625,6 +19647,7 @@ packages: /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -19656,6 +19679,7 @@ packages: /ts-node@10.9.1(@types/node@18.15.11)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19685,6 +19709,7 @@ packages: /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -19743,9 +19768,10 @@ packages: /tslib@2.5.0: resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} - /tsup@6.5.0(typescript@4.9.3): + /tsup@6.5.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==} engines: {node: '>=14'} + hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -19772,7 +19798,7 @@ packages: source-map: 0.8.0-beta.0 sucrase: 3.29.0 tree-kill: 1.2.2 - typescript: 4.9.3 + typescript: 5.0.4 transitivePeerDependencies: - supports-color - ts-node @@ -20224,6 +20250,7 @@ packages: /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -20477,6 +20504,7 @@ packages: /vite@3.2.5: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20509,6 +20537,7 @@ packages: /vite@4.2.0: resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20541,6 +20570,7 @@ packages: /vite@4.3.2: resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20572,6 +20602,7 @@ packages: /vite@4.3.9(@types/node@18.15.11): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20604,6 +20635,7 @@ packages: /vite@4.3.9(@types/node@20.2.5): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -20658,6 +20690,7 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20703,6 +20736,7 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -20914,6 +20948,7 @@ packages: /webpack-dev-server@4.11.1(webpack@5.75.0): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} + hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -20988,6 +21023,7 @@ packages: /webpack@5.75.0(esbuild@0.17.8): resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} engines: {node: '>=10.13.0'} + hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -21184,12 +21220,14 @@ packages: /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} + hasBin: true dependencies: isexe: 2.0.0 /which@3.0.1: resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true dependencies: isexe: 2.0.0 dev: true From 6a4841c1d9b9b2c4c468feb1bb2ce86c9f95173d Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 21 Jun 2023 13:56:29 +0200 Subject: [PATCH 41/68] add gitignore --- packages/nodejs/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/nodejs/.gitignore diff --git a/packages/nodejs/.gitignore b/packages/nodejs/.gitignore new file mode 100644 index 00000000..53c37a16 --- /dev/null +++ b/packages/nodejs/.gitignore @@ -0,0 +1 @@ +dist \ No newline at end of file From dc44eb6e6705a8344eca99e1e66b6722f2d14d71 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 6 Jul 2023 13:45:05 +0200 Subject: [PATCH 42/68] add alll flags middleware --- .../src/express/abbyMiddlewareFactory.ts | 53 +++++++++++++------ packages/nodejs/src/index.ts | 36 ++++++++++--- 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index bc3071e8..7e56ee1b 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -5,8 +5,6 @@ import { AbbyConfig, ABConfig } from "@tryabby/core"; import { createAbby } from "../abby/createAbby.ts"; import { F } from "ts-toolbelt"; -type abbyMiddlewareConfig = {}; - export const abbyMiddlewareFactory = async < FlagName extends string, TestName extends string, @@ -14,43 +12,64 @@ export const abbyMiddlewareFactory = async < ConfigType extends AbbyConfig = AbbyConfig >({ abbyConfig, - config: abbyMiddlewarreConfig, }: { abbyConfig: F.Narrow>; - config?: abbyMiddlewareConfig; }) => { - const config = abbyConfig as unknown as ConfigType; + const configNarrowed = abbyConfig as unknown as ConfigType; const abby = await createAbby(abbyConfig); const featureFlagMiddleware = [number]>( name: F, req: Request, res: Response, - next: NextFunction + next: NextFunction, + statusCode?: number, + errorMessage?: string ) => { const flagValue = abby.getFeatureFlagValue(name); + if (!flagValue) { - res.status(403).json({}); + res.status(statusCode ?? 403).json(errorMessage); return; } next(); }; - const AbTestMiddleware = ( - name: T, + const setRequestResponse = (req: Request, res: Response) => { + setRequest(req); + setResponse(res); + }; + + const extractTest = (name: T) => { + const variant = abby.getABTestValue(name); + return { name, variant }; + }; + + const allTestsMiddleWare = ( req: Request, res: Response, next: NextFunction ) => { - setRequest(req); - setResponse(res); - const value = abby.getABTestValue(name); - //make sure body is defined - req.body = req.body ?? {}; - // appends test to body - req.body.ABBY = value; + if (configNarrowed.tests) { + setRequestResponse(req, res); + const allTests = Object.keys(configNarrowed.tests) as T[]; //TODO get type in a proper way + const testWithVariant = allTests.map((test) => { + return extractTest(test); + }); + } + next(); }; - return { featureFlagMiddleware, AbTestMiddleware }; + const allFlagMiddleWare = [number]>( + req: Request, + res: Response, + next: NextFunction + ) => {}; + + const getVariant = (name: T) => { + return abby.getABTestValue(name); + }; + + return { featureFlagMiddleware, allTestsMiddleWare, getVariant }; }; diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 477120aa..78af1d5c 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,20 +1,40 @@ import express from "express"; -// import { featureFlagMiddleware, AbTestMiddleware } from "./express/abbyMiddlewareFactory.ts"; import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory.ts"; import { createAbby } from "./abby/createAbby.ts"; const app = express(); const port = 3000; -// app.use("/", (req, res, next) => AbTestMiddleware(req, res, "New Test3", next)); -// app.use("/", (req: Request, res: Response, next: NextFunction) => featureFlagMiddleware(req, res, "testAbby", next)) +const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = await abbyMiddlewareFactory({ + abbyConfig: { + projectId: "clfn3hs1t0002kx08x3kidi80", + currentEnvironment: process.env.NODE_ENV, + tests: { + "New Test3": { + variants: ["A", "B"], + }, + Test2: { + variants: ["A", "klein", "basic"], + }, + "New Test6": { + variants: ["A"], + }, + }, + flags: ["lol", "test3", "testAbby"], + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1, + }, + }, +}); + +app.use("/", (req, res, next) => allTestsMiddleWare(req, res, next)); + +// app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next)); app.get("/", async (req, res) => { - res.send("very nice content that needs to be protected"); + const variant = getVariant("New Test3"); + res.send(variant === "A" ? "very nice content that needs to be protected" : "vriant B"); }); app.listen(port, () => console.log(`Express app running on port ${port}!`)); - -const exportObj: any = { expressMiddlware: abbyMiddlewareFactory, NodeJsStandAlone: createAbby }; - -export default exportObj; From 17479551c484a73173faefc3c2659be6a92e2f69 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 6 Jul 2023 15:58:49 +0200 Subject: [PATCH 43/68] fix package name --- packages/nodejs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index d1317052..5fef7efe 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -1,5 +1,5 @@ { - "name": "my-express-app", + "name": "@tryabby/nodejs", "version": "1.0.0", "description": "", "type": "module", From 489ed85b46c18c5953eb26930fc720d38808b878 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:13:49 +0200 Subject: [PATCH 44/68] add body parser --- packages/next/package.json | 3 +- packages/nodejs/src/index.ts | 10 ++- pnpm-lock.yaml | 163 +++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 3 deletions(-) diff --git a/packages/next/package.json b/packages/next/package.json index d25cff48..02b698dc 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -7,7 +7,8 @@ "dist" ], "scripts": { - "build": "tsup src/index.tsx", + "build": "echo 0", + "build2": "tsup src/index.tsx", "dev": "pnpm run build --watch", "test": "vitest", "prepare": "pnpm run build" diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 11b61496..9c88d714 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -29,13 +29,19 @@ const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = await abbyMidd }, }); +app.use(express.json()); + app.use("/", (req, res, next) => { + console.log(req.body) allTestsMiddleWare(req, res, next) }); const deciderFunc = (req: Request, flagVal: any) => { - - return true; + const countryOfOrigin = req.body.country; + if(!countryOfOrigin) return false; + const decision = flagVal.enabledCountries === countryOfOrigin + console.log("acces granted") + return decision; } app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next, deciderFunc)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 14b6d2f0..458f1bde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1349,6 +1349,7 @@ packages: /@angular/cli@15.2.8: resolution: {integrity: sha512-3VlTfm6DUZfFHBY43vQSAaqmFTxy3VtRd/iDBCHcEPhHwYLWBvNwReJuJfNja8O105QQ6DBiYVBExEBtPmjQ4w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true dependencies: '@angular-devkit/architect': 0.1502.8(chokidar@3.5.3) '@angular-devkit/core': 15.2.8(chokidar@3.5.3) @@ -1388,6 +1389,7 @@ packages: /@angular/compiler-cli@15.2.9(@angular/compiler@15.2.9)(typescript@4.9.5): resolution: {integrity: sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler': 15.2.9 typescript: '>=4.8.2 <5.0' @@ -1517,6 +1519,7 @@ packages: /@aw-web-design/x-default-browser@1.4.88: resolution: {integrity: sha512-AkEmF0wcwYC2QkhK703Y83fxWARttIWXDmQN8+cof8FmFZ5BRhnNXGymeb1S73bOCLfWjYELxtujL56idCN/XA==} + hasBin: true dependencies: default-browser-id: 3.0.0 dev: true @@ -2043,6 +2046,7 @@ packages: /@babel/parser@7.21.9: resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} engines: {node: '>=6.0.0'} + hasBin: true dependencies: '@babel/types': 7.21.5 dev: true @@ -2050,6 +2054,7 @@ packages: /@babel/parser@7.22.5: resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} engines: {node: '>=6.0.0'} + hasBin: true dependencies: '@babel/types': 7.22.5 @@ -4827,6 +4832,7 @@ packages: /@changesets/cli@2.26.1: resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} + hasBin: true dependencies: '@babel/runtime': 7.22.5 '@changesets/apply-release-plan': 6.1.3 @@ -5901,6 +5907,7 @@ packages: /@microsoft/api-extractor@7.35.2: resolution: {integrity: sha512-f3aM4hJkv5W04eLh6wdJ9fzscAmb+GgnT6j+pMlGVyz+0p2yQDndymvgUseFO6a+HqFDSH4yZXmkqT8bP7lVWQ==} + hasBin: true dependencies: '@microsoft/api-extractor-model': 7.27.2 '@microsoft/tsdoc': 0.14.2 @@ -6458,6 +6465,7 @@ packages: /@npmcli/installed-package-contents@2.0.2: resolution: {integrity: sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true dependencies: npm-bundled: 3.0.0 npm-normalize-package-bin: 3.0.1 @@ -6466,6 +6474,7 @@ packages: /@npmcli/move-file@2.0.1: resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs dependencies: mkdirp: 1.0.4 rimraf: 3.0.2 @@ -8160,6 +8169,7 @@ packages: /@storybook/cli@7.0.20: resolution: {integrity: sha512-ZYBJL1d7nWXQok7SriF18h0YPO38Eu1YxR8b1VHgOZYKZhuQmtvhmjMTSgpoGjnynNkEaV3fvm6+KYTjSqYcnw==} + hasBin: true dependencies: '@babel/core': 7.22.5 '@babel/preset-env': 7.22.5(@babel/core@7.22.5) @@ -8608,6 +8618,7 @@ packages: /@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9): resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==} engines: {node: ^16.14 || >=18} + hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 @@ -8635,6 +8646,7 @@ packages: /@sveltejs/package@2.0.2(svelte@3.59.1)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} + hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -9603,6 +9615,7 @@ packages: /@types/sass@1.45.0: resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==} + deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed. dependencies: sass: 1.63.3 dev: true @@ -10067,6 +10080,7 @@ packages: /@wessberg/ts-evaluator@0.0.27(typescript@4.9.5): resolution: {integrity: sha512-7gOpVm3yYojUp/Yn7F4ZybJRxyqfMNf0LXK5KJiawbPfL0XTsJV+0mgrEDjOIR6Bi0OYk2Cyg4tjFu1r8MCZaA==} engines: {node: '>=10.1.0'} + deprecated: this package has been renamed to ts-evaluator. Please install ts-evaluator instead peerDependencies: typescript: '>=3.2.x || >= 4.x' dependencies: @@ -10179,14 +10193,17 @@ packages: /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} + hasBin: true /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} + hasBin: true /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} + hasBin: true /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} @@ -10291,6 +10308,7 @@ packages: /ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} + hasBin: true /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -10497,6 +10515,7 @@ packages: /astring@1.8.6: resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + hasBin: true dev: false /async-each-series@0.1.1: @@ -10524,6 +10543,7 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10538,6 +10558,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.24): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10907,6 +10928,7 @@ packages: /browser-sync@2.29.3: resolution: {integrity: sha512-NiM38O6XU84+MN+gzspVmXV2fTOoe+jBqIBx3IBdhZrdeURr6ZgznJr/p+hQ+KzkKEiGH/GcC4SQFSL0jV49bg==} engines: {node: '>= 8.0.0'} + hasBin: true dependencies: browser-sync-client: 2.29.3 browser-sync-ui: 2.29.3 @@ -10953,6 +10975,7 @@ packages: /browserslist@4.21.5: resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true dependencies: caniuse-lite: 1.0.30001499 electron-to-chromium: 1.4.427 @@ -10962,6 +10985,7 @@ packages: /browserslist@4.21.7: resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true dependencies: caniuse-lite: 1.0.30001499 electron-to-chromium: 1.4.427 @@ -11049,6 +11073,7 @@ packages: /c8@7.14.0: resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} engines: {node: '>=10.12.0'} + hasBin: true dependencies: '@bcoe/v8-coverage': 0.2.3 '@istanbuljs/schema': 0.1.3 @@ -11413,6 +11438,7 @@ packages: /color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true dev: true /colorette@2.0.20: @@ -11738,6 +11764,7 @@ packages: /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} + hasBin: true /cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} @@ -12064,6 +12091,7 @@ packages: /detect-port@1.5.1: resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + hasBin: true dependencies: address: 1.2.2 debug: 4.3.4 @@ -12074,6 +12102,7 @@ packages: /dev-ip@1.0.1: resolution: {integrity: sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==} engines: {node: '>= 0.8.0'} + hasBin: true dev: false /devalue@4.3.2: @@ -12267,6 +12296,7 @@ packages: /editorconfig@0.15.3: resolution: {integrity: sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==} + hasBin: true dependencies: commander: 2.20.3 lru-cache: 4.1.5 @@ -12280,6 +12310,7 @@ packages: /ejs@3.1.9: resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} engines: {node: '>=0.10.0'} + hasBin: true dependencies: jake: 10.8.7 dev: true @@ -12388,6 +12419,7 @@ packages: /envinfo@7.8.1: resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} engines: {node: '>=4'} + hasBin: true dev: true /err-code@2.0.3: @@ -12396,6 +12428,7 @@ packages: /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true requiresBuild: true dependencies: prr: 1.0.1 @@ -12661,11 +12694,13 @@ packages: /esbuild-wasm@0.17.19: resolution: {integrity: sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==} engines: {node: '>=12'} + hasBin: true dev: true /esbuild-wasm@0.17.8: resolution: {integrity: sha512-zCmpxv95E0FuCmvdw1K836UHnj4EdiQnFfjTby35y3LAjRPtXMj3sbHDRHjbD8Mqg5lTwq3knacr/1qIFU51CQ==} engines: {node: '>=12'} + hasBin: true /esbuild-windows-32@0.15.18: resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} @@ -12697,6 +12732,7 @@ packages: /esbuild@0.15.18: resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.15.18 @@ -12726,6 +12762,7 @@ packages: /esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -12755,6 +12792,7 @@ packages: /esbuild@0.17.8: resolution: {integrity: sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.8 @@ -12808,6 +12846,7 @@ packages: /escodegen@2.0.0: resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} engines: {node: '>=6.0'} + hasBin: true dependencies: esprima: 4.0.1 estraverse: 5.3.0 @@ -12893,6 +12932,7 @@ packages: /eslint-config-prettier@8.8.0(eslint@7.32.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -13303,6 +13343,7 @@ packages: /eslint@7.32.0: resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} engines: {node: ^10.12.0 || >=12.0.0} + hasBin: true dependencies: '@babel/code-frame': 7.12.11 '@eslint/eslintrc': 0.4.3 @@ -13350,6 +13391,7 @@ packages: /eslint@8.29.0: resolution: {integrity: sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true dependencies: '@eslint/eslintrc': 1.4.1 '@humanwhocodes/config-array': 0.11.10 @@ -13397,6 +13439,7 @@ packages: /eslint@8.4.1: resolution: {integrity: sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true dependencies: '@eslint/eslintrc': 1.4.1 '@humanwhocodes/config-array': 0.9.5 @@ -13443,6 +13486,7 @@ packages: /eslint@8.42.0: resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) '@eslint-community/regexpp': 4.5.1 @@ -13519,6 +13563,7 @@ packages: /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} + hasBin: true /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} @@ -13723,6 +13768,7 @@ packages: /extract-zip@1.7.0: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true dependencies: concat-stream: 1.6.2 debug: 2.6.9 @@ -14219,6 +14265,7 @@ packages: /giget@1.1.2: resolution: {integrity: sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==} + hasBin: true dependencies: colorette: 2.0.20 defu: 6.1.2 @@ -14280,6 +14327,7 @@ packages: /glob@10.2.7: resolution: {integrity: sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==} engines: {node: '>=16 || 14 >=14.17'} + hasBin: true dependencies: foreground-child: 3.1.1 jackspeak: 2.2.1 @@ -14427,6 +14475,7 @@ packages: /gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true dependencies: browserify-zlib: 0.1.4 is-deflate: 1.0.0 @@ -14449,6 +14498,7 @@ packages: /handlebars@4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} engines: {node: '>=0.4.7'} + hasBin: true dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -14879,6 +14929,7 @@ packages: /image-size@0.5.5: resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} engines: {node: '>=0.10.0'} + hasBin: true requiresBuild: true optional: true @@ -15124,6 +15175,7 @@ packages: /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true dependencies: ci-info: 3.8.0 dev: true @@ -15150,10 +15202,12 @@ packages: /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} + hasBin: true /is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true dev: false /is-extendable@0.1.1: @@ -15201,6 +15255,7 @@ packages: /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} + hasBin: true dependencies: is-docker: 3.0.0 dev: false @@ -15507,6 +15562,7 @@ packages: /jake@10.8.7: resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} engines: {node: '>=10'} + hasBin: true dependencies: async: 3.2.4 chalk: 4.1.2 @@ -15622,6 +15678,7 @@ packages: /jiti@1.18.2: resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} + hasBin: true /jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} @@ -15639,6 +15696,7 @@ packages: /js-beautify@1.14.8: resolution: {integrity: sha512-4S7HFeI9YfRvRgKnEweohs0tgJj28InHVIj4Nl8Htf96Y6pHg3+tJrmo4ucAM9f7l4SHbFI3IvFAZ2a1eQPbyg==} engines: {node: '>=12'} + hasBin: true dependencies: config-chain: 1.1.13 editorconfig: 0.15.3 @@ -15670,17 +15728,20 @@ packages: /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true dependencies: argparse: 1.0.10 esprima: 4.0.1 /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true dependencies: argparse: 2.0.1 /jscodeshift@0.14.0(@babel/preset-env@7.21.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15710,6 +15771,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.22.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15863,10 +15925,12 @@ packages: /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} + hasBin: true /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -15887,12 +15951,14 @@ packages: /json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true dependencies: minimist: 1.2.8 /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} + hasBin: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -16014,6 +16080,7 @@ packages: /karma@6.4.2: resolution: {integrity: sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==} engines: {node: '>= 10'} + hasBin: true dependencies: '@colors/colors': 1.5.0 body-parser: 1.20.2 @@ -16047,6 +16114,7 @@ packages: /katex@0.16.7: resolution: {integrity: sha512-Xk9C6oGKRwJTfqfIbtr0Kes9OSv6IFsuhFGc7tW4urlpMJtuh+7YhzU6YEG9n8gmWKcMAFzkp7nr+r69kV0zrA==} + hasBin: true dependencies: commander: 8.3.0 dev: false @@ -16114,6 +16182,7 @@ packages: /less@4.1.3: resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} engines: {node: '>=6'} + hasBin: true dependencies: copy-anything: 2.0.6 parse-node-version: 1.0.1 @@ -16217,6 +16286,7 @@ packages: /localtunnel@2.0.2: resolution: {integrity: sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==} engines: {node: '>=8.3.0'} + hasBin: true dependencies: axios: 0.21.4(debug@4.3.2) debug: 4.3.2 @@ -16330,6 +16400,7 @@ packages: /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true dependencies: js-tokens: 4.0.0 @@ -16380,6 +16451,7 @@ packages: /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true dev: true /magic-string@0.25.9: @@ -16505,6 +16577,7 @@ packages: /markdown-it@13.0.1: resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} + hasBin: true dependencies: argparse: 2.0.1 entities: 3.0.1 @@ -16798,6 +16871,7 @@ packages: /micro@10.0.1: resolution: {integrity: sha512-9uwZSsUrqf6+4FLLpiPj5TRWQv5w5uJrJwsx1LR/TjqvQmKC1XnGQ9OHrFwR3cbZ46YqPqxO/XJCOpWnqMPw2Q==} engines: {node: '>= 16.0.0'} + hasBin: true dependencies: arg: 4.1.0 content-type: 1.0.4 @@ -17169,24 +17243,29 @@ packages: /mime@1.4.1: resolution: {integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==} + hasBin: true dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} + hasBin: true /mime@2.5.2: resolution: {integrity: sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==} engines: {node: '>=4.0.0'} + hasBin: true dev: true /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} + hasBin: true /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} + hasBin: true dev: true /mimic-fn@2.1.0: @@ -17214,6 +17293,7 @@ packages: /mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true dev: true /minimalistic-assert@1.0.1: @@ -17352,16 +17432,19 @@ packages: /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true dependencies: minimist: 1.2.8 /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} + hasBin: true /mkdirp@2.1.6: resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} engines: {node: '>=10'} + hasBin: true dev: true /mlly@1.4.0: @@ -17406,6 +17489,7 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17441,6 +17525,7 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17475,6 +17560,7 @@ packages: /multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true dependencies: dns-packet: 5.6.0 thunky: 1.1.0 @@ -17492,10 +17578,12 @@ packages: /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true /nanoid@4.0.2: resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} engines: {node: ^14 || ^16 || >=18} + hasBin: true dev: false /natural-compare-lite@1.4.0: @@ -17508,6 +17596,7 @@ packages: /needle@3.2.0: resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} engines: {node: '>= 4.4.x'} + hasBin: true requiresBuild: true dependencies: debug: 3.2.7(supports-color@5.5.0) @@ -17582,6 +17671,7 @@ packages: /next-sitemap@3.1.55(@next/env@13.4.5)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -17607,6 +17697,7 @@ packages: /next@13.3.4(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17650,6 +17741,7 @@ packages: /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17761,6 +17853,7 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.9)(tslib@2.5.3)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -17863,11 +17956,13 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + hasBin: true optional: true /node-gyp@9.3.1: resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true dependencies: env-paths: 2.2.1 glob: 7.2.3 @@ -17899,6 +17994,7 @@ packages: /nodemon@2.0.22: resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} engines: {node: '>=8.10.0'} + hasBin: true dependencies: chokidar: 3.5.3 debug: 3.2.7(supports-color@5.5.0) @@ -17914,6 +18010,7 @@ packages: /nopt@1.0.10: resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true dependencies: abbrev: 1.1.1 dev: true @@ -17921,6 +18018,7 @@ packages: /nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true dependencies: abbrev: 1.1.1 @@ -17995,6 +18093,7 @@ packages: /npm-packlist@5.1.3: resolution: {integrity: sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true dependencies: glob: 8.1.0 ignore-walk: 5.0.1 @@ -18265,6 +18364,7 @@ packages: /opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true dev: true /openid-client@5.4.2: @@ -18414,6 +18514,7 @@ packages: /pacote@15.1.0: resolution: {integrity: sha512-FFcjtIl+BQNfeliSm7MZz5cpdohvUV1yjGnqgVM4UnVF7JslRY0ImXAygdaCDV0jjUADEWu4y5xsDV8brtrTLg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true dependencies: '@npmcli/git': 4.1.0 '@npmcli/installed-package-contents': 2.0.2 @@ -18913,6 +19014,7 @@ packages: /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} + hasBin: true dev: true /prettier@3.0.0: @@ -18964,6 +19066,7 @@ packages: /prisma@4.15.0: resolution: {integrity: sha512-iKZZpobPl48gTcSZVawLMQ3lEy6BnXwtoMj7hluoGFYu2kQ6F9LBuBrUyF95zRVnNo8/3KzLXJXJ5TEnLSJFiA==} engines: {node: '>=14.17'} + hasBin: true requiresBuild: true dependencies: '@prisma/engines': 4.15.0 @@ -19202,6 +19305,7 @@ packages: /publint@0.1.12: resolution: {integrity: sha512-8LxkO430t/SOhUl0qXQWdXq34m6oyLcPhE4Kc8eXhOEnB82vCHcShPQ2kH53n/ksC7jWdRWDP7MPGxKJbntQfg==} engines: {node: '>=16'} + hasBin: true dependencies: npm-packlist: 5.1.3 picocolors: 1.0.0 @@ -19659,6 +19763,7 @@ packages: /regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true dependencies: jsesc: 0.5.0 @@ -19809,6 +19914,7 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -19817,6 +19923,7 @@ packages: /resolve@1.22.2: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -19824,6 +19931,7 @@ packages: /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -19864,24 +19972,28 @@ packages: /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + hasBin: true dependencies: glob: 7.2.3 dev: true /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true dependencies: glob: 7.2.3 dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true dependencies: glob: 7.2.3 /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -19889,6 +20001,7 @@ packages: /rollup@3.25.0: resolution: {integrity: sha512-FnJkNRst2jEZGw7f+v4hFo6UTzpDKrAKcHZWcEfm5/GJQ5CK7wgb4moNLNAe7npKUev7yQn1AY/YbZRIxOv6Qg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -19990,6 +20103,7 @@ packages: /sass@1.58.1: resolution: {integrity: sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==} engines: {node: '>=12.0.0'} + hasBin: true dependencies: chokidar: 3.5.3 immutable: 4.3.0 @@ -19998,6 +20112,7 @@ packages: /sass@1.63.3: resolution: {integrity: sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==} engines: {node: '>=14.0.0'} + hasBin: true dependencies: chokidar: 3.5.3 immutable: 4.3.0 @@ -20074,23 +20189,28 @@ packages: /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + hasBin: true dev: true /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} + hasBin: true dependencies: lru-cache: 6.0.0 /semver@7.5.1: resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} engines: {node: '>=10'} + hasBin: true dependencies: lru-cache: 6.0.0 @@ -20239,6 +20359,7 @@ packages: /shelljs@0.8.5: resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} engines: {node: '>=4'} + hasBin: true dependencies: glob: 7.2.3 interpret: 1.4.0 @@ -20296,6 +20417,7 @@ packages: /sigstore@1.6.0: resolution: {integrity: sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true dependencies: '@sigstore/protobuf-specs': 0.1.0 '@sigstore/tuf': 1.0.0 @@ -20358,6 +20480,7 @@ packages: /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} + hasBin: true dependencies: array.prototype.flat: 1.3.1 breakword: 1.0.6 @@ -20441,6 +20564,7 @@ packages: /sorcery@0.10.0: resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==} + hasBin: true dependencies: buffer-crc32: 0.2.13 minimist: 1.2.8 @@ -20493,6 +20617,7 @@ packages: /sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead dev: true /space-separated-tokens@1.1.5: @@ -20625,6 +20750,7 @@ packages: /storybook@7.0.20: resolution: {integrity: sha512-QxMdqeY7oigiwnVqVPp8550CUtfWW5fujkVXUhgyI1u4i9dpmJxkxWRvfSvhGKAvHf0n2BZ550SevZRPrCr+Tg==} + hasBin: true dependencies: '@storybook/cli': 7.0.20 transitivePeerDependencies: @@ -20641,6 +20767,7 @@ packages: /stream-throttle@0.1.3: resolution: {integrity: sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==} engines: {node: '>= 0.10.0'} + hasBin: true dependencies: commander: 2.20.3 limiter: 1.1.5 @@ -20836,6 +20963,7 @@ packages: /sucrase@3.32.0: resolution: {integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==} engines: {node: '>=8'} + hasBin: true dependencies: '@jridgewell/gen-mapping': 0.3.3 commander: 4.1.1 @@ -20911,6 +21039,7 @@ packages: /svelte-check@2.10.3(@babel/core@7.22.5)(svelte@3.59.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -21073,6 +21202,7 @@ packages: /tailwindcss@3.3.2(ts-node@10.9.1): resolution: {integrity: sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==} engines: {node: '>=14.0.0'} + hasBin: true dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -21196,6 +21326,7 @@ packages: /terser@5.16.3: resolution: {integrity: sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==} engines: {node: '>=10'} + hasBin: true dependencies: '@jridgewell/source-map': 0.3.3 acorn: 8.10.0 @@ -21205,6 +21336,7 @@ packages: /terser@5.17.7: resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==} engines: {node: '>=10'} + hasBin: true dependencies: '@jridgewell/source-map': 0.3.3 acorn: 8.10.0 @@ -21295,6 +21427,7 @@ packages: /title@3.5.3: resolution: {integrity: sha512-20JyowYglSEeCvZv3EZ0nZ046vLarO37prvV0mbtQV7C8DJPGgN967r8SJkqd3XK3K3lD3/Iyfp3avjfil8Q2Q==} + hasBin: true dependencies: arg: 1.0.0 chalk: 2.3.0 @@ -21359,6 +21492,7 @@ packages: /touch@3.1.0: resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true dependencies: nopt: 1.0.10 dev: true @@ -21396,6 +21530,7 @@ packages: /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -21427,6 +21562,7 @@ packages: /ts-node@10.9.1(@types/node@18.16.17)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21456,6 +21592,7 @@ packages: /ts-node@10.9.1(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21520,6 +21657,7 @@ packages: /tsup@6.7.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -21574,6 +21712,7 @@ packages: /tty-table@4.2.1: resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} engines: {node: '>=8.0.0'} + hasBin: true dependencies: chalk: 4.1.2 csv: 5.5.3 @@ -21734,15 +21873,18 @@ packages: /typescript@4.9.3: resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} engines: {node: '>=4.2.0'} + hasBin: true dev: false /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} + hasBin: true /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} + hasBin: true dev: true /ua-parser-js@0.7.35: @@ -21763,6 +21905,7 @@ packages: /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} + hasBin: true requiresBuild: true dev: true optional: true @@ -21996,6 +22139,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22005,6 +22149,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.7): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22092,14 +22237,17 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true dev: true /uvu@0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} + hasBin: true dependencies: dequal: 2.0.3 diff: 5.1.0 @@ -22179,6 +22327,7 @@ packages: /vite-node@0.31.4(@types/node@18.16.17): resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} engines: {node: '>=v14.18.0'} + hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 @@ -22222,6 +22371,7 @@ packages: /vite@3.2.7: resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22254,6 +22404,7 @@ packages: /vite@4.3.9(@types/node@18.16.17): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22286,6 +22437,7 @@ packages: /vite@4.3.9(@types/node@20.3.0): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22329,6 +22481,7 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22374,6 +22527,7 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22457,6 +22611,7 @@ packages: /w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. dependencies: browser-process-hrtime: 1.0.0 dev: false @@ -22541,6 +22696,7 @@ packages: /webpack-bundle-analyzer@4.7.0: resolution: {integrity: sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==} engines: {node: '>= 10.13.0'} + hasBin: true dependencies: acorn: 8.8.2 acorn-walk: 8.2.0 @@ -22585,6 +22741,7 @@ packages: /webpack-dev-server@4.11.1(webpack@5.76.1): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} + hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -22667,6 +22824,7 @@ packages: /webpack@5.76.1(esbuild@0.17.8): resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} + hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -22815,18 +22973,21 @@ packages: /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true dependencies: isexe: 2.0.0 /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} + hasBin: true dependencies: isexe: 2.0.0 /which@3.0.1: resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true dependencies: isexe: 2.0.0 dev: true @@ -22834,6 +22995,7 @@ packages: /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} + hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 @@ -23125,6 +23287,7 @@ packages: /z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} + hasBin: true dependencies: lodash.get: 4.4.2 lodash.isequal: 4.5.0 From 28e4633a3489859e13af1c27960b96202f773a12 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:10:49 +0200 Subject: [PATCH 45/68] remove unecassry awaits --- packages/nodejs/src/abby/createAbby.ts | 17 ++++++-------- .../src/express/abbyMiddlewareFactory.ts | 18 +++++++-------- packages/nodejs/src/index.ts | 22 +++++++++---------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 519ba0af..00d14e37 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,13 +1,13 @@ -import { ABConfig, Abby, AbbyConfig , FlagValueString, FlagValueStringToType } from "@tryabby/core"; +import { ABConfig, Abby, AbbyConfig, FlagValueString, FlagValueStringToType } from "@tryabby/core"; import { F } from "ts-toolbelt"; import { TestStorageService } from "./StorageService.ts"; -export async function createAbby< +export function createAbby< FlagName extends string, TestName extends string, Tests extends Record, Flags extends Record = Record, - ConfigType extends AbbyConfig = AbbyConfig + ConfigType extends AbbyConfig = AbbyConfig, >(abbyConfig: F.Narrow>) { const abbyCoreInstance = new Abby(abbyConfig, { get: (key: string) => { @@ -19,10 +19,11 @@ export async function createAbby< }); //load data and initialise the abby Object - await abbyCoreInstance.loadProjectData(); + // await + abbyCoreInstance.loadProjectData(); const config = abbyConfig as unknown as ConfigType; - + /** * @param name Name of the test that the variant should be retrieved for * @returns Value of the currently selected variant @@ -36,11 +37,7 @@ export async function createAbby< * @param name Name of the feature flag * @returns Value of the feature flag */ - const getFeatureFlagValue = < - F extends keyof Flags - >( - name: F - ) => { + const getFeatureFlagValue = (name: F) => { return abbyCoreInstance.getFeatureFlag(name); }; diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index 59cba1c9..39c06fcd 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -5,22 +5,22 @@ import { AbbyConfig, ABConfig, FlagValueString } from "@tryabby/core"; import { createAbby } from "../abby/createAbby.ts"; import { F } from "ts-toolbelt"; -export const abbyMiddlewareFactory = async < +export const abbyMiddlewareFactory = < FlagName extends string, TestName extends string, Tests extends Record, Flags extends Record = Record, - ConfigType extends AbbyConfig = AbbyConfig + ConfigType extends AbbyConfig = AbbyConfig, >({ abbyConfig, }: { abbyConfig: F.Narrow>; }) => { const configNarrowed = abbyConfig as unknown as ConfigType; - const abbyNodeInstance = await createAbby(abbyConfig); + const abbyNodeInstance = createAbby(abbyConfig); // const featureFlagMiddleware = [number]>( - const featureFlagMiddleware = ( + const featureFlagMiddleware = ( name: F, req: Request, res: Response, @@ -29,9 +29,9 @@ export const abbyMiddlewareFactory = async < ) => { const flagValue = abbyNodeInstance.getFeatureFlagValue(name as any); //TODO fix type - console.log(flagValue) + console.log(flagValue); const decision = deciderFunction(req, flagValue); - console.log(decision) + console.log(decision); if (!decision) { res.status(403).json("errorMessage"); return; @@ -46,7 +46,7 @@ export const abbyMiddlewareFactory = async < const extractTest = (name: T) => { const variant = abbyNodeInstance.getABTestValue(name); - console.log(name, variant) + console.log(name, variant); return { name, variant }; }; @@ -69,9 +69,7 @@ export const abbyMiddlewareFactory = async < req: Request, res: Response, next: NextFunction - ) => { - - }; + ) => {}; const getVariant = (name: T) => { return abbyNodeInstance.getABTestValue(name); diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 9c88d714..7acf3ea1 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,11 +1,11 @@ -import express , {Request} from "express"; +import express, { Request } from "express"; import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory.ts"; import { createAbby } from "./abby/createAbby.ts"; const app = express(); const port = 3000; -const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = await abbyMiddlewareFactory({ +const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = abbyMiddlewareFactory({ abbyConfig: { projectId: "clfn3hs1t0002kx08x3kidi80", currentEnvironment: process.env.NODE_ENV, @@ -18,9 +18,9 @@ const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = await abbyMidd }, }, flags: { - "lol": "Boolean", - "test3": "Boolean", - "testAbby": "Boolean" + lol: "Boolean", + test3: "Boolean", + testAbby: "Boolean", }, flagCacheConfig: { refetchFlags: true, @@ -32,17 +32,17 @@ const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = await abbyMidd app.use(express.json()); app.use("/", (req, res, next) => { - console.log(req.body) - allTestsMiddleWare(req, res, next) + console.log(req.body); + allTestsMiddleWare(req, res, next); }); const deciderFunc = (req: Request, flagVal: any) => { const countryOfOrigin = req.body.country; - if(!countryOfOrigin) return false; - const decision = flagVal.enabledCountries === countryOfOrigin - console.log("acces granted") + if (!countryOfOrigin) return false; + const decision = flagVal.enabledCountries === countryOfOrigin; + console.log("acces granted"); return decision; -} +}; app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next, deciderFunc)); From 9df8bcfffb0971a7808f2fc155d94eaa1221375a Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Fri, 7 Jul 2023 15:32:37 +0200 Subject: [PATCH 46/68] Fix build --- packages/core/package.json | 1 - packages/core/src/shared/http.ts | 3 +- packages/core/tsup.config.ts | 1 + packages/nodejs/package.json | 20 ++-- packages/nodejs/src/abby/StorageService.ts | 63 +++++------ packages/nodejs/src/abby/createAbby.ts | 3 +- .../src/express/abbyMiddlewareFactory.ts | 37 ++++--- packages/nodejs/src/index.ts | 3 +- packages/nodejs/tsconfig.json | 104 +----------------- packages/nodejs/tsup.config.ts | 3 - pnpm-lock.yaml | 12 +- 11 files changed, 84 insertions(+), 166 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index e410094b..f8b5ee58 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,7 +39,6 @@ "zod": "^3.19.1" }, "dependencies": { - "node-fetch": "^3.3.0", "ts-toolbelt": "^9.6.0" } } \ No newline at end of file diff --git a/packages/core/src/shared/http.ts b/packages/core/src/shared/http.ts index 9955bd0d..75b36d9a 100644 --- a/packages/core/src/shared/http.ts +++ b/packages/core/src/shared/http.ts @@ -1,6 +1,5 @@ import { ABBY_BASE_URL } from "./constants"; import type { AbbyEventType, AbbyEvent, AbbyDataResponse } from "./index"; -import fetch from "node-fetch"; //TODO remove later export abstract class HttpService { static async getProjectData({ @@ -23,7 +22,7 @@ export abstract class HttpService { const data = (await res.json()) as AbbyDataResponse; return data; } catch (err) { - console.log(err) + console.log(err); console.error("[ABBY]: failed to load project data, falling back to defaults"); return null; } diff --git a/packages/core/tsup.config.ts b/packages/core/tsup.config.ts index 998f88c1..6fbd5074 100644 --- a/packages/core/tsup.config.ts +++ b/packages/core/tsup.config.ts @@ -7,5 +7,6 @@ export default defineConfig({ clean: true, sourcemap: true, treeshake: true, + format: ["cjs", "esm"], }); diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 5fef7efe..d26e26aa 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -2,25 +2,31 @@ "name": "@tryabby/nodejs", "version": "1.0.0", "description": "", - "type": "module", "scripts": { "test": "vitest ", - "build": "tsup src/index.ts src/abby/createAbby.ts src/express/abbyMiddlewareFactory.ts", + "build": "tsup src/index.ts", "dev": "nodemon ./src/index.ts", "dev:debugger": "nodemon ./src/index.ts --inspect" }, + "main": "dist/index.js", + "files": [ + "dist" + ], "exports": { ".": { "import": "./dist/index.js", - "require": "./dist/index.cjs" + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" }, - "express": { + "./express": { "import": "./dist/express/abbyMiddlewareFactory.js", - "require": "./dist/express/abbyMiddlewareFactory.cjs" + "require": "./dist/express/abbyMiddlewareFactory.cjs", + "types": "./dist/abbyMiddlewareFactory.d.ts" }, - "node": { + "./node": { "import": "./dist/abby/createAbby.js", - "require": "./dist/abby/createAbby.cjs" + "require": "./dist/abby/createAbby.cjs", + "types": "./dist/createAbby.d.ts" } }, "keywords": [], diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/abby/StorageService.ts index 9382e472..792e20c8 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/abby/StorageService.ts @@ -1,42 +1,39 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; -import { parseCookies } from "./helpers.ts"; -import { getRequest } from "./contexts/requestContext.ts"; -import { getResponse } from "./contexts/responseContext.ts"; +import { parseCookies } from "./helpers"; +import { getRequest } from "./contexts/requestContext"; +import { getResponse } from "./contexts/responseContext"; class ABStorageService implements IStorageService { - get(projectId: string, key: string): string | null { - const req = getRequest(); - if (!req) return null; - const cookieMap = parseCookies(req); - const cookieKey = getABStorageKey(projectId, key); - const cookieValue = cookieMap.get(cookieKey) - return cookieValue ?? null; - } - set(projectId: string, key: string, value: string): void { - const response = getResponse(); - if (!response) return; - const cookieKey = getABStorageKey(projectId, key); - response.cookie(cookieKey, value) - } - remove(projectId: string, key: string): void { - throw new Error("Method not implemented."); - } - + get(projectId: string, key: string): string | null { + const req = getRequest(); + if (!req) return null; + const cookieMap = parseCookies(req); + const cookieKey = getABStorageKey(projectId, key); + const cookieValue = cookieMap.get(cookieKey); + return cookieValue ?? null; + } + set(projectId: string, key: string, value: string): void { + const response = getResponse(); + if (!response) return; + const cookieKey = getABStorageKey(projectId, key); + response.cookie(cookieKey, value); + } + remove(projectId: string, key: string): void { + throw new Error("Method not implemented."); + } } class FFStorageService implements IStorageService { - get(projectId: string, key: string): string | null { - throw new Error("Method not implemented."); - } - set(projectId: string, key: string, value: string): void { - throw new Error("Method not implemented."); - } - remove(projectId: string, key: string): void { - throw new Error("Method not implemented."); - } - - + get(projectId: string, key: string): string | null { + throw new Error("Method not implemented."); + } + set(projectId: string, key: string, value: string): void { + throw new Error("Method not implemented."); + } + remove(projectId: string, key: string): void { + throw new Error("Method not implemented."); + } } export const TestStorageService = new ABStorageService(); -export const FlagStorageService = new FFStorageService(); \ No newline at end of file +export const FlagStorageService = new FFStorageService(); diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 00d14e37..4d8cdee6 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,6 +1,6 @@ import { ABConfig, Abby, AbbyConfig, FlagValueString, FlagValueStringToType } from "@tryabby/core"; import { F } from "ts-toolbelt"; -import { TestStorageService } from "./StorageService.ts"; +import { TestStorageService } from "./StorageService"; export function createAbby< FlagName extends string, @@ -19,7 +19,6 @@ export function createAbby< }); //load data and initialise the abby Object - // await abbyCoreInstance.loadProjectData(); const config = abbyConfig as unknown as ConfigType; diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index 39c06fcd..dfc0a0ec 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -1,10 +1,22 @@ import { NextFunction, Request, Response } from "express"; -import { setRequest } from "../abby/contexts/requestContext.ts"; -import { setResponse } from "../abby/contexts/responseContext.ts"; +import { setRequest } from "../abby/contexts/requestContext"; +import { setResponse } from "../abby/contexts/responseContext"; import { AbbyConfig, ABConfig, FlagValueString } from "@tryabby/core"; -import { createAbby } from "../abby/createAbby.ts"; +import { createAbby } from "../abby/createAbby"; import { F } from "ts-toolbelt"; +interface AbbyMiddlewareFactoryResult { + featureFlagMiddleware: ( + name: F, + req: Request, + res: Response, + next: NextFunction, + deciderFunction: (req: Request, flagValue: any) => boolean + ) => void; + allTestsMiddleWare: (req: Request, res: Response, next: NextFunction) => void; + getVariant: (name: T) => any; +} + export const abbyMiddlewareFactory = < FlagName extends string, TestName extends string, @@ -16,10 +28,9 @@ export const abbyMiddlewareFactory = < }: { abbyConfig: F.Narrow>; }) => { - const configNarrowed = abbyConfig as unknown as ConfigType; const abbyNodeInstance = createAbby(abbyConfig); + const configNarrowed = abbyConfig as unknown as ConfigType; - // const featureFlagMiddleware = [number]>( const featureFlagMiddleware = ( name: F, req: Request, @@ -27,7 +38,7 @@ export const abbyMiddlewareFactory = < next: NextFunction, deciderFunction: (req: Request, flagValue: any) => boolean ) => { - const flagValue = abbyNodeInstance.getFeatureFlagValue(name as any); //TODO fix type + const flagValue = abbyNodeInstance.getFeatureFlagValue(name as unknown as FlagName); //TODO fix type console.log(flagValue); const decision = deciderFunction(req, flagValue); @@ -39,12 +50,12 @@ export const abbyMiddlewareFactory = < next(); }; - const setRequestResponse = (req: Request, res: Response) => { + const setRequestResponse = (req: Request, res: Response): void => { setRequest(req); setResponse(res); }; - const extractTest = (name: T) => { + const extractTest = (name: T): any => { const variant = abbyNodeInstance.getABTestValue(name); console.log(name, variant); return { name, variant }; @@ -65,11 +76,11 @@ export const abbyMiddlewareFactory = < next(); }; - const allFlagMiddleWare = ( - req: Request, - res: Response, - next: NextFunction - ) => {}; + // const allFlagMiddleWare = ( + // req: Request, + // res: Response, + // next: NextFunction + // ) => {}; const getVariant = (name: T) => { return abbyNodeInstance.getABTestValue(name); diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 7acf3ea1..1889f700 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,6 +1,5 @@ import express, { Request } from "express"; -import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory.ts"; -import { createAbby } from "./abby/createAbby.ts"; +import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory"; const app = express(); const port = 3000; diff --git a/packages/nodejs/tsconfig.json b/packages/nodejs/tsconfig.json index 58354e67..3379dc3b 100644 --- a/packages/nodejs/tsconfig.json +++ b/packages/nodejs/tsconfig.json @@ -1,104 +1,8 @@ { + "extends": "tsconfig/react-library.json", "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - "module": "node16", /* Specify what module code is generated. */ - "rootDir": "./src", /* Specify the root folder within your source files. */ - "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "lib": ["ESNext", "DOM"], + "types": ["vitest/globals"] }, - "ts-node": { - "esm": true - } + "exclude": ["src/tests/**/*.ts"] } \ No newline at end of file diff --git a/packages/nodejs/tsup.config.ts b/packages/nodejs/tsup.config.ts index 2521d3f3..f516547a 100644 --- a/packages/nodejs/tsup.config.ts +++ b/packages/nodejs/tsup.config.ts @@ -2,9 +2,6 @@ import { defineConfig } from "tsup"; export default defineConfig({ dts: true, - // we want to bundle the shared package because it's not published to npm - // it's hacky :) - noExternal: ["shared/src/types"], clean: true, sourcemap: true, treeshake: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 458f1bde..11d85ebb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -575,9 +575,6 @@ importers: packages/core: dependencies: - node-fetch: - specifier: ^3.3.0 - version: 3.3.1 ts-toolbelt: specifier: ^9.6.0 version: 9.6.0 @@ -588,6 +585,9 @@ importers: msw: specifier: ^0.49.1 version: 0.49.3(typescript@4.9.5) + node-fetch: + specifier: ^3.3.0 + version: 3.3.1 tsconfig: specifier: workspace:* version: link:../tsconfig @@ -11824,6 +11824,7 @@ packages: /data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + dev: true /data-urls@2.0.0: resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} @@ -13834,6 +13835,7 @@ packages: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.2.1 + dev: true /fetch-retry@5.0.6: resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} @@ -14040,6 +14042,7 @@ packages: engines: {node: '>=12.20.0'} dependencies: fetch-blob: 3.2.0 + dev: true /formidable@2.1.2: resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} @@ -17926,6 +17929,7 @@ packages: /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} + dev: true /node-fetch-native@1.2.0: resolution: {integrity: sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==} @@ -17949,6 +17953,7 @@ packages: data-uri-to-buffer: 4.0.1 fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + dev: true /node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} @@ -22671,6 +22676,7 @@ packages: /web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} + dev: true /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} From e7b14ca7d49f36faf9d3ca92c9ab65f0fd0bf32f Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Fri, 7 Jul 2023 16:36:02 +0200 Subject: [PATCH 47/68] update package.json --- packages/nodejs/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index d26e26aa..867b2f2b 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -48,6 +48,7 @@ "nodemon": "^2.0.22", "supertest": "^6.3.3", "ts-node": "^10.9.1", + "tsconfig": "workspace:*", "tsup": "^6.5.0", "typescript": "^5.0.4", "vite": "^4.3.9", From 0e24266b1947e967b0be27a789e61be9f7821ed6 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:43:41 +0200 Subject: [PATCH 48/68] it works --- packages/nodejs/package.json | 4 +++- packages/nodejs/src/abby/abby.ts | 32 ++++++++++++++++++-------------- packages/nodejs/tsconfig.json | 15 ++++++++++++--- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 867b2f2b..131aadb0 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -5,7 +5,8 @@ "scripts": { "test": "vitest ", "build": "tsup src/index.ts", - "dev": "nodemon ./src/index.ts", + "dev": "ts-node --esm ./src/index.ts", + "dev2": "tsnd --respawn --transpile-only ./src/index.ts", "dev:debugger": "nodemon ./src/index.ts --inspect" }, "main": "dist/index.js", @@ -48,6 +49,7 @@ "nodemon": "^2.0.22", "supertest": "^6.3.3", "ts-node": "^10.9.1", + "ts-node-dev": "^2.0.0", "tsconfig": "workspace:*", "tsup": "^6.5.0", "typescript": "^5.0.4", diff --git a/packages/nodejs/src/abby/abby.ts b/packages/nodejs/src/abby/abby.ts index d5d33eba..d144d6ac 100644 --- a/packages/nodejs/src/abby/abby.ts +++ b/packages/nodejs/src/abby/abby.ts @@ -1,18 +1,22 @@ -import { createAbby } from './createAbby.ts'; +import { createAbby } from "./createAbby"; -export const { getFeatureFlagValue, getABTestValue } = await createAbby({ - projectId: 'clfn3hs1t0002kx08x3kidi80', - currentEnvironment: process.env.NODE_ENV, - tests: { - 'New Test3': { - variants: ['A', 'B'] - } - }, - flags: ['lol', 'test3', 'testAbby'], - flagCacheConfig: { - refetchFlags: true, - timeToLive: 1 - } +export const { getFeatureFlagValue, getABTestValue } = createAbby({ + projectId: "clfn3hs1t0002kx08x3kidi80", + currentEnvironment: process.env.NODE_ENV, + tests: { + "New Test3": { + variants: ["A", "B"], + }, + }, + flags: { + lol: "Boolean", + test3: "Boolean", + testAbby: "Boolean", + }, + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1, + }, }); export const abby = { getFeatureFlagValue, getABTestValue }; diff --git a/packages/nodejs/tsconfig.json b/packages/nodejs/tsconfig.json index 3379dc3b..a4e4e1c8 100644 --- a/packages/nodejs/tsconfig.json +++ b/packages/nodejs/tsconfig.json @@ -1,8 +1,17 @@ { "extends": "tsconfig/react-library.json", "compilerOptions": { - "lib": ["ESNext", "DOM"], - "types": ["vitest/globals"] + "module": "CommonJS", + "lib": ["ESNext", "DOM"], + "types": ["vitest/globals"], + "esModuleInterop": true, + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true, + "noEmit": true, + "allowImportingTsExtensions": true + }, + "ts-node": { + "esm": true }, "exclude": ["src/tests/**/*.ts"] -} \ No newline at end of file +} From f60453580fa874f91371504082e5641ec20b3016 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:44:15 +0200 Subject: [PATCH 49/68] it works --- packages/next/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/next/package.json b/packages/next/package.json index 02b698dc..d25cff48 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -7,8 +7,7 @@ "dist" ], "scripts": { - "build": "echo 0", - "build2": "tsup src/index.tsx", + "build": "tsup src/index.tsx", "dev": "pnpm run build --watch", "test": "vitest", "prepare": "pnpm run build" From 6f2c349594bb1010a4066abe7860623257294766 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:07:27 +0200 Subject: [PATCH 50/68] create fastify package --- packages/nodejs/package.json | 4 ++-- packages/nodejs/src/fastify/createAbby.ts | 20 ++++++++++++++++++++ packages/nodejs/src/fastify/index.ts | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 packages/nodejs/src/fastify/createAbby.ts create mode 100644 packages/nodejs/src/fastify/index.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 131aadb0..a293f7e0 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -5,8 +5,8 @@ "scripts": { "test": "vitest ", "build": "tsup src/index.ts", - "dev": "ts-node --esm ./src/index.ts", - "dev2": "tsnd --respawn --transpile-only ./src/index.ts", + "dev": "tsnd --respawn --transpile-only ./src/index.ts", + "dev:fastify": "tsnd --respawn --transpile-only ./src/fastify/index.ts", "dev:debugger": "nodemon ./src/index.ts --inspect" }, "main": "dist/index.js", diff --git a/packages/nodejs/src/fastify/createAbby.ts b/packages/nodejs/src/fastify/createAbby.ts new file mode 100644 index 00000000..c479b134 --- /dev/null +++ b/packages/nodejs/src/fastify/createAbby.ts @@ -0,0 +1,20 @@ +import { createAbby } from "../abby/createAbby"; + +export const abby = createAbby({ + projectId: "clfn3hs1t0002kx08x3kidi80", + currentEnvironment: process.env.NODE_ENV, + tests: { + "New Test3": { + variants: ["A", "B"], + }, + }, + flags: { + lol: "Boolean", + test3: "Boolean", + testAbby: "Boolean", + }, + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1, + }, +}); diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts new file mode 100644 index 00000000..4cc7e5ed --- /dev/null +++ b/packages/nodejs/src/fastify/index.ts @@ -0,0 +1,18 @@ +import Fastify from "fastify"; + +const fastify = Fastify(); + +const port = 3000; +console.log("start fastify"); +fastify.get("/", function (request, reply) { + reply.send("Hello world!"); +}); + +fastify.listen({ port }, function (err, address) { + if (err) { + fastify.log.error(err); + process.exit(1); + } + + fastify.log.info(`Fastify is listening on port: ${address}`); +}); From 53b6a9a781d217cfe447c859dd405781e654a55c Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:13:51 +0200 Subject: [PATCH 51/68] make response and request context usable in express and fastify, add fastify cookie parsing --- packages/nodejs/package.json | 2 ++ .../src/abby/contexts/requestContext.ts | 11 ++++++--- .../src/abby/contexts/responseContext.ts | 15 +++++++----- packages/nodejs/src/abby/createAbby.ts | 4 +++- .../nodejs/src/fastify/fastifyHookFactory.ts | 13 ++++++++++ packages/nodejs/src/fastify/index.ts | 14 +++++++++++ .../src/{abby => shared}/StorageService.ts | 11 ++++++--- packages/nodejs/src/shared/helpers.ts | 24 +++++++++++++++++++ 8 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 packages/nodejs/src/fastify/fastifyHookFactory.ts rename packages/nodejs/src/{abby => shared}/StorageService.ts (82%) create mode 100644 packages/nodejs/src/shared/helpers.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index a293f7e0..c53ea6d7 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -34,8 +34,10 @@ "author": "", "license": "ISC", "dependencies": { + "@fastify/cookie": "^8.3.0", "@tryabby/core": "workspace:^", "express": "^4.18.2", + "fastify": "^4.19.2", "ts-toolbelt": "^9.6.0" }, "devDependencies": { diff --git a/packages/nodejs/src/abby/contexts/requestContext.ts b/packages/nodejs/src/abby/contexts/requestContext.ts index 770a0a9b..560d8486 100644 --- a/packages/nodejs/src/abby/contexts/requestContext.ts +++ b/packages/nodejs/src/abby/contexts/requestContext.ts @@ -1,11 +1,16 @@ // hacky way to get request object in storage service without passing it import { Request } from "express"; -let req: Request | null = null; +import { FastifyRequest } from "fastify"; -export function setRequest(request: Request) { +// type RequestType = T extends Request ? Request : FastifyRequest; +type RequestType = Request | FastifyRequest | null; +let req: RequestType = null; + +export function setRequest(request: RequestType) { + console.log("setRequest"); req = request; } -export function getRequest(): Request | null { +export function getRequest(): RequestType | null { return req; } diff --git a/packages/nodejs/src/abby/contexts/responseContext.ts b/packages/nodejs/src/abby/contexts/responseContext.ts index 46f68aa2..353aae42 100644 --- a/packages/nodejs/src/abby/contexts/responseContext.ts +++ b/packages/nodejs/src/abby/contexts/responseContext.ts @@ -1,12 +1,15 @@ // hacky way to get response object in storage service without passing it -import { Response, } from "express"; -let res: Response | null = null; +import { Response } from "express"; +import { FastifyReply } from "fastify"; -export function setResponse(response: Response) { - res = response; +type ResponseType = Response | FastifyReply | null; + +let res: ResponseType = null; + +export function setResponse(response: ResponseType) { + res = response; } export function getResponse() { - return res; + return res; } - diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 4d8cdee6..d8496cef 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,6 +1,6 @@ import { ABConfig, Abby, AbbyConfig, FlagValueString, FlagValueStringToType } from "@tryabby/core"; import { F } from "ts-toolbelt"; -import { TestStorageService } from "./StorageService"; +import { TestStorageService } from "../shared/StorageService"; export function createAbby< FlagName extends string, @@ -11,9 +11,11 @@ export function createAbby< >(abbyConfig: F.Narrow>) { const abbyCoreInstance = new Abby(abbyConfig, { get: (key: string) => { + console.log("getStore"); return TestStorageService.get(abbyConfig.projectId, key); }, set: (key: string, value: any) => { + console.log("set"); TestStorageService.set(abbyConfig.projectId, key, value); }, }); diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts new file mode 100644 index 00000000..d76caa37 --- /dev/null +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -0,0 +1,13 @@ +import { abby } from "./createAbby"; + +export const fastifyHookFactory = () => { + const featureFlagHook = () => {}; + + const ABTestHook = () => {}; + + const getFlagValue = () => {}; + + const getTestValue = () => {}; + + return {}; +}; diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index 4cc7e5ed..bdebf74c 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -1,10 +1,24 @@ import Fastify from "fastify"; +import { parseCookies } from "../shared/helpers"; +import { abby } from "./createAbby"; +import { setRequest, getRequest } from "../abby/contexts/requestContext"; +import { setResponse } from "../abby/contexts/responseContext"; const fastify = Fastify(); +fastify.register(require("@fastify/cookie"), { + secret: "my-secret", // for cookies signature + hook: "onRequest", // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest' + parseOptions: {}, // options for parsing cookies +}); + const port = 3000; console.log("start fastify"); fastify.get("/", function (request, reply) { + console.log(parseCookies(request)); + setRequest(request); + setResponse(reply); + console.log(abby.getABTestValue("New Test3")); reply.send("Hello world!"); }); diff --git a/packages/nodejs/src/abby/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts similarity index 82% rename from packages/nodejs/src/abby/StorageService.ts rename to packages/nodejs/src/shared/StorageService.ts index 792e20c8..e0082dd3 100644 --- a/packages/nodejs/src/abby/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -1,7 +1,8 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers"; -import { getRequest } from "./contexts/requestContext"; -import { getResponse } from "./contexts/responseContext"; +import { getRequest } from "../abby/contexts/requestContext"; +import { getResponse } from "../abby/contexts/responseContext"; +import { FastifyReply } from "fastify"; class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { @@ -14,8 +15,12 @@ class ABStorageService implements IStorageService { } set(projectId: string, key: string, value: string): void { const response = getResponse(); - if (!response) return; + if (!response) { + console.log("return;"); + return; + } const cookieKey = getABStorageKey(projectId, key); + console.log("cookie Service"); response.cookie(cookieKey, value); } remove(projectId: string, key: string): void { diff --git a/packages/nodejs/src/shared/helpers.ts b/packages/nodejs/src/shared/helpers.ts new file mode 100644 index 00000000..8a2a34bd --- /dev/null +++ b/packages/nodejs/src/shared/helpers.ts @@ -0,0 +1,24 @@ +import { Request } from "express"; +import { type FastifyRequest } from "fastify"; + +const fastify = true; + +/** + * helper function to parse express cookie + * @param req express Request | Fastify Request + */ + +// export function parseCookies(req: T) { + +export function parseCookies(req: Request | FastifyRequest) { + const cookies = req.headers.cookie; + const cookieMap = new Map(); + if (!cookies) { + return cookieMap; + } + cookies?.split(";").map((res, index) => { + const parsedCookie = res.trim().split("="); + cookieMap.set(parsedCookie[0], parsedCookie[1]); + }); + return cookieMap; +} From b5bf94ba7ed9239f297b4d417701c9fd34ea34f3 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:48:57 +0200 Subject: [PATCH 52/68] update fastify factory --- .../nodejs/src/fastify/fastifyHookFactory.ts | 57 ++++++++++++++++--- packages/nodejs/src/fastify/index.ts | 30 ++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index d76caa37..71541787 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -1,13 +1,56 @@ +import { ABConfig, FlagValueString, AbbyConfig } from "@tryabby/core"; +import { F } from "ts-toolbelt"; +import { createAbby } from "../abby/createAbby"; import { abby } from "./createAbby"; +import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; -export const fastifyHookFactory = () => { - const featureFlagHook = () => {}; +export const abbyFastifyFactory = < + FlagName extends string, + TestName extends string, + Tests extends Record, + Flags extends Record = Record, + ConfigType extends AbbyConfig = AbbyConfig, +>({ + abbyConfig, +}: { + abbyConfig: F.Narrow>; +}) => { + const abbyNodeInstance = createAbby(abbyConfig); + const configNarrowed = abbyConfig as unknown as ConfigType; + /** + * hook to disbale a path via feature flag + */ + const featureFlagHook = ( + key: F, + request: FastifyRequest, + reply: FastifyReply, + done: HookHandlerDoneFunction + ) => { + const flagValue = abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); //TODO fix type + if (!flagValue) { + reply.status(403).send(); + console.log("disbaled endpoint"); + return; + } + done(); + }; + /** + * hook to parse all ab values on the request object needs to be used at the top + */ + const ABTestHook = ( + key: T, + request: FastifyRequest, + reply: FastifyReply, + done: HookHandlerDoneFunction + ) => {}; - const ABTestHook = () => {}; + const getFlagValue = (key: F) => { + return abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); + }; - const getFlagValue = () => {}; + const getTestValue = (key: T) => { + return abbyNodeInstance.getABTestValue(key); + }; - const getTestValue = () => {}; - - return {}; + return { ABTestHook, featureFlagHook, getFlagValue, getTestValue }; }; diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index bdebf74c..08b89d67 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -3,6 +3,7 @@ import { parseCookies } from "../shared/helpers"; import { abby } from "./createAbby"; import { setRequest, getRequest } from "../abby/contexts/requestContext"; import { setResponse } from "../abby/contexts/responseContext"; +import { abbyFastifyFactory } from "./fastifyHookFactory"; const fastify = Fastify(); @@ -12,6 +13,35 @@ fastify.register(require("@fastify/cookie"), { parseOptions: {}, // options for parsing cookies }); +const { featureFlagHook } = abbyFastifyFactory({ + abbyConfig: { + projectId: "clfn3hs1t0002kx08x3kidi80", + currentEnvironment: process.env.NODE_ENV, + tests: { + "New Test3": { + variants: ["A", "B"], + }, + "New Test6": { + variants: ["A"], + }, + }, + flags: { + lol: "Boolean", + test3: "Boolean", + testAbby: "Boolean", + }, + flagCacheConfig: { + refetchFlags: true, + timeToLive: 1, + }, + }, +}); + +fastify.addHook("onRequest", async (request, reply, done) => { + console.log("hook"); + featureFlagHook("lol", request, reply, done); +}); + const port = 3000; console.log("start fastify"); fastify.get("/", function (request, reply) { From 7b4d66bbdd65973fc31a9794d5e42cb967512c99 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:54:59 +0200 Subject: [PATCH 53/68] repair lockfile --- pnpm-lock.yaml | 470 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 315 insertions(+), 155 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11d85ebb..37212f44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -777,12 +777,18 @@ importers: packages/nodejs: dependencies: + '@fastify/cookie': + specifier: ^8.3.0 + version: 8.3.0 '@tryabby/core': specifier: workspace:^ version: link:../core express: specifier: ^4.18.2 version: 4.18.2 + fastify: + specifier: ^4.19.2 + version: 4.19.2 ts-toolbelt: specifier: ^9.6.0 version: 9.6.0 @@ -817,6 +823,12 @@ importers: ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.3.0)(typescript@5.0.4) + ts-node-dev: + specifier: ^2.0.0 + version: 2.0.0(@types/node@20.3.0)(typescript@5.0.4) + tsconfig: + specifier: workspace:* + version: link:../tsconfig tsup: specifier: ^6.5.0 version: 6.7.0(ts-node@10.9.1)(typescript@5.0.4) @@ -1349,7 +1361,6 @@ packages: /@angular/cli@15.2.8: resolution: {integrity: sha512-3VlTfm6DUZfFHBY43vQSAaqmFTxy3VtRd/iDBCHcEPhHwYLWBvNwReJuJfNja8O105QQ6DBiYVBExEBtPmjQ4w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - hasBin: true dependencies: '@angular-devkit/architect': 0.1502.8(chokidar@3.5.3) '@angular-devkit/core': 15.2.8(chokidar@3.5.3) @@ -1389,7 +1400,6 @@ packages: /@angular/compiler-cli@15.2.9(@angular/compiler@15.2.9)(typescript@4.9.5): resolution: {integrity: sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler': 15.2.9 typescript: '>=4.8.2 <5.0' @@ -1519,7 +1529,6 @@ packages: /@aw-web-design/x-default-browser@1.4.88: resolution: {integrity: sha512-AkEmF0wcwYC2QkhK703Y83fxWARttIWXDmQN8+cof8FmFZ5BRhnNXGymeb1S73bOCLfWjYELxtujL56idCN/XA==} - hasBin: true dependencies: default-browser-id: 3.0.0 dev: true @@ -2046,7 +2055,6 @@ packages: /@babel/parser@7.21.9: resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} engines: {node: '>=6.0.0'} - hasBin: true dependencies: '@babel/types': 7.21.5 dev: true @@ -2054,7 +2062,6 @@ packages: /@babel/parser@7.22.5: resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} engines: {node: '>=6.0.0'} - hasBin: true dependencies: '@babel/types': 7.22.5 @@ -4832,7 +4839,6 @@ packages: /@changesets/cli@2.26.1: resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} - hasBin: true dependencies: '@babel/runtime': 7.22.5 '@changesets/apply-release-plan': 6.1.3 @@ -5543,6 +5549,35 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true + /@fastify/ajv-compiler@3.5.0: + resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==} + dependencies: + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + fast-uri: 2.2.0 + dev: false + + /@fastify/cookie@8.3.0: + resolution: {integrity: sha512-P9hY9GO11L20TnZ33XN3i0bt+3x0zaT7S0ohAzWO950E9PB2xnNhLYzPFJIGFi5AVN0yr5+/iZhWxeYvR6KCzg==} + dependencies: + cookie: 0.5.0 + fastify-plugin: 4.5.0 + dev: false + + /@fastify/deepmerge@1.3.0: + resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} + dev: false + + /@fastify/error@3.3.0: + resolution: {integrity: sha512-dj7vjIn1Ar8sVXj2yAXiMNCJDmS9MQ9XMlIecX2dIzzhjSHCyKo4DdXjXMs7wKW2kj6yvVRSpuQjOZ3YLrh56w==} + dev: false + + /@fastify/fast-json-stringify-compiler@4.3.0: + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + dependencies: + fast-json-stringify: 5.7.0 + dev: false + /@floating-ui/core@1.3.1: resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==} dev: false @@ -5907,7 +5942,6 @@ packages: /@microsoft/api-extractor@7.35.2: resolution: {integrity: sha512-f3aM4hJkv5W04eLh6wdJ9fzscAmb+GgnT6j+pMlGVyz+0p2yQDndymvgUseFO6a+HqFDSH4yZXmkqT8bP7lVWQ==} - hasBin: true dependencies: '@microsoft/api-extractor-model': 7.27.2 '@microsoft/tsdoc': 0.14.2 @@ -6465,7 +6499,6 @@ packages: /@npmcli/installed-package-contents@2.0.2: resolution: {integrity: sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true dependencies: npm-bundled: 3.0.0 npm-normalize-package-bin: 3.0.1 @@ -6474,7 +6507,6 @@ packages: /@npmcli/move-file@2.0.1: resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This functionality has been moved to @npmcli/fs dependencies: mkdirp: 1.0.4 rimraf: 3.0.2 @@ -8169,7 +8201,6 @@ packages: /@storybook/cli@7.0.20: resolution: {integrity: sha512-ZYBJL1d7nWXQok7SriF18h0YPO38Eu1YxR8b1VHgOZYKZhuQmtvhmjMTSgpoGjnynNkEaV3fvm6+KYTjSqYcnw==} - hasBin: true dependencies: '@babel/core': 7.22.5 '@babel/preset-env': 7.22.5(@babel/core@7.22.5) @@ -8618,7 +8649,6 @@ packages: /@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9): resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==} engines: {node: ^16.14 || >=18} - hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 @@ -8646,7 +8676,6 @@ packages: /@sveltejs/package@2.0.2(svelte@3.59.1)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} - hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -9615,7 +9644,6 @@ packages: /@types/sass@1.45.0: resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==} - deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed. dependencies: sass: 1.63.3 dev: true @@ -9663,6 +9691,14 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true + /@types/strip-bom@3.0.0: + resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} + dev: true + + /@types/strip-json-comments@0.0.30: + resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} + dev: true + /@types/stripe-v3@3.1.28: resolution: {integrity: sha512-5poJyz1QFXpi1hE2bAWy7gFMdj5Fgofm94DNCaTK9V2LeWPdhCQIaP/6qUagZwgCcTURXzih1J7f3sjXH1cOsw==} dev: false @@ -10080,7 +10116,6 @@ packages: /@wessberg/ts-evaluator@0.0.27(typescript@4.9.5): resolution: {integrity: sha512-7gOpVm3yYojUp/Yn7F4ZybJRxyqfMNf0LXK5KJiawbPfL0XTsJV+0mgrEDjOIR6Bi0OYk2Cyg4tjFu1r8MCZaA==} engines: {node: '>=10.1.0'} - deprecated: this package has been renamed to ts-evaluator. Please install ts-evaluator instead peerDependencies: typescript: '>=3.2.x || >= 4.x' dependencies: @@ -10133,6 +10168,17 @@ packages: /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + + /abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + dev: false + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -10193,17 +10239,14 @@ packages: /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} - hasBin: true /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} - hasBin: true /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} - hasBin: true /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} @@ -10308,7 +10351,6 @@ packages: /ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} - hasBin: true /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -10367,6 +10409,10 @@ packages: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} dev: false + /archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + dev: false + /are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} @@ -10515,7 +10561,6 @@ packages: /astring@1.8.6: resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} - hasBin: true dev: false /async-each-series@0.1.1: @@ -10540,10 +10585,14 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10558,7 +10607,6 @@ packages: /autoprefixer@10.4.14(postcss@8.4.24): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10575,6 +10623,16 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} + /avvio@8.2.1: + resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==} + dependencies: + archy: 1.0.0 + debug: 4.3.4 + fastq: 1.15.0 + transitivePeerDependencies: + - supports-color + dev: false + /axe-core@4.7.2: resolution: {integrity: sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==} engines: {node: '>=4'} @@ -10928,7 +10986,6 @@ packages: /browser-sync@2.29.3: resolution: {integrity: sha512-NiM38O6XU84+MN+gzspVmXV2fTOoe+jBqIBx3IBdhZrdeURr6ZgznJr/p+hQ+KzkKEiGH/GcC4SQFSL0jV49bg==} engines: {node: '>= 8.0.0'} - hasBin: true dependencies: browser-sync-client: 2.29.3 browser-sync-ui: 2.29.3 @@ -10975,7 +11032,6 @@ packages: /browserslist@4.21.5: resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true dependencies: caniuse-lite: 1.0.30001499 electron-to-chromium: 1.4.427 @@ -10985,7 +11041,6 @@ packages: /browserslist@4.21.7: resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true dependencies: caniuse-lite: 1.0.30001499 electron-to-chromium: 1.4.427 @@ -11023,6 +11078,13 @@ packages: base64-js: 1.5.1 ieee754: 1.2.1 + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -11073,7 +11135,6 @@ packages: /c8@7.14.0: resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} engines: {node: '>=10.12.0'} - hasBin: true dependencies: '@bcoe/v8-coverage': 0.2.3 '@istanbuljs/schema': 0.1.3 @@ -11438,7 +11499,6 @@ packages: /color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true dev: true /colorette@2.0.20: @@ -11764,7 +11824,6 @@ packages: /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} - hasBin: true /cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} @@ -12092,7 +12151,6 @@ packages: /detect-port@1.5.1: resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} - hasBin: true dependencies: address: 1.2.2 debug: 4.3.4 @@ -12103,7 +12161,6 @@ packages: /dev-ip@1.0.1: resolution: {integrity: sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==} engines: {node: '>= 0.8.0'} - hasBin: true dev: false /devalue@4.3.2: @@ -12271,6 +12328,12 @@ packages: stream-shift: 1.0.1 dev: true + /dynamic-dedupe@0.3.0: + resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} + dependencies: + xtend: 4.0.2 + dev: true + /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true @@ -12297,7 +12360,6 @@ packages: /editorconfig@0.15.3: resolution: {integrity: sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==} - hasBin: true dependencies: commander: 2.20.3 lru-cache: 4.1.5 @@ -12311,7 +12373,6 @@ packages: /ejs@3.1.9: resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} engines: {node: '>=0.10.0'} - hasBin: true dependencies: jake: 10.8.7 dev: true @@ -12420,7 +12481,6 @@ packages: /envinfo@7.8.1: resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} engines: {node: '>=4'} - hasBin: true dev: true /err-code@2.0.3: @@ -12429,7 +12489,6 @@ packages: /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} - hasBin: true requiresBuild: true dependencies: prr: 1.0.1 @@ -12695,13 +12754,11 @@ packages: /esbuild-wasm@0.17.19: resolution: {integrity: sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==} engines: {node: '>=12'} - hasBin: true dev: true /esbuild-wasm@0.17.8: resolution: {integrity: sha512-zCmpxv95E0FuCmvdw1K836UHnj4EdiQnFfjTby35y3LAjRPtXMj3sbHDRHjbD8Mqg5lTwq3knacr/1qIFU51CQ==} engines: {node: '>=12'} - hasBin: true /esbuild-windows-32@0.15.18: resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} @@ -12733,7 +12790,6 @@ packages: /esbuild@0.15.18: resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.15.18 @@ -12763,7 +12819,6 @@ packages: /esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -12793,7 +12848,6 @@ packages: /esbuild@0.17.8: resolution: {integrity: sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==} engines: {node: '>=12'} - hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.17.8 @@ -12847,7 +12901,6 @@ packages: /escodegen@2.0.0: resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} engines: {node: '>=6.0'} - hasBin: true dependencies: esprima: 4.0.1 estraverse: 5.3.0 @@ -12933,7 +12986,6 @@ packages: /eslint-config-prettier@8.8.0(eslint@7.32.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} - hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -13344,7 +13396,6 @@ packages: /eslint@7.32.0: resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} engines: {node: ^10.12.0 || >=12.0.0} - hasBin: true dependencies: '@babel/code-frame': 7.12.11 '@eslint/eslintrc': 0.4.3 @@ -13392,7 +13443,6 @@ packages: /eslint@8.29.0: resolution: {integrity: sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true dependencies: '@eslint/eslintrc': 1.4.1 '@humanwhocodes/config-array': 0.11.10 @@ -13440,7 +13490,6 @@ packages: /eslint@8.4.1: resolution: {integrity: sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true dependencies: '@eslint/eslintrc': 1.4.1 '@humanwhocodes/config-array': 0.9.5 @@ -13487,7 +13536,6 @@ packages: /eslint@8.42.0: resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) '@eslint-community/regexpp': 4.5.1 @@ -13564,7 +13612,6 @@ packages: /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} - hasBin: true /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} @@ -13644,6 +13691,11 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + /eventemitter-asyncresource@1.0.0: resolution: {integrity: sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==} @@ -13769,7 +13821,6 @@ packages: /extract-zip@1.7.0: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} - hasBin: true dependencies: concat-stream: 1.6.2 debug: 2.6.9 @@ -13779,6 +13830,14 @@ packages: - supports-color dev: true + /fast-content-type-parse@1.0.0: + resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==} + dev: false + + /fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + dev: false + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -13799,13 +13858,66 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + /fast-json-stringify@5.7.0: + resolution: {integrity: sha512-sBVPTgnAZseLu1Qgj6lUbQ0HfjFhZWXAmpZ5AaSGkyLh5gAXBga/uPJjQPHpDFjC9adWIpdOcCLSDTgrZ7snoQ==} + dependencies: + '@fastify/deepmerge': 1.3.0 + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + fast-deep-equal: 3.1.3 + fast-uri: 2.2.0 + rfdc: 1.3.0 + dev: false + /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + /fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + dependencies: + fast-decode-uri-component: 1.0.1 + dev: false + + /fast-redact@3.2.0: + resolution: {integrity: sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==} + engines: {node: '>=6'} + dev: false + /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} dev: true + /fast-uri@2.2.0: + resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==} + dev: false + + /fastify-plugin@4.5.0: + resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==} + dev: false + + /fastify@4.19.2: + resolution: {integrity: sha512-2unheeIRWFf9/Jjcz7djOpKuXCTzZjlyFfiBwKqpldkHMN2rfTLu/f9pYTdwlhzC9Cdj0S2H12zlug0Kd5uZ1w==} + dependencies: + '@fastify/ajv-compiler': 3.5.0 + '@fastify/error': 3.3.0 + '@fastify/fast-json-stringify-compiler': 4.3.0 + abstract-logging: 2.0.1 + avvio: 8.2.1 + fast-content-type-parse: 1.0.0 + fast-json-stringify: 5.7.0 + find-my-way: 7.6.2 + light-my-request: 5.10.0 + pino: 8.14.1 + process-warning: 2.2.0 + proxy-addr: 2.0.7 + rfdc: 1.3.0 + secure-json-parse: 2.7.0 + semver: 7.5.1 + tiny-lru: 11.0.1 + transitivePeerDependencies: + - supports-color + dev: false + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -13932,6 +14044,15 @@ packages: make-dir: 3.1.0 pkg-dir: 4.2.0 + /find-my-way@7.6.2: + resolution: {integrity: sha512-0OjHn1b1nCX3eVbm9ByeEHiscPYiHLfhei1wOUU9qffQkk98wE0Lo8VrVYfSGMgnSnDh86DxedduAnBf4nwUEw==} + engines: {node: '>=14'} + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 2.0.0 + dev: false + /find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -14268,7 +14389,6 @@ packages: /giget@1.1.2: resolution: {integrity: sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==} - hasBin: true dependencies: colorette: 2.0.20 defu: 6.1.2 @@ -14478,7 +14598,6 @@ packages: /gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} - hasBin: true dependencies: browserify-zlib: 0.1.4 is-deflate: 1.0.0 @@ -14501,7 +14620,6 @@ packages: /handlebars@4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} engines: {node: '>=0.4.7'} - hasBin: true dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -14932,7 +15050,6 @@ packages: /image-size@0.5.5: resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} engines: {node: '>=0.10.0'} - hasBin: true requiresBuild: true optional: true @@ -15178,7 +15295,6 @@ packages: /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true dependencies: ci-info: 3.8.0 dev: true @@ -15205,12 +15321,10 @@ packages: /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} - hasBin: true /is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true dev: false /is-extendable@0.1.1: @@ -15258,7 +15372,6 @@ packages: /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} - hasBin: true dependencies: is-docker: 3.0.0 dev: false @@ -15565,7 +15678,6 @@ packages: /jake@10.8.7: resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} engines: {node: '>=10'} - hasBin: true dependencies: async: 3.2.4 chalk: 4.1.2 @@ -15681,7 +15793,6 @@ packages: /jiti@1.18.2: resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} - hasBin: true /jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} @@ -15699,7 +15810,6 @@ packages: /js-beautify@1.14.8: resolution: {integrity: sha512-4S7HFeI9YfRvRgKnEweohs0tgJj28InHVIj4Nl8Htf96Y6pHg3+tJrmo4ucAM9f7l4SHbFI3IvFAZ2a1eQPbyg==} engines: {node: '>=12'} - hasBin: true dependencies: config-chain: 1.1.13 editorconfig: 0.15.3 @@ -15731,20 +15841,17 @@ packages: /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true dependencies: argparse: 1.0.10 esprima: 4.0.1 /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true dependencies: argparse: 2.0.1 /jscodeshift@0.14.0(@babel/preset-env@7.21.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15774,7 +15881,6 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.22.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15928,12 +16034,10 @@ packages: /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} - hasBin: true /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -15954,14 +16058,12 @@ packages: /json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true dependencies: minimist: 1.2.8 /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} - hasBin: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -16083,7 +16185,6 @@ packages: /karma@6.4.2: resolution: {integrity: sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==} engines: {node: '>= 10'} - hasBin: true dependencies: '@colors/colors': 1.5.0 body-parser: 1.20.2 @@ -16117,7 +16218,6 @@ packages: /katex@0.16.7: resolution: {integrity: sha512-Xk9C6oGKRwJTfqfIbtr0Kes9OSv6IFsuhFGc7tW4urlpMJtuh+7YhzU6YEG9n8gmWKcMAFzkp7nr+r69kV0zrA==} - hasBin: true dependencies: commander: 8.3.0 dev: false @@ -16185,7 +16285,6 @@ packages: /less@4.1.3: resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} engines: {node: '>=6'} - hasBin: true dependencies: copy-anything: 2.0.6 parse-node-version: 1.0.1 @@ -16233,6 +16332,14 @@ packages: webpack: 5.76.1(esbuild@0.17.8) webpack-sources: 3.2.3 + /light-my-request@5.10.0: + resolution: {integrity: sha512-ZU2D9GmAcOUculTTdH9/zryej6n8TzT+fNGdNtm6SDp5MMMpHrJJkvAdE3c6d8d2chE9i+a//dS9CWZtisknqA==} + dependencies: + cookie: 0.5.0 + process-warning: 2.2.0 + set-cookie-parser: 2.6.0 + dev: false + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -16289,7 +16396,6 @@ packages: /localtunnel@2.0.2: resolution: {integrity: sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==} engines: {node: '>=8.3.0'} - hasBin: true dependencies: axios: 0.21.4(debug@4.3.2) debug: 4.3.2 @@ -16403,7 +16509,6 @@ packages: /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true dependencies: js-tokens: 4.0.0 @@ -16454,7 +16559,6 @@ packages: /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true dev: true /magic-string@0.25.9: @@ -16580,7 +16684,6 @@ packages: /markdown-it@13.0.1: resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} - hasBin: true dependencies: argparse: 2.0.1 entities: 3.0.1 @@ -16874,7 +16977,6 @@ packages: /micro@10.0.1: resolution: {integrity: sha512-9uwZSsUrqf6+4FLLpiPj5TRWQv5w5uJrJwsx1LR/TjqvQmKC1XnGQ9OHrFwR3cbZ46YqPqxO/XJCOpWnqMPw2Q==} engines: {node: '>= 16.0.0'} - hasBin: true dependencies: arg: 4.1.0 content-type: 1.0.4 @@ -17246,29 +17348,24 @@ packages: /mime@1.4.1: resolution: {integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==} - hasBin: true dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} - hasBin: true /mime@2.5.2: resolution: {integrity: sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==} engines: {node: '>=4.0.0'} - hasBin: true dev: true /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} - hasBin: true /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} - hasBin: true dev: true /mimic-fn@2.1.0: @@ -17296,7 +17393,6 @@ packages: /mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} - hasBin: true dev: true /minimalistic-assert@1.0.1: @@ -17435,7 +17531,6 @@ packages: /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true dependencies: minimist: 1.2.8 @@ -17492,7 +17587,6 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17528,7 +17622,6 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17563,7 +17656,6 @@ packages: /multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} - hasBin: true dependencies: dns-packet: 5.6.0 thunky: 1.1.0 @@ -17581,12 +17673,10 @@ packages: /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true /nanoid@4.0.2: resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} engines: {node: ^14 || ^16 || >=18} - hasBin: true dev: false /natural-compare-lite@1.4.0: @@ -17599,7 +17689,6 @@ packages: /needle@3.2.0: resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} engines: {node: '>= 4.4.x'} - hasBin: true requiresBuild: true dependencies: debug: 3.2.7(supports-color@5.5.0) @@ -17674,7 +17763,6 @@ packages: /next-sitemap@3.1.55(@next/env@13.4.5)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -17700,7 +17788,6 @@ packages: /next@13.3.4(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17744,7 +17831,6 @@ packages: /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17856,7 +17942,6 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.9)(tslib@2.5.3)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -17961,13 +18046,11 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} - hasBin: true optional: true /node-gyp@9.3.1: resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} engines: {node: ^12.13 || ^14.13 || >=16} - hasBin: true dependencies: env-paths: 2.2.1 glob: 7.2.3 @@ -17999,7 +18082,6 @@ packages: /nodemon@2.0.22: resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} engines: {node: '>=8.10.0'} - hasBin: true dependencies: chokidar: 3.5.3 debug: 3.2.7(supports-color@5.5.0) @@ -18015,7 +18097,6 @@ packages: /nopt@1.0.10: resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true dependencies: abbrev: 1.1.1 dev: true @@ -18023,7 +18104,6 @@ packages: /nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true dependencies: abbrev: 1.1.1 @@ -18098,7 +18178,6 @@ packages: /npm-packlist@5.1.3: resolution: {integrity: sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true dependencies: glob: 8.1.0 ignore-walk: 5.0.1 @@ -18298,6 +18377,10 @@ packages: engines: {node: ^10.13.0 || >=12.0.0} dev: false + /on-exit-leak-free@2.1.0: + resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==} + dev: false + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} @@ -18369,7 +18452,6 @@ packages: /opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} - hasBin: true dev: true /openid-client@5.4.2: @@ -18519,7 +18601,6 @@ packages: /pacote@15.1.0: resolution: {integrity: sha512-FFcjtIl+BQNfeliSm7MZz5cpdohvUV1yjGnqgVM4UnVF7JslRY0ImXAygdaCDV0jjUADEWu4y5xsDV8brtrTLg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true dependencies: '@npmcli/git': 4.1.0 '@npmcli/installed-package-contents': 2.0.2 @@ -18742,6 +18823,34 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + /pino-abstract-transport@1.0.0: + resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==} + dependencies: + readable-stream: 4.4.2 + split2: 4.2.0 + dev: false + + /pino-std-serializers@6.2.2: + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + dev: false + + /pino@8.14.1: + resolution: {integrity: sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.2.0 + on-exit-leak-free: 2.1.0 + pino-abstract-transport: 1.0.0 + pino-std-serializers: 6.2.2 + process-warning: 2.2.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 3.3.0 + thread-stream: 2.3.0 + dev: false + /pirates@4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} @@ -19019,7 +19128,6 @@ packages: /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} - hasBin: true dev: true /prettier@3.0.0: @@ -19071,7 +19179,6 @@ packages: /prisma@4.15.0: resolution: {integrity: sha512-iKZZpobPl48gTcSZVawLMQ3lEy6BnXwtoMj7hluoGFYu2kQ6F9LBuBrUyF95zRVnNo8/3KzLXJXJ5TEnLSJFiA==} engines: {node: '>=14.17'} - hasBin: true requiresBuild: true dependencies: '@prisma/engines': 4.15.0 @@ -19084,10 +19191,13 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + /process-warning@2.2.0: + resolution: {integrity: sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==} + dev: false + /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - dev: true /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} @@ -19310,7 +19420,6 @@ packages: /publint@0.1.12: resolution: {integrity: sha512-8LxkO430t/SOhUl0qXQWdXq34m6oyLcPhE4Kc8eXhOEnB82vCHcShPQ2kH53n/ksC7jWdRWDP7MPGxKJbntQfg==} engines: {node: '>=16'} - hasBin: true dependencies: npm-packlist: 5.1.3 picocolors: 1.0.0 @@ -19385,6 +19494,10 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -19662,6 +19775,17 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readable-stream@4.4.2: + resolution: {integrity: sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -19672,6 +19796,11 @@ packages: resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} dev: false + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: false + /recast@0.21.5: resolution: {integrity: sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==} engines: {node: '>= 4'} @@ -19768,7 +19897,6 @@ packages: /regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true dependencies: jsesc: 0.5.0 @@ -19919,7 +20047,6 @@ packages: /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -19959,6 +20086,11 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 + /ret@0.2.2: + resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} + engines: {node: '>=4'} + dev: false + /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -19991,14 +20123,12 @@ packages: /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true dependencies: glob: 7.2.3 /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} - hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -20006,7 +20136,6 @@ packages: /rollup@3.25.0: resolution: {integrity: sha512-FnJkNRst2jEZGw7f+v4hFo6UTzpDKrAKcHZWcEfm5/GJQ5CK7wgb4moNLNAe7npKUev7yQn1AY/YbZRIxOv6Qg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true optionalDependencies: fsevents: 2.3.2 dev: true @@ -20069,6 +20198,17 @@ packages: get-intrinsic: 1.2.1 is-regex: 1.1.4 + /safe-regex2@2.0.0: + resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} + dependencies: + ret: 0.2.2 + dev: false + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -20108,7 +20248,6 @@ packages: /sass@1.58.1: resolution: {integrity: sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==} engines: {node: '>=12.0.0'} - hasBin: true dependencies: chokidar: 3.5.3 immutable: 4.3.0 @@ -20117,7 +20256,6 @@ packages: /sass@1.63.3: resolution: {integrity: sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==} engines: {node: '>=14.0.0'} - hasBin: true dependencies: chokidar: 3.5.3 immutable: 4.3.0 @@ -20177,6 +20315,10 @@ packages: kind-of: 6.0.3 dev: false + /secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + dev: false + /selderee@0.10.0: resolution: {integrity: sha512-DEL/RW/f4qLw/NrVg97xKaEBC8IpzIG2fvxnzCp3Z4yk4jQ3MXom+Imav9wApjxX2dfS3eW7x0DXafJr85i39A==} dependencies: @@ -20194,7 +20336,6 @@ packages: /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} @@ -20208,7 +20349,6 @@ packages: /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} - hasBin: true dependencies: lru-cache: 6.0.0 @@ -20323,7 +20463,6 @@ packages: /set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - dev: true /setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} @@ -20364,7 +20503,6 @@ packages: /shelljs@0.8.5: resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} engines: {node: '>=4'} - hasBin: true dependencies: glob: 7.2.3 interpret: 1.4.0 @@ -20422,7 +20560,6 @@ packages: /sigstore@1.6.0: resolution: {integrity: sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true dependencies: '@sigstore/protobuf-specs': 0.1.0 '@sigstore/tuf': 1.0.0 @@ -20485,7 +20622,6 @@ packages: /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} - hasBin: true dependencies: array.prototype.flat: 1.3.1 breakword: 1.0.6 @@ -20567,9 +20703,14 @@ packages: smart-buffer: 4.2.0 dev: true + /sonic-boom@3.3.0: + resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + /sorcery@0.10.0: resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==} - hasBin: true dependencies: buffer-crc32: 0.2.13 minimist: 1.2.8 @@ -20622,7 +20763,6 @@ packages: /sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead dev: true /space-separated-tokens@1.1.5: @@ -20686,6 +20826,11 @@ packages: transitivePeerDependencies: - supports-color + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: false + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -20755,7 +20900,6 @@ packages: /storybook@7.0.20: resolution: {integrity: sha512-QxMdqeY7oigiwnVqVPp8550CUtfWW5fujkVXUhgyI1u4i9dpmJxkxWRvfSvhGKAvHf0n2BZ550SevZRPrCr+Tg==} - hasBin: true dependencies: '@storybook/cli': 7.0.20 transitivePeerDependencies: @@ -20772,7 +20916,6 @@ packages: /stream-throttle@0.1.3: resolution: {integrity: sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==} engines: {node: '>= 0.10.0'} - hasBin: true dependencies: commander: 2.20.3 limiter: 1.1.5 @@ -20924,6 +21067,11 @@ packages: min-indent: 1.0.1 dev: true + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -20968,7 +21116,6 @@ packages: /sucrase@3.32.0: resolution: {integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==} engines: {node: '>=8'} - hasBin: true dependencies: '@jridgewell/gen-mapping': 0.3.3 commander: 4.1.1 @@ -21044,7 +21191,6 @@ packages: /svelte-check@2.10.3(@babel/core@7.22.5)(svelte@3.59.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} - hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -21207,7 +21353,6 @@ packages: /tailwindcss@3.3.2(ts-node@10.9.1): resolution: {integrity: sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==} engines: {node: '>=14.0.0'} - hasBin: true dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -21331,7 +21476,6 @@ packages: /terser@5.16.3: resolution: {integrity: sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==} engines: {node: '>=10'} - hasBin: true dependencies: '@jridgewell/source-map': 0.3.3 acorn: 8.10.0 @@ -21341,7 +21485,6 @@ packages: /terser@5.17.7: resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==} engines: {node: '>=10'} - hasBin: true dependencies: '@jridgewell/source-map': 0.3.3 acorn: 8.10.0 @@ -21370,6 +21513,12 @@ packages: dependencies: any-promise: 1.3.0 + /thread-stream@2.3.0: + resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==} + dependencies: + real-require: 0.2.0 + dev: false + /throttle-debounce@3.0.1: resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} engines: {node: '>=10'} @@ -21400,6 +21549,11 @@ packages: globrex: 0.1.2 dev: true + /tiny-lru@11.0.1: + resolution: {integrity: sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==} + engines: {node: '>=12'} + dev: false + /tinybench@2.5.0: resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} dev: true @@ -21432,7 +21586,6 @@ packages: /title@3.5.3: resolution: {integrity: sha512-20JyowYglSEeCvZv3EZ0nZ046vLarO37prvV0mbtQV7C8DJPGgN967r8SJkqd3XK3K3lD3/Iyfp3avjfil8Q2Q==} - hasBin: true dependencies: arg: 1.0.0 chalk: 2.3.0 @@ -21497,7 +21650,6 @@ packages: /touch@3.1.0: resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} - hasBin: true dependencies: nopt: 1.0.10 dev: true @@ -21535,7 +21687,6 @@ packages: /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -21565,9 +21716,36 @@ packages: code-block-writer: 12.0.0 dev: true + /ts-node-dev@2.0.0(@types/node@20.3.0)(typescript@5.0.4): + resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} + engines: {node: '>=0.8.0'} + hasBin: true + peerDependencies: + node-notifier: '*' + typescript: '*' + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + chokidar: 3.5.3 + dynamic-dedupe: 0.3.0 + minimist: 1.2.8 + mkdirp: 1.0.4 + resolve: 1.22.2 + rimraf: 2.7.1 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + ts-node: 10.9.1(@types/node@20.3.0)(typescript@5.0.4) + tsconfig: 7.0.0 + typescript: 5.0.4 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + dev: true + /ts-node@10.9.1(@types/node@18.16.17)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21597,7 +21775,6 @@ packages: /ts-node@10.9.1(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21650,6 +21827,15 @@ packages: strip-bom: 3.0.0 dev: true + /tsconfig@7.0.0: + resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} + dependencies: + '@types/strip-bom': 3.0.0 + '@types/strip-json-comments': 0.0.30 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + dev: true + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -21662,7 +21848,6 @@ packages: /tsup@6.7.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -21717,7 +21902,6 @@ packages: /tty-table@4.2.1: resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} engines: {node: '>=8.0.0'} - hasBin: true dependencies: chalk: 4.1.2 csv: 5.5.3 @@ -21878,18 +22062,15 @@ packages: /typescript@4.9.3: resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} engines: {node: '>=4.2.0'} - hasBin: true dev: false /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} - hasBin: true /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} - hasBin: true dev: true /ua-parser-js@0.7.35: @@ -21910,7 +22091,6 @@ packages: /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} - hasBin: true requiresBuild: true dev: true optional: true @@ -22144,7 +22324,6 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22154,7 +22333,6 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.7): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22242,17 +22420,14 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true dev: true /uvu@0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} - hasBin: true dependencies: dequal: 2.0.3 diff: 5.1.0 @@ -22332,7 +22507,6 @@ packages: /vite-node@0.31.4(@types/node@18.16.17): resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} engines: {node: '>=v14.18.0'} - hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 @@ -22376,7 +22550,6 @@ packages: /vite@3.2.7: resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22409,7 +22582,6 @@ packages: /vite@4.3.9(@types/node@18.16.17): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22442,7 +22614,6 @@ packages: /vite@4.3.9(@types/node@20.3.0): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22486,7 +22657,6 @@ packages: /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22532,7 +22702,6 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22616,7 +22785,6 @@ packages: /w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} - deprecated: Use your platform's native performance.now() and performance.timeOrigin. dependencies: browser-process-hrtime: 1.0.0 dev: false @@ -22702,7 +22870,6 @@ packages: /webpack-bundle-analyzer@4.7.0: resolution: {integrity: sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==} engines: {node: '>= 10.13.0'} - hasBin: true dependencies: acorn: 8.8.2 acorn-walk: 8.2.0 @@ -22747,7 +22914,6 @@ packages: /webpack-dev-server@4.11.1(webpack@5.76.1): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} - hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -22830,7 +22996,6 @@ packages: /webpack@5.76.1(esbuild@0.17.8): resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} - hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: @@ -22979,21 +23144,18 @@ packages: /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true dependencies: isexe: 2.0.0 /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} - hasBin: true dependencies: isexe: 2.0.0 /which@3.0.1: resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true dependencies: isexe: 2.0.0 dev: true @@ -23001,7 +23163,6 @@ packages: /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} - hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 @@ -23293,7 +23454,6 @@ packages: /z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} - hasBin: true dependencies: lodash.get: 4.4.2 lodash.isequal: 4.5.0 From 619d24fa5ac8dfca8724f0eb1b4f2cd7a634d14c Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:36:02 +0200 Subject: [PATCH 54/68] fix tests --- .../src/express/abbyMiddlewareFactory.ts | 7 +- .../nodejs/src/fastify/fastifyHookFactory.ts | 27 ++++- packages/nodejs/src/tests/abby.test.ts | 95 +++++++-------- packages/nodejs/src/tests/abbyExpress.test.ts | 13 ++- packages/nodejs/src/tests/mocks/handlers.ts | 109 +++++++++--------- 5 files changed, 138 insertions(+), 113 deletions(-) diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index dfc0a0ec..a37aafdd 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -35,14 +35,11 @@ export const abbyMiddlewareFactory = < name: F, req: Request, res: Response, - next: NextFunction, - deciderFunction: (req: Request, flagValue: any) => boolean + next: NextFunction ) => { const flagValue = abbyNodeInstance.getFeatureFlagValue(name as unknown as FlagName); //TODO fix type - console.log(flagValue); - const decision = deciderFunction(req, flagValue); - console.log(decision); + const decision = flagValue; if (!decision) { res.status(403).json("errorMessage"); return; diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index 71541787..e9797f5a 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -27,13 +27,27 @@ export const abbyFastifyFactory = < done: HookHandlerDoneFunction ) => { const flagValue = abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); //TODO fix type - if (!flagValue) { - reply.status(403).send(); + if (flagValue) { + reply.status(403); + reply.send(); console.log("disbaled endpoint"); return; } done(); }; + + /** + * helper function to extract a single test + * @param name + * @returns + */ + + const extractTest = (name: T): any => { + const variant = abbyNodeInstance.getABTestValue(name); + console.log(name, variant); + return { name, variant }; + }; + /** * hook to parse all ab values on the request object needs to be used at the top */ @@ -42,7 +56,14 @@ export const abbyFastifyFactory = < request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction - ) => {}; + ) => { + if (configNarrowed.tests) { + const allTests = Object.keys(configNarrowed.tests) as T[]; + allTests.map((test) => { + return extractTest(test); + }); + } + }; const getFlagValue = (key: F) => { return abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index 5eed0df9..442a8857 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -1,47 +1,50 @@ -import { expect, test, describe } from 'vitest'; -import { createAbby } from '../abby/createAbby.ts'; - -describe('it works', () => { - test('getFeatureFlagValue working', async () => { - const { getFeatureFlagValue } = await createAbby({ - projectId: '123', - tests: {}, - flags: ['flag1', 'flag2'] - }); - - expect(await getFeatureFlagValue('flag1')).toBeTruthy(); - expect(await getFeatureFlagValue('flag2')).toBeFalsy(); - }); - - test('it returns a correct variant', async () => { - const variants = ['A', 'B', 'C', 'D']; - const { getABTestValue } = await createAbby({ - projectId: '123', - tests: { - test: { - variants - } - } - }); - - const variant = getABTestValue('test'); - - expect(variant).toContain(variant); - }); - - test('it returns a correct variant with respect to the weights', async () => { - const variants = ['A', 'B']; - const { getABTestValue } = await createAbby({ - projectId: '123', - tests: { - test2: { - variants - } - } - }); - - const variant = getABTestValue('test2'); - - expect(variant).toBe('A'); - }); +import { expect, test, describe } from "vitest"; +import { createAbby } from "../abby/createAbby"; + +describe("it works", () => { + test("getFeatureFlagValue working", async () => { + const { getFeatureFlagValue } = createAbby({ + projectId: "123", + tests: {}, + flags: { + flag1: "String", + flag2: "Boolean", + }, + }); + + expect(await getFeatureFlagValue("flag1")).toBeTruthy(); + expect(await getFeatureFlagValue("flag2")).toBeFalsy(); + }); + + test("it returns a correct variant", async () => { + const variants = ["A", "B", "C", "D"]; + const { getABTestValue } = await createAbby({ + projectId: "123", + tests: { + test: { + variants, + }, + }, + }); + + const variant = getABTestValue("test"); + + expect(variant).toContain(variant); + }); + + test("it returns a correct variant with respect to the weights", async () => { + const variants = ["A", "B"]; + const { getABTestValue } = createAbby({ + projectId: "123", + tests: { + test2: { + variants, + }, + }, + }); + + const variant = getABTestValue("test2"); + + expect(variant).toBe("A"); + }); }); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 88788414..288605f8 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -7,7 +7,7 @@ describe("express middleware working", () => { let app: express.Application; beforeAll(async () => { - const { AbTestMiddleware, featureFlagMiddleware } = await abbyMiddlewareFactory({ + const { allTestsMiddleWare, featureFlagMiddleware, getVariant } = await abbyMiddlewareFactory({ abbyConfig: { projectId: "123", currentEnvironment: process.env.NODE_ENV, @@ -19,7 +19,10 @@ describe("express middleware working", () => { variants: ["A", "B"], }, }, - flags: ["flag1", "flag2"], + flags: { + flag1: "String", + flag2: "Boolean", + }, }, }); @@ -34,9 +37,9 @@ describe("express middleware working", () => { app.get("/featureFlag/Enabled", (req, res) => res.send("")); app.get("/featureFlag/Disabled", (req, res) => res.send("")); - app.use("/cookie", (req, res, next) => AbTestMiddleware("test2", req, res, next)); + app.use("/cookie", (req, res, next) => allTestsMiddleWare(req, res, next)); app.get("/cookie/notSet", (req, res) => { - const variant = req.body.ABBY; + const variant = getVariant("test2"); if (variant) { res.send(variant); return; @@ -70,6 +73,6 @@ describe("express middleware working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(app).get("/cookie/Set"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - expect(cookies[0]).toBe("__abby__ab__123_test2=A; Path=/"); + expect(cookies[1]).toBe("__abby__ab__123_test2=A; Path=/"); }); }); diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts index 4bd16651..1e700ce3 100644 --- a/packages/nodejs/src/tests/mocks/handlers.ts +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -1,58 +1,59 @@ -import { rest } from 'msw'; -import { type AbbyDataResponse, ABBY_BASE_URL } from '@tryabby/core'; +import { rest } from "msw"; +import { type AbbyDataResponse, ABBY_BASE_URL } from "@tryabby/core"; export const handlers = [ - rest.get(`${ABBY_BASE_URL}api/dashboard/123/data`, (req, res, ctx) => { - return res( - ctx.json({ - tests: [ - { - name: 'test', - weights: [1, 1, 1, 1] - }, - { - name: 'test2', - weights: [1, 0] - } - ], - flags: [ - { - name: 'flag1', - isEnabled: true - }, - { - name: 'flag2', - isEnabled: false - } - ] - } as AbbyDataResponse) - ); - }), + rest.get(`${ABBY_BASE_URL}api/v1/data/123`, (req, res, ctx) => { + console.log("handler"); + return res( + ctx.json({ + tests: [ + { + name: "test", + weights: [1, 1, 1, 1], + }, + { + name: "test2", + weights: [1, 0], + }, + ], + flags: [ + { + name: "flag1", + value: true, + }, + { + name: "flag2", + value: false, + }, + ], + } as AbbyDataResponse) + ); + }), - rest.get(`${ABBY_BASE_URL}api/dashboard/clfn3hs1t0002kx08x3kidi80/data`, (req, res, ctx) => { - return res( - ctx.json({ - tests: [ - { - name: 'test', - weights: [1, 1, 1, 1] - }, - { - name: 'test2', - weights: [1, 0] - } - ], - flags: [ - { - name: 'lol', - isEnabled: true - }, - { - name: 'test3', - isEnabled: false - } - ] - } as AbbyDataResponse) - ); - }) + rest.get(`${ABBY_BASE_URL}api/dashboard/clfn3hs1t0002kx08x3kidi80/data`, (req, res, ctx) => { + return res( + ctx.json({ + tests: [ + { + name: "test", + weights: [1, 1, 1, 1], + }, + { + name: "test2", + weights: [1, 0], + }, + ], + flags: [ + { + name: "lol", + value: true, + }, + { + name: "test3", + value: false, + }, + ], + } as AbbyDataResponse) + ); + }), ]; From c784e8c6a378a7b89d8e2024d809772a8c4c93d9 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:12:24 +0200 Subject: [PATCH 55/68] tests for fastify wip --- .../nodejs/src/fastify/fastifyHookFactory.ts | 2 +- packages/nodejs/src/shared/StorageService.ts | 2 +- packages/nodejs/src/tests/abbyExpress.test.ts | 2 +- packages/nodejs/src/tests/abbyFastify.test.ts | 72 +++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 packages/nodejs/src/tests/abbyFastify.test.ts diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index e9797f5a..8d26b96f 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -52,7 +52,6 @@ export const abbyFastifyFactory = < * hook to parse all ab values on the request object needs to be used at the top */ const ABTestHook = ( - key: T, request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction @@ -63,6 +62,7 @@ export const abbyFastifyFactory = < return extractTest(test); }); } + done(); }; const getFlagValue = (key: F) => { diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index e0082dd3..16d8c98c 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -21,7 +21,7 @@ class ABStorageService implements IStorageService { } const cookieKey = getABStorageKey(projectId, key); console.log("cookie Service"); - response.cookie(cookieKey, value); + response.cookie(cookieKey, value); //TODO find a way to handle fastify and express cookies } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 288605f8..e86b06a2 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -1,7 +1,7 @@ import { expect, test, describe, beforeAll } from "vitest"; import express from "express"; import request from "supertest"; -import { abbyMiddlewareFactory } from "../express/abbyMiddlewareFactory.ts"; +import { abbyMiddlewareFactory } from "../express/abbyMiddlewareFactory"; describe("express middleware working", () => { let app: express.Application; diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts new file mode 100644 index 00000000..6c988ce6 --- /dev/null +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -0,0 +1,72 @@ +import { expect, test, describe, beforeAll } from "vitest"; +import Fastify, { FastifyInstance } from "fastify"; +import { abbyFastifyFactory } from "../fastify/fastifyHookFactory"; +import request from "supertest"; + +describe("fastify working", () => { + let fastify: FastifyInstance; + beforeAll(() => { + const { getTestValue, ABTestHook } = abbyFastifyFactory({ + abbyConfig: { + projectId: "123", + currentEnvironment: process.env.NODE_ENV, + tests: { + test: { + variants: ["A", "B", "C", "D"], + }, + test2: { + variants: ["A", "B"], + }, + }, + flags: { + flag1: "String", + flag2: "Boolean", + }, + }, + }); + + fastify = Fastify(); + + // fastify.register(require("@fastify/cookie"), { + // secret: "my-secret", // for cookies signature + // hook: "onRequest", // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest' + // parseOptions: {}, // options for parsing cookies + // }); + + // fastify.addHook("onRequest", (request, reply, done) => { + // ABTestHook(request, reply, done); + // }); + + fastify.get("/", function (request, reply) { + reply.send("Hello world!"); + }); + fastify.get("/cookie/notSet", (request, reply) => { + const variant = getTestValue("test2"); + reply.send(variant); + }); + }); + + test("featureFlag middleware", async () => { + await fastify.ready(); + const res = await request(fastify.server).get("/"); + console.log(res.statusCode); + }); + + // test("abTestMiddleware respects the set cookie", async () => { + // const cookieVariant = "D"; + // //test cookie retrieval + // const response = await request(fastify.server) + // .get("/cookie/notSet") + // .set("Cookie", [`__abby__ab__123_test2=${cookieVariant}; Path=/`]); + + // expect(response.text).toBe(cookieVariant); + // }); + + // test("abTestMiddleware sets the right cookie", async () => { + // const res = await request(fastify.server).get("/cookie/notSet"); + // console.log("response:", res.text); + // const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull + // console.log(cookies); + // expect(cookies[1]).toBe("__abby__ab__123_test2=A; Path=/"); + // }); +}); From 0f93096ae5b71ab60c48232f03e8b86cc55b82e1 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:29:54 +0200 Subject: [PATCH 56/68] fix basic tests --- packages/nodejs/package.json | 1 + packages/nodejs/src/tests/abby.test.ts | 9 +++- packages/nodejs/src/tests/abbyFastify.test.ts | 5 +- pnpm-lock.yaml | 52 +++++++++++++++---- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index c53ea6d7..495ce3ab 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -45,6 +45,7 @@ "@types/jest": "^29.5.1", "@types/node": "^20.2.5", "@types/supertest": "^2.0.12", + "flush-promises": "^1.0.2", "install": "^0.13.0", "msw": "^0.49.1", "node-fetch": "^3.3.1", diff --git a/packages/nodejs/src/tests/abby.test.ts b/packages/nodejs/src/tests/abby.test.ts index 442a8857..9e8c7ea0 100644 --- a/packages/nodejs/src/tests/abby.test.ts +++ b/packages/nodejs/src/tests/abby.test.ts @@ -1,5 +1,6 @@ import { expect, test, describe } from "vitest"; import { createAbby } from "../abby/createAbby"; +import flushPromises from "flush-promises"; describe("it works", () => { test("getFeatureFlagValue working", async () => { @@ -7,11 +8,14 @@ describe("it works", () => { projectId: "123", tests: {}, flags: { - flag1: "String", + flag1: "Boolean", flag2: "Boolean", }, }); + //await abbyInstance initialisation + await flushPromises(); + expect(await getFeatureFlagValue("flag1")).toBeTruthy(); expect(await getFeatureFlagValue("flag2")).toBeFalsy(); }); @@ -43,6 +47,9 @@ describe("it works", () => { }, }); + //await abbyInstance initialisation + await flushPromises(); + const variant = getABTestValue("test2"); expect(variant).toBe("A"); diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts index 6c988ce6..f733ab6d 100644 --- a/packages/nodejs/src/tests/abbyFastify.test.ts +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -40,8 +40,9 @@ describe("fastify working", () => { fastify.get("/", function (request, reply) { reply.send("Hello world!"); }); - fastify.get("/cookie/notSet", (request, reply) => { + fastify.get("/cookie/Set", (request, reply) => { const variant = getTestValue("test2"); + console.log(variant); reply.send(variant); }); }); @@ -56,7 +57,7 @@ describe("fastify working", () => { // const cookieVariant = "D"; // //test cookie retrieval // const response = await request(fastify.server) - // .get("/cookie/notSet") + // .get("/cookie/Set") // .set("Cookie", [`__abby__ab__123_test2=${cookieVariant}; Path=/`]); // expect(response.text).toBe(cookieVariant); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37212f44..7b7ca912 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -678,7 +678,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@20.3.0) + version: 4.3.9(@types/node@18.16.17) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -805,6 +805,9 @@ importers: '@types/supertest': specifier: ^2.0.12 version: 2.0.12 + flush-promises: + specifier: ^1.0.2 + version: 1.0.2 install: specifier: ^0.13.0 version: 0.13.0 @@ -995,7 +998,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@20.3.0) + version: 4.3.9(@types/node@18.16.17) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -1400,6 +1403,7 @@ packages: /@angular/compiler-cli@15.2.9(@angular/compiler@15.2.9)(typescript@4.9.5): resolution: {integrity: sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler': 15.2.9 typescript: '>=4.8.2 <5.0' @@ -8170,7 +8174,7 @@ packages: remark-slug: 6.1.0 rollup: 3.25.0 typescript: 4.9.5 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8555,7 +8559,7 @@ packages: svelte: 3.59.1 sveltedoc-parser: 4.2.1 ts-dedent: 2.2.0 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - '@preact/preset-vite' - supports-color @@ -8649,6 +8653,7 @@ packages: /@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9): resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==} engines: {node: ^16.14 || >=18} + hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 @@ -8668,7 +8673,7 @@ packages: svelte: 3.59.1 tiny-glob: 0.2.9 undici: 5.22.1 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8676,6 +8681,7 @@ packages: /@sveltejs/package@2.0.2(svelte@3.59.1)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} + hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -8699,7 +8705,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.1(svelte@3.59.1)(vite@4.3.9) debug: 4.3.4 svelte: 3.59.1 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8718,7 +8724,7 @@ packages: magic-string: 0.30.0 svelte: 3.59.1 svelte-hmr: 0.15.2(svelte@3.59.1) - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) vitefu: 0.2.4(vite@4.3.9) transitivePeerDependencies: - supports-color @@ -10593,6 +10599,7 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10607,6 +10614,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.24): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -12986,6 +12994,7 @@ packages: /eslint-config-prettier@8.8.0(eslint@7.32.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -14100,6 +14109,10 @@ packages: engines: {node: '>=0.4.0'} dev: true + /flush-promises@1.0.2: + resolution: {integrity: sha512-G0sYfLQERwKz4+4iOZYQEZVpOt9zQrlItIxQAAYAWpfby3gbHrx0osCHz5RLl/XoXevXk0xoN4hDFky/VV9TrA==} + dev: true + /focus-trap@7.4.3: resolution: {integrity: sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==} dependencies: @@ -15852,6 +15865,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15881,6 +15895,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.22.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -17587,6 +17602,7 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17622,6 +17638,7 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17763,6 +17780,7 @@ packages: /next-sitemap@3.1.55(@next/env@13.4.5)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -17788,6 +17806,7 @@ packages: /next@13.3.4(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17831,6 +17850,7 @@ packages: /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17942,6 +17962,7 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.9)(tslib@2.5.3)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -21191,6 +21212,7 @@ packages: /svelte-check@2.10.3(@babel/core@7.22.5)(svelte@3.59.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -21746,6 +21768,7 @@ packages: /ts-node@10.9.1(@types/node@18.16.17)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21775,6 +21798,7 @@ packages: /ts-node@10.9.1(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21848,6 +21872,7 @@ packages: /tsup@6.7.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -22324,6 +22349,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22333,6 +22359,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.7): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22540,7 +22567,7 @@ packages: kolorist: 1.8.0 magic-string: 0.29.0 ts-morph: 18.0.0 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - '@types/node' - rollup @@ -22550,6 +22577,7 @@ packages: /vite@3.2.7: resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22582,6 +22610,7 @@ packages: /vite@4.3.9(@types/node@18.16.17): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22614,6 +22643,7 @@ packages: /vite@4.3.9(@types/node@20.3.0): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22651,12 +22681,13 @@ packages: vite: optional: true dependencies: - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) dev: true /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22702,6 +22733,7 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22914,6 +22946,7 @@ packages: /webpack-dev-server@4.11.1(webpack@5.76.1): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} + hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -22996,6 +23029,7 @@ packages: /webpack@5.76.1(esbuild@0.17.8): resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} + hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: From 2082531f46b269a4959c78851b26be0d5db3c31d Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:35:48 +0200 Subject: [PATCH 57/68] fix build --- packages/nodejs/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 1889f700..23af4382 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -43,7 +43,7 @@ const deciderFunc = (req: Request, flagVal: any) => { return decision; }; -app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next, deciderFunc)); +app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next)); app.get("/", async (req, res) => { const variant = getVariant("New Test3"); From 85b55a00711217f70eddb5a3dd9493692931e7ab Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:39:42 +0200 Subject: [PATCH 58/68] remove console.log --- packages/nodejs/src/abby/contexts/requestContext.ts | 1 - packages/nodejs/src/abby/createAbby.ts | 2 -- packages/nodejs/src/shared/StorageService.ts | 2 -- packages/nodejs/src/tests/abbyFastify.test.ts | 4 ++-- packages/nodejs/src/tests/mocks/handlers.ts | 1 - packages/nodejs/src/tests/setup.ts | 2 +- 6 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/nodejs/src/abby/contexts/requestContext.ts b/packages/nodejs/src/abby/contexts/requestContext.ts index 560d8486..61ca0bb9 100644 --- a/packages/nodejs/src/abby/contexts/requestContext.ts +++ b/packages/nodejs/src/abby/contexts/requestContext.ts @@ -7,7 +7,6 @@ type RequestType = Request | FastifyRequest | null; let req: RequestType = null; export function setRequest(request: RequestType) { - console.log("setRequest"); req = request; } diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index d8496cef..fb831015 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -11,11 +11,9 @@ export function createAbby< >(abbyConfig: F.Narrow>) { const abbyCoreInstance = new Abby(abbyConfig, { get: (key: string) => { - console.log("getStore"); return TestStorageService.get(abbyConfig.projectId, key); }, set: (key: string, value: any) => { - console.log("set"); TestStorageService.set(abbyConfig.projectId, key, value); }, }); diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index 16d8c98c..ee46a06b 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -16,11 +16,9 @@ class ABStorageService implements IStorageService { set(projectId: string, key: string, value: string): void { const response = getResponse(); if (!response) { - console.log("return;"); return; } const cookieKey = getABStorageKey(projectId, key); - console.log("cookie Service"); response.cookie(cookieKey, value); //TODO find a way to handle fastify and express cookies } remove(projectId: string, key: string): void { diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts index f733ab6d..6c1d551b 100644 --- a/packages/nodejs/src/tests/abbyFastify.test.ts +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -37,7 +37,7 @@ describe("fastify working", () => { // ABTestHook(request, reply, done); // }); - fastify.get("/", function (request, reply) { + fastify.get("/fastify", function (request, reply) { reply.send("Hello world!"); }); fastify.get("/cookie/Set", (request, reply) => { @@ -49,7 +49,7 @@ describe("fastify working", () => { test("featureFlag middleware", async () => { await fastify.ready(); - const res = await request(fastify.server).get("/"); + const res = await request(fastify.server).get("/fastify"); console.log(res.statusCode); }); diff --git a/packages/nodejs/src/tests/mocks/handlers.ts b/packages/nodejs/src/tests/mocks/handlers.ts index 1e700ce3..8c2bf207 100644 --- a/packages/nodejs/src/tests/mocks/handlers.ts +++ b/packages/nodejs/src/tests/mocks/handlers.ts @@ -3,7 +3,6 @@ import { type AbbyDataResponse, ABBY_BASE_URL } from "@tryabby/core"; export const handlers = [ rest.get(`${ABBY_BASE_URL}api/v1/data/123`, (req, res, ctx) => { - console.log("handler"); return res( ctx.json({ tests: [ diff --git a/packages/nodejs/src/tests/setup.ts b/packages/nodejs/src/tests/setup.ts index e1c80da3..7d98bb7e 100644 --- a/packages/nodejs/src/tests/setup.ts +++ b/packages/nodejs/src/tests/setup.ts @@ -11,7 +11,7 @@ beforeAll(() => server.listen({ onUnhandledRequest(req) { //requests to express should not be intercepted and there should be no warning - const excludedRoutes = ["/cookie", "/featureFlag"]; + const excludedRoutes = ["/cookie", "/featureFlag", "/fastify"]; const routeIsExcluded = excludedRoutes.some((route) => req.url.pathname.includes(route)); if (routeIsExcluded) { return; From c2c6c4da08df74643c29daf724b976b6eb95f5fa Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:41:17 +0200 Subject: [PATCH 59/68] enable setCookie for express AND fastify --- packages/nodejs/src/shared/StorageService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index ee46a06b..340dfad8 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -19,7 +19,9 @@ class ABStorageService implements IStorageService { return; } const cookieKey = getABStorageKey(projectId, key); - response.cookie(cookieKey, value); //TODO find a way to handle fastify and express cookies + const cookie = `${cookieKey}=${value}`; + response.header("set-cookie", cookie); + // response.cookie(cookieKey, value); //TODO find a way to handle fastify and express cookies } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); From f0f9438573ed2fb30023fa60bf7d6f33d5ea4d2c Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:37:39 +0200 Subject: [PATCH 60/68] finish tests for fastify --- .../nodejs/src/fastify/fastifyHookFactory.ts | 15 ++++++- packages/nodejs/src/fastify/index.ts | 2 - packages/nodejs/src/index.ts | 9 ----- packages/nodejs/src/tests/abbyExpress.test.ts | 2 +- packages/nodejs/src/tests/abbyFastify.test.ts | 40 +++++++++---------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index 8d26b96f..0b5850d9 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -1,7 +1,8 @@ import { ABConfig, FlagValueString, AbbyConfig } from "@tryabby/core"; import { F } from "ts-toolbelt"; import { createAbby } from "../abby/createAbby"; -import { abby } from "./createAbby"; +import { setRequest } from "../abby/contexts/requestContext"; +import { setResponse } from "../abby/contexts/responseContext"; import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; export const abbyFastifyFactory = < @@ -44,10 +45,19 @@ export const abbyFastifyFactory = < const extractTest = (name: T): any => { const variant = abbyNodeInstance.getABTestValue(name); - console.log(name, variant); return { name, variant }; }; + /** + * helperfunction to setup the context + * @param req + * @param res + */ + const setRequestResponse = (req: FastifyRequest, res: FastifyReply): void => { + setRequest(req); + setResponse(res); + }; + /** * hook to parse all ab values on the request object needs to be used at the top */ @@ -57,6 +67,7 @@ export const abbyFastifyFactory = < done: HookHandlerDoneFunction ) => { if (configNarrowed.tests) { + setRequestResponse(request, reply); const allTests = Object.keys(configNarrowed.tests) as T[]; allTests.map((test) => { return extractTest(test); diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index 08b89d67..150c9545 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -45,10 +45,8 @@ fastify.addHook("onRequest", async (request, reply, done) => { const port = 3000; console.log("start fastify"); fastify.get("/", function (request, reply) { - console.log(parseCookies(request)); setRequest(request); setResponse(reply); - console.log(abby.getABTestValue("New Test3")); reply.send("Hello world!"); }); diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 23af4382..f5a80797 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -31,18 +31,9 @@ const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = abbyMiddleware app.use(express.json()); app.use("/", (req, res, next) => { - console.log(req.body); allTestsMiddleWare(req, res, next); }); -const deciderFunc = (req: Request, flagVal: any) => { - const countryOfOrigin = req.body.country; - if (!countryOfOrigin) return false; - const decision = flagVal.enabledCountries === countryOfOrigin; - console.log("acces granted"); - return decision; -}; - app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next)); app.get("/", async (req, res) => { diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index e86b06a2..40d7aae1 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -73,6 +73,6 @@ describe("express middleware working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(app).get("/cookie/Set"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - expect(cookies[1]).toBe("__abby__ab__123_test2=A; Path=/"); + expect(cookies[0]).toBe("__abby__ab__123_test2=A"); }); }); diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts index 6c1d551b..64838331 100644 --- a/packages/nodejs/src/tests/abbyFastify.test.ts +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -33,16 +33,19 @@ describe("fastify working", () => { // parseOptions: {}, // options for parsing cookies // }); - // fastify.addHook("onRequest", (request, reply, done) => { - // ABTestHook(request, reply, done); - // }); + fastify.addHook("onRequest", (request, reply, done) => { + ABTestHook(request, reply, done); + }); fastify.get("/fastify", function (request, reply) { reply.send("Hello world!"); }); fastify.get("/cookie/Set", (request, reply) => { + const variant = getTestValue("test"); + reply.send(variant); + }); + fastify.get("/cookie/notSet", (request, reply) => { const variant = getTestValue("test2"); - console.log(variant); reply.send(variant); }); }); @@ -50,24 +53,21 @@ describe("fastify working", () => { test("featureFlag middleware", async () => { await fastify.ready(); const res = await request(fastify.server).get("/fastify"); - console.log(res.statusCode); }); - // test("abTestMiddleware respects the set cookie", async () => { - // const cookieVariant = "D"; - // //test cookie retrieval - // const response = await request(fastify.server) - // .get("/cookie/Set") - // .set("Cookie", [`__abby__ab__123_test2=${cookieVariant}; Path=/`]); + test("abTestMiddleware respects the set cookie", async () => { + const cookieVariant = "D"; + //test cookie retrieval + const response = await request(fastify.server) + .get("/cookie/Set") + .set("Cookie", [`__abby__ab__123_test=${cookieVariant}`]); - // expect(response.text).toBe(cookieVariant); - // }); + expect(response.text).toBe(cookieVariant); + }); - // test("abTestMiddleware sets the right cookie", async () => { - // const res = await request(fastify.server).get("/cookie/notSet"); - // console.log("response:", res.text); - // const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - // console.log(cookies); - // expect(cookies[1]).toBe("__abby__ab__123_test2=A; Path=/"); - // }); + test("abTestMiddleware sets the right cookie", async () => { + const res = await request(fastify.server).get("/cookie/notSet"); + const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull + expect(cookies[1]).toBe("__abby__ab__123_test2=A"); + }); }); From c3cbd53fba1bddd9d113c5e8446e8cd48eb1a200 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:01:48 +0200 Subject: [PATCH 61/68] working in browser for express and fastify , express test need to be fixed --- .../src/abby/contexts/responseContext.ts | 4 +-- .../src/express/abbyMiddlewareFactory.ts | 6 ++-- packages/nodejs/src/fastify/createAbby.ts | 20 ----------- .../nodejs/src/fastify/fastifyHookFactory.ts | 4 +-- packages/nodejs/src/fastify/index.ts | 34 +++++++++---------- packages/nodejs/src/shared/StorageService.ts | 18 +++++++--- packages/nodejs/src/tests/abbyExpress.test.ts | 3 +- packages/nodejs/src/tests/abbyFastify.test.ts | 10 +++--- 8 files changed, 44 insertions(+), 55 deletions(-) delete mode 100644 packages/nodejs/src/fastify/createAbby.ts diff --git a/packages/nodejs/src/abby/contexts/responseContext.ts b/packages/nodejs/src/abby/contexts/responseContext.ts index 353aae42..d0227d6d 100644 --- a/packages/nodejs/src/abby/contexts/responseContext.ts +++ b/packages/nodejs/src/abby/contexts/responseContext.ts @@ -2,9 +2,9 @@ import { Response } from "express"; import { FastifyReply } from "fastify"; -type ResponseType = Response | FastifyReply | null; +type ResponseType = Response | FastifyReply; -let res: ResponseType = null; +let res: ResponseType; export function setResponse(response: ResponseType) { res = response; diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index a37aafdd..e942d16a 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -28,7 +28,10 @@ export const abbyMiddlewareFactory = < }: { abbyConfig: F.Narrow>; }) => { - const abbyNodeInstance = createAbby(abbyConfig); + const setCookie = (cookie: string) => { + throw new Error("Method not implemented."); + }; + const abbyNodeInstance = createAbby(abbyConfig, setCookie); const configNarrowed = abbyConfig as unknown as ConfigType; const featureFlagMiddleware = ( @@ -54,7 +57,6 @@ export const abbyMiddlewareFactory = < const extractTest = (name: T): any => { const variant = abbyNodeInstance.getABTestValue(name); - console.log(name, variant); return { name, variant }; }; diff --git a/packages/nodejs/src/fastify/createAbby.ts b/packages/nodejs/src/fastify/createAbby.ts deleted file mode 100644 index c479b134..00000000 --- a/packages/nodejs/src/fastify/createAbby.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { createAbby } from "../abby/createAbby"; - -export const abby = createAbby({ - projectId: "clfn3hs1t0002kx08x3kidi80", - currentEnvironment: process.env.NODE_ENV, - tests: { - "New Test3": { - variants: ["A", "B"], - }, - }, - flags: { - lol: "Boolean", - test3: "Boolean", - testAbby: "Boolean", - }, - flagCacheConfig: { - refetchFlags: true, - timeToLive: 1, - }, -}); diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index 0b5850d9..4ecbf8af 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -3,7 +3,7 @@ import { F } from "ts-toolbelt"; import { createAbby } from "../abby/createAbby"; import { setRequest } from "../abby/contexts/requestContext"; import { setResponse } from "../abby/contexts/responseContext"; -import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; +import { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; export const abbyFastifyFactory = < FlagName extends string, @@ -69,7 +69,7 @@ export const abbyFastifyFactory = < if (configNarrowed.tests) { setRequestResponse(request, reply); const allTests = Object.keys(configNarrowed.tests) as T[]; - allTests.map((test) => { + const vals = allTests.map((test) => { return extractTest(test); }); } diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index 150c9545..c6aec90e 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -1,19 +1,17 @@ import Fastify from "fastify"; -import { parseCookies } from "../shared/helpers"; -import { abby } from "./createAbby"; -import { setRequest, getRequest } from "../abby/contexts/requestContext"; -import { setResponse } from "../abby/contexts/responseContext"; import { abbyFastifyFactory } from "./fastifyHookFactory"; +import fastifyCookie, { FastifyCookieOptions } from "@fastify/cookie"; const fastify = Fastify(); -fastify.register(require("@fastify/cookie"), { - secret: "my-secret", // for cookies signature - hook: "onRequest", // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest' - parseOptions: {}, // options for parsing cookies -}); +// Register the fastify-cookie plugin +fastify.register(fastifyCookie); + +const setCookie = fastifyCookie; + +console.log(setCookie); -const { featureFlagHook } = abbyFastifyFactory({ +const { featureFlagHook, ABTestHook, getTestValue } = abbyFastifyFactory({ abbyConfig: { projectId: "clfn3hs1t0002kx08x3kidi80", currentEnvironment: process.env.NODE_ENV, @@ -22,7 +20,7 @@ const { featureFlagHook } = abbyFastifyFactory({ variants: ["A", "B"], }, "New Test6": { - variants: ["A"], + variants: ["A", "GG"], }, }, flags: { @@ -37,17 +35,19 @@ const { featureFlagHook } = abbyFastifyFactory({ }, }); -fastify.addHook("onRequest", async (request, reply, done) => { - console.log("hook"); - featureFlagHook("lol", request, reply, done); +fastify.addHook("onRequest", (request, reply, done) => { + ABTestHook(request, reply, done); + // featureFlagHook("lol", request, reply, done); }); const port = 3000; console.log("start fastify"); fastify.get("/", function (request, reply) { - setRequest(request); - setResponse(reply); - reply.send("Hello world!"); + // setResponse(reply); + const variant = getTestValue("New Test3"); + const variant2 = getTestValue("New Test6"); + console.log("reply before send", reply.getHeaders()); + reply.send("hi"); }); fastify.listen({ port }, function (err, address) { diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index 340dfad8..ba6bd5d1 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -2,9 +2,8 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers"; import { getRequest } from "../abby/contexts/requestContext"; import { getResponse } from "../abby/contexts/responseContext"; -import { FastifyReply } from "fastify"; -class ABStorageService implements IStorageService { +export class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { const req = getRequest(); if (!req) return null; @@ -18,10 +17,19 @@ class ABStorageService implements IStorageService { if (!response) { return; } + const cookieKey = getABStorageKey(projectId, key); - const cookie = `${cookieKey}=${value}`; - response.header("set-cookie", cookie); - // response.cookie(cookieKey, value); //TODO find a way to handle fastify and express cookies + const cookieValue = `${cookieKey}=${value}`; + + if (response.setCookie) { + //TODO fix typecheck + //fastify + response.setCookie(cookieKey, cookieValue); + } else { + //express + response.cookie(cookieKey, cookieValue); + // console.log(response); + } } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 40d7aae1..e9c375b1 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -72,7 +72,8 @@ describe("express middleware working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(app).get("/cookie/Set"); - const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull + const cookies = res.headers; //res.headers["set-cookie"]; //res headers is any so need to be carefull + console.log(cookies); expect(cookies[0]).toBe("__abby__ab__123_test2=A"); }); }); diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts index 64838331..29b7f8f9 100644 --- a/packages/nodejs/src/tests/abbyFastify.test.ts +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -2,6 +2,7 @@ import { expect, test, describe, beforeAll } from "vitest"; import Fastify, { FastifyInstance } from "fastify"; import { abbyFastifyFactory } from "../fastify/fastifyHookFactory"; import request from "supertest"; +import fastifyCookie from "@fastify/cookie"; describe("fastify working", () => { let fastify: FastifyInstance; @@ -27,11 +28,8 @@ describe("fastify working", () => { fastify = Fastify(); - // fastify.register(require("@fastify/cookie"), { - // secret: "my-secret", // for cookies signature - // hook: "onRequest", // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest' - // parseOptions: {}, // options for parsing cookies - // }); + // Register the fastify-cookie plugin + fastify.register(fastifyCookie); fastify.addHook("onRequest", (request, reply, done) => { ABTestHook(request, reply, done); @@ -68,6 +66,6 @@ describe("fastify working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(fastify.server).get("/cookie/notSet"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - expect(cookies[1]).toBe("__abby__ab__123_test2=A"); + expect(cookies[1]).toBe("__abby__ab__123_test2=__abby__ab__123_test2%3DA"); }); }); From 815d794beee0dcfac6e906883d58c8e3d5b9ca4d Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:15:53 +0200 Subject: [PATCH 62/68] add cookie parser --- packages/nodejs/package.json | 1 + .../src/abby/contexts/requestContext.ts | 15 ------------- .../src/abby/contexts/responseContext.ts | 15 ------------- packages/nodejs/src/abby/createAbby.ts | 11 +++++----- packages/nodejs/src/abby/helpers.ts | 17 +++++++------- .../src/express/abbyMiddlewareFactory.ts | 13 +---------- .../nodejs/src/fastify/fastifyHookFactory.ts | 22 ++++--------------- packages/nodejs/src/fastify/index.ts | 6 +---- packages/nodejs/src/shared/StorageService.ts | 14 +++++------- packages/nodejs/src/tests/abbyExpress.test.ts | 19 ++++++++-------- 10 files changed, 38 insertions(+), 95 deletions(-) delete mode 100644 packages/nodejs/src/abby/contexts/requestContext.ts delete mode 100644 packages/nodejs/src/abby/contexts/responseContext.ts diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 495ce3ab..68d3920c 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -36,6 +36,7 @@ "dependencies": { "@fastify/cookie": "^8.3.0", "@tryabby/core": "workspace:^", + "cookie-parser": "^1.4.6", "express": "^4.18.2", "fastify": "^4.19.2", "ts-toolbelt": "^9.6.0" diff --git a/packages/nodejs/src/abby/contexts/requestContext.ts b/packages/nodejs/src/abby/contexts/requestContext.ts deleted file mode 100644 index 61ca0bb9..00000000 --- a/packages/nodejs/src/abby/contexts/requestContext.ts +++ /dev/null @@ -1,15 +0,0 @@ -// hacky way to get request object in storage service without passing it -import { Request } from "express"; -import { FastifyRequest } from "fastify"; - -// type RequestType = T extends Request ? Request : FastifyRequest; -type RequestType = Request | FastifyRequest | null; -let req: RequestType = null; - -export function setRequest(request: RequestType) { - req = request; -} - -export function getRequest(): RequestType | null { - return req; -} diff --git a/packages/nodejs/src/abby/contexts/responseContext.ts b/packages/nodejs/src/abby/contexts/responseContext.ts deleted file mode 100644 index d0227d6d..00000000 --- a/packages/nodejs/src/abby/contexts/responseContext.ts +++ /dev/null @@ -1,15 +0,0 @@ -// hacky way to get response object in storage service without passing it -import { Response } from "express"; -import { FastifyReply } from "fastify"; - -type ResponseType = Response | FastifyReply; - -let res: ResponseType; - -export function setResponse(response: ResponseType) { - res = response; -} - -export function getResponse() { - return res; -} diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index fb831015..60a0ff81 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,6 +1,7 @@ import { ABConfig, Abby, AbbyConfig, FlagValueString, FlagValueStringToType } from "@tryabby/core"; import { F } from "ts-toolbelt"; import { TestStorageService } from "../shared/StorageService"; +import { FastifyRequest } from "fastify"; export function createAbby< FlagName extends string, @@ -10,11 +11,11 @@ export function createAbby< ConfigType extends AbbyConfig = AbbyConfig, >(abbyConfig: F.Narrow>) { const abbyCoreInstance = new Abby(abbyConfig, { - get: (key: string) => { - return TestStorageService.get(abbyConfig.projectId, key); + get: (key: keyof Tests) => { + return TestStorageService.get(abbyConfig.projectId, key as string); }, - set: (key: string, value: any) => { - TestStorageService.set(abbyConfig.projectId, key, value); + set: (key: keyof Tests, value: any) => { + TestStorageService.set(abbyConfig.projectId, key as string, value); }, }); @@ -27,7 +28,7 @@ export function createAbby< * @param name Name of the test that the variant should be retrieved for * @returns Value of the currently selected variant */ - const getABTestValue = (name: T) => { + const getABTestValue = (name: T, req: FastifyRequest) => { const value = abbyCoreInstance.getTestVariant(name); return value; }; diff --git a/packages/nodejs/src/abby/helpers.ts b/packages/nodejs/src/abby/helpers.ts index 07c36ac8..3f5824e9 100644 --- a/packages/nodejs/src/abby/helpers.ts +++ b/packages/nodejs/src/abby/helpers.ts @@ -5,11 +5,12 @@ import { Request } from "express"; * @param req express Request */ export function parseCookies(req: Request) { - const cookies = req.headers.cookie; - const cookieMap = new Map(); - cookies?.split(";").map((res, index) => { - const parsedCookie = res.trim().split("="); - cookieMap.set(parsedCookie[0], parsedCookie[1]) - }) - return cookieMap; -} \ No newline at end of file + console.log(req.headers); + const cookies = req.headers.cookie; + const cookieMap = new Map(); + cookies?.split(";").map((res, index) => { + const parsedCookie = res.trim().split("="); + cookieMap.set(parsedCookie[0], parsedCookie[1]); + }); + return cookieMap; +} diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index e942d16a..04df70c0 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -1,6 +1,4 @@ import { NextFunction, Request, Response } from "express"; -import { setRequest } from "../abby/contexts/requestContext"; -import { setResponse } from "../abby/contexts/responseContext"; import { AbbyConfig, ABConfig, FlagValueString } from "@tryabby/core"; import { createAbby } from "../abby/createAbby"; import { F } from "ts-toolbelt"; @@ -28,10 +26,7 @@ export const abbyMiddlewareFactory = < }: { abbyConfig: F.Narrow>; }) => { - const setCookie = (cookie: string) => { - throw new Error("Method not implemented."); - }; - const abbyNodeInstance = createAbby(abbyConfig, setCookie); + const abbyNodeInstance = createAbby(abbyConfig); const configNarrowed = abbyConfig as unknown as ConfigType; const featureFlagMiddleware = ( @@ -50,11 +45,6 @@ export const abbyMiddlewareFactory = < next(); }; - const setRequestResponse = (req: Request, res: Response): void => { - setRequest(req); - setResponse(res); - }; - const extractTest = (name: T): any => { const variant = abbyNodeInstance.getABTestValue(name); return { name, variant }; @@ -66,7 +56,6 @@ export const abbyMiddlewareFactory = < next: NextFunction ) => { if (configNarrowed.tests) { - setRequestResponse(req, res); const allTests = Object.keys(configNarrowed.tests) as T[]; //TODO get type in a proper way const testWithVariant = allTests.map((test) => { return extractTest(test); diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index 4ecbf8af..ba8240c7 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -1,9 +1,7 @@ import { ABConfig, FlagValueString, AbbyConfig } from "@tryabby/core"; import { F } from "ts-toolbelt"; import { createAbby } from "../abby/createAbby"; -import { setRequest } from "../abby/contexts/requestContext"; -import { setResponse } from "../abby/contexts/responseContext"; -import { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; +import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify"; export const abbyFastifyFactory = < FlagName extends string, @@ -19,7 +17,7 @@ export const abbyFastifyFactory = < const abbyNodeInstance = createAbby(abbyConfig); const configNarrowed = abbyConfig as unknown as ConfigType; /** - * hook to disbale a path via feature flag + * hook to disable a path via feature flag */ const featureFlagHook = ( key: F, @@ -31,7 +29,6 @@ export const abbyFastifyFactory = < if (flagValue) { reply.status(403); reply.send(); - console.log("disbaled endpoint"); return; } done(); @@ -48,16 +45,6 @@ export const abbyFastifyFactory = < return { name, variant }; }; - /** - * helperfunction to setup the context - * @param req - * @param res - */ - const setRequestResponse = (req: FastifyRequest, res: FastifyReply): void => { - setRequest(req); - setResponse(res); - }; - /** * hook to parse all ab values on the request object needs to be used at the top */ @@ -67,7 +54,6 @@ export const abbyFastifyFactory = < done: HookHandlerDoneFunction ) => { if (configNarrowed.tests) { - setRequestResponse(request, reply); const allTests = Object.keys(configNarrowed.tests) as T[]; const vals = allTests.map((test) => { return extractTest(test); @@ -80,8 +66,8 @@ export const abbyFastifyFactory = < return abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); }; - const getTestValue = (key: T) => { - return abbyNodeInstance.getABTestValue(key); + const getTestValue = (key: T, req: FastifyRequest) => { + return abbyNodeInstance.getABTestValue(key, req); }; return { ABTestHook, featureFlagHook, getFlagValue, getTestValue }; diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index c6aec90e..5419d3ae 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -1,16 +1,12 @@ import Fastify from "fastify"; import { abbyFastifyFactory } from "./fastifyHookFactory"; -import fastifyCookie, { FastifyCookieOptions } from "@fastify/cookie"; +import fastifyCookie from "@fastify/cookie"; const fastify = Fastify(); // Register the fastify-cookie plugin fastify.register(fastifyCookie); -const setCookie = fastifyCookie; - -console.log(setCookie); - const { featureFlagHook, ABTestHook, getTestValue } = abbyFastifyFactory({ abbyConfig: { projectId: "clfn3hs1t0002kx08x3kidi80", diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index ba6bd5d1..aa281a2b 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -1,23 +1,22 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers"; -import { getRequest } from "../abby/contexts/requestContext"; -import { getResponse } from "../abby/contexts/responseContext"; export class ABStorageService implements IStorageService { get(projectId: string, key: string): string | null { - const req = getRequest(); + const req = null; if (!req) return null; + console.log("req.headers", req.headers); const cookieMap = parseCookies(req); + console.log("cookieMap", cookieMap); const cookieKey = getABStorageKey(projectId, key); const cookieValue = cookieMap.get(cookieKey); + console.log(cookieValue); return cookieValue ?? null; } set(projectId: string, key: string, value: string): void { - const response = getResponse(); - if (!response) { - return; - } + const response = null; + if (!response) return; const cookieKey = getABStorageKey(projectId, key); const cookieValue = `${cookieKey}=${value}`; @@ -28,7 +27,6 @@ export class ABStorageService implements IStorageService { } else { //express response.cookie(cookieKey, cookieValue); - // console.log(response); } } remove(projectId: string, key: string): void { diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index e9c375b1..3b86bc3c 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -47,12 +47,13 @@ describe("express middleware working", () => { res.sendStatus(404); }); app.get("/cookie/Set", (req, res) => { - res.send("hiadsa"); + const variant = getVariant("test"); + res.send(variant); }); }); - //TODO for whatever reason middleware tests need to be executed first, else it does not work - test("featureFlag Middleware working", async () => { + // TODO for whatever reason middleware tests need to be executed first, else it does not work + test.skip("featureFlag Middleware working", async () => { //check if feature flag value is respected const succesFullResponse = await request(app).get("/featureFlag/Enabled"); @@ -60,20 +61,20 @@ describe("express middleware working", () => { expect(succesFullResponse.statusCode).toBe(200); expect(forbiddenResponse.statusCode).toBe(403); }); - test("abTestMiddleware respects the set cookie", async () => { + test.skip("abTestMiddleware respects the set cookie", async () => { const cookieVariant = "D"; //test cookie retrieval const response = await request(app) - .get("/cookie/notSet") - .set("Cookie", [`__abby__ab__123_test2=${cookieVariant}; Path=/`]); + .get("/cookie/Set") + .set("Cookie", [`__abby__ab__123_test=${cookieVariant}`]); expect(response.text).toBe(cookieVariant); }); test("abTestMiddleware sets the right cookie", async () => { - const res = await request(app).get("/cookie/Set"); - const cookies = res.headers; //res.headers["set-cookie"]; //res headers is any so need to be carefull + const res = await request(app).get("/cookie/notSet"); + const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull console.log(cookies); - expect(cookies[0]).toBe("__abby__ab__123_test2=A"); + expect(cookies[0]).toBe("__abby__ab__123_test=__abby__ab__123_test%3DA; Path=/"); }); }); From 91fd26cebc0d43b49300cd464f6030c6d8bffb21 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:08:41 +0200 Subject: [PATCH 63/68] fix svelte imports --- packages/svelte/src/lib/createAbby.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/src/lib/createAbby.ts b/packages/svelte/src/lib/createAbby.ts index 3b8cec3f..99cacfeb 100644 --- a/packages/svelte/src/lib/createAbby.ts +++ b/packages/svelte/src/lib/createAbby.ts @@ -1,4 +1,4 @@ -import { Abby, type AbbyConfig, type ABConfig } from "@tryabby/core"; +import { Abby, type AbbyConfig, type ABConfig, type FlagValueString } from "@tryabby/core"; import { HttpService, AbbyEventType } from "@tryabby/core"; import { derived } from "svelte/store"; import type { F } from "ts-toolbelt"; From 74cc9a3b212104e8c727624c44fb61970a3b4513 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 18:47:20 +0200 Subject: [PATCH 64/68] add optional passing of response and request object --- packages/core/src/index.ts | 81 +++++++++++-------- packages/nodejs/src/abby/createAbby.ts | 19 +++-- packages/nodejs/src/abby/helpers.ts | 1 - .../src/express/abbyMiddlewareFactory.ts | 6 +- .../nodejs/src/fastify/fastifyHookFactory.ts | 8 +- packages/nodejs/src/fastify/index.ts | 14 ++-- packages/nodejs/src/index.ts | 15 ++-- packages/nodejs/src/shared/StorageService.ts | 72 +++++++++++++---- pnpm-lock.yaml | 25 ++++++ 9 files changed, 166 insertions(+), 75 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ae868979..33c89c37 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -20,7 +20,7 @@ export type ABConfig = { type Settings< FlagName extends string, - Flags extends Record = Record + Flags extends Record = Record, > = { flags?: { defaultValues?: { @@ -44,8 +44,8 @@ type LocalData string | null; - set: (key: string, value: string) => void; + get: (key: string, args?: unknown) => string | null; + set: (key: string, value: string, args?: unknown) => void; } type flagCacheConfig = { @@ -56,7 +56,7 @@ type flagCacheConfig = { export type AbbyConfig< FlagName extends string = string, Tests extends Record = Record, - Flags extends Record = Record + Flags extends Record = Record, > = { projectId: string; apiUrl?: string; @@ -72,7 +72,7 @@ export class Abby< FlagName extends string, TestName extends string, Tests extends Record, - Flags extends Record + Flags extends Record, > { private log = (...args: any[]) => this.config.debug ? console.log(`core.Abby`, ...args) : () => {}; @@ -105,13 +105,16 @@ export class Abby< private persistantFlagStorage?: PersistentStorage ) { this._cfg = config as AbbyConfig; - this.#data.flags = Object.keys(config.flags ?? {}).reduce((acc, flagName) => { - acc[flagName as FlagName] = this.getDefaultFlagValue( - flagName as FlagName, - config.flags as any - ); - return acc; - }, {} as Record); + this.#data.flags = Object.keys(config.flags ?? {}).reduce( + (acc, flagName) => { + acc[flagName as FlagName] = this.getDefaultFlagValue( + flagName as FlagName, + config.flags as any + ); + return acc; + }, + {} as Record + ); this.#data.tests = config.tests ?? ({} as any); } @@ -152,26 +155,32 @@ export class Abby< data: AbbyDataResponse ): LocalData { return { - tests: data.tests.reduce((acc, { name, weights }) => { - if (!acc[name as keyof Tests]) { + tests: data.tests.reduce( + (acc, { name, weights }) => { + if (!acc[name as keyof Tests]) { + return acc; + } + + // assigned the fetched weights to the initial config + acc[name as keyof Tests] = { + ...acc[name as keyof Tests], + weights, + }; return acc; - } - - // assigned the fetched weights to the initial config - acc[name as keyof Tests] = { - ...acc[name as keyof Tests], - weights, - }; - return acc; - }, (this.config.tests ?? {}) as any), - flags: data.flags.reduce((acc, { name, value }) => { - const validUntil = new Date( - new Date().getTime() + 1000 * 60 * (this.config.flagCacheConfig?.timeToLive ?? 1) - ); // flagdefault timeout is 1 minute - this.#flagTimeoutMap.set(name, validUntil); - acc[name] = value; - return acc; - }, {} as Record), + }, + (this.config.tests ?? {}) as any + ), + flags: data.flags.reduce( + (acc, { name, value }) => { + const validUntil = new Date( + new Date().getTime() + 1000 * 60 * (this.config.flagCacheConfig?.timeToLive ?? 1) + ); // flagdefault timeout is 1 minute + this.#flagTimeoutMap.set(name, validUntil); + acc[name] = value; + return acc; + }, + {} as Record + ), }; } @@ -304,7 +313,10 @@ export class Abby< * @param key The name of the test * @returns the value of the test variant */ - getTestVariant(key: T): Tests[T]["variants"][number] { + getTestVariant( + key: T, + args?: T_ARGS + ): Tests[T]["variants"][number] { this.log(`getTestVariant()`, key); const { variants, weights } = (this.#data.tests as LocalData["tests"])[ @@ -317,7 +329,7 @@ export class Abby< return override; } - const persistedValue = this.persistantTestStorage?.get(key as string); + const persistedValue = this.persistantTestStorage?.get(key as string, args); if (persistedValue != null) { this.log(`getTestVariant() => persistedValue:`, persistedValue); @@ -326,7 +338,8 @@ export class Abby< } const weightedVariant = getWeightedRandomVariant(variants, weights); - this.persistantTestStorage?.set(key as string, weightedVariant); + console.log("args", args !== undefined); + this.persistantTestStorage?.set(key as string, weightedVariant, args); this.log(`getTestVariant() => weightedVariant:`, weightedVariant); diff --git a/packages/nodejs/src/abby/createAbby.ts b/packages/nodejs/src/abby/createAbby.ts index 60a0ff81..3f069353 100644 --- a/packages/nodejs/src/abby/createAbby.ts +++ b/packages/nodejs/src/abby/createAbby.ts @@ -1,7 +1,8 @@ import { ABConfig, Abby, AbbyConfig, FlagValueString, FlagValueStringToType } from "@tryabby/core"; import { F } from "ts-toolbelt"; import { TestStorageService } from "../shared/StorageService"; -import { FastifyRequest } from "fastify"; +import { FastifyReply, FastifyRequest } from "fastify"; +import { Request } from "express"; export function createAbby< FlagName extends string, @@ -11,11 +12,11 @@ export function createAbby< ConfigType extends AbbyConfig = AbbyConfig, >(abbyConfig: F.Narrow>) { const abbyCoreInstance = new Abby(abbyConfig, { - get: (key: keyof Tests) => { - return TestStorageService.get(abbyConfig.projectId, key as string); + get: (key: string, args?: unknown) => { + return TestStorageService.get(abbyConfig.projectId, key as string, args); }, - set: (key: keyof Tests, value: any) => { - TestStorageService.set(abbyConfig.projectId, key as string, value); + set: (key: string, value: any, args?: unknown) => { + TestStorageService.set(abbyConfig.projectId, key as string, value, args); }, }); @@ -28,9 +29,11 @@ export function createAbby< * @param name Name of the test that the variant should be retrieved for * @returns Value of the currently selected variant */ - const getABTestValue = (name: T, req: FastifyRequest) => { - const value = abbyCoreInstance.getTestVariant(name); - return value; + const getABTestValue = ( + name: T, + reqRes: { req: Request | FastifyRequest; res: Response | FastifyReply } + ) => { + return abbyCoreInstance.getTestVariant(name, reqRes); }; /** * diff --git a/packages/nodejs/src/abby/helpers.ts b/packages/nodejs/src/abby/helpers.ts index 3f5824e9..10008e70 100644 --- a/packages/nodejs/src/abby/helpers.ts +++ b/packages/nodejs/src/abby/helpers.ts @@ -5,7 +5,6 @@ import { Request } from "express"; * @param req express Request */ export function parseCookies(req: Request) { - console.log(req.headers); const cookies = req.headers.cookie; const cookieMap = new Map(); cookies?.split(";").map((res, index) => { diff --git a/packages/nodejs/src/express/abbyMiddlewareFactory.ts b/packages/nodejs/src/express/abbyMiddlewareFactory.ts index 04df70c0..f723874e 100644 --- a/packages/nodejs/src/express/abbyMiddlewareFactory.ts +++ b/packages/nodejs/src/express/abbyMiddlewareFactory.ts @@ -46,7 +46,7 @@ export const abbyMiddlewareFactory = < }; const extractTest = (name: T): any => { - const variant = abbyNodeInstance.getABTestValue(name); + const variant = abbyNodeInstance.getABTestValue(name as string, null); return { name, variant }; }; @@ -70,8 +70,8 @@ export const abbyMiddlewareFactory = < // next: NextFunction // ) => {}; - const getVariant = (name: T) => { - return abbyNodeInstance.getABTestValue(name); + const getVariant = (name: T, reqRes: { req: Request; res: Response }) => { + return abbyNodeInstance.getABTestValue(name as string, reqRes); }; return { featureFlagMiddleware, allTestsMiddleWare, getVariant }; diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index ba8240c7..29b84947 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -66,8 +66,12 @@ export const abbyFastifyFactory = < return abbyNodeInstance.getFeatureFlagValue(key as unknown as FlagName); }; - const getTestValue = (key: T, req: FastifyRequest) => { - return abbyNodeInstance.getABTestValue(key, req); + const getTestValue = ( + key: T, + reqRes: { req: FastifyRequest; res: FastifyReply } + ) => { + console.log("isdef reqRes", reqRes !== undefined); + return abbyNodeInstance.getABTestValue(key, reqRes); }; return { ABTestHook, featureFlagHook, getFlagValue, getTestValue }; diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index 5419d3ae..bff4fe82 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -31,18 +31,18 @@ const { featureFlagHook, ABTestHook, getTestValue } = abbyFastifyFactory({ }, }); -fastify.addHook("onRequest", (request, reply, done) => { - ABTestHook(request, reply, done); - // featureFlagHook("lol", request, reply, done); -}); +// fastify.addHook("onRequest", (request, reply, done) => { +// ABTestHook(request, reply, done); +// // featureFlagHook("lol", request, reply, done); +// }); const port = 3000; console.log("start fastify"); fastify.get("/", function (request, reply) { // setResponse(reply); - const variant = getTestValue("New Test3"); - const variant2 = getTestValue("New Test6"); - console.log("reply before send", reply.getHeaders()); + const variant = getTestValue("New Test3", { req: request, res: reply }); + // const variant2 = getTestValue("New Test6"); + console.log("reply before send", variant); reply.send("hi"); }); diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index f5a80797..2cc9bbf3 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -1,9 +1,12 @@ import express, { Request } from "express"; import { abbyMiddlewareFactory } from "./express/abbyMiddlewareFactory"; +import cookieParser from "cookie-parser"; const app = express(); const port = 3000; +app.use(cookieParser()); + const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = abbyMiddlewareFactory({ abbyConfig: { projectId: "clfn3hs1t0002kx08x3kidi80", @@ -30,14 +33,16 @@ const { featureFlagMiddleware, allTestsMiddleWare, getVariant } = abbyMiddleware app.use(express.json()); -app.use("/", (req, res, next) => { - allTestsMiddleWare(req, res, next); -}); +// app.use("/", (req, res, next) => { +// allTestsMiddleWare(req, res, next); +// }); -app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next)); +// app.use("/", (req, res, next) => featureFlagMiddleware("test3", req, res, next)); app.get("/", async (req, res) => { - const variant = getVariant("New Test3"); + const variant = getVariant("New Test3", { req, res }); + res.cookie("yo", 222); + console.log(variant); res.send(variant === "B" ? "very nice content that needs to be protected" : "vriant B"); }); diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index aa281a2b..0914306e 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -1,37 +1,79 @@ import { IStorageService, getABStorageKey } from "@tryabby/core"; import { parseCookies } from "./helpers"; +import { Request, Response } from "express"; +import { FastifyReply, FastifyRequest } from "fastify"; export class ABStorageService implements IStorageService { - get(projectId: string, key: string): string | null { - const req = null; + get( + projectId: string, + key: string, + args?: { + req: Request | FastifyRequest; + } + ): string | null { + const req = args?.req; if (!req) return null; - console.log("req.headers", req.headers); - const cookieMap = parseCookies(req); - console.log("cookieMap", cookieMap); + const cookieMap = this.parseCookies(req); const cookieKey = getABStorageKey(projectId, key); const cookieValue = cookieMap.get(cookieKey); - console.log(cookieValue); return cookieValue ?? null; } - set(projectId: string, key: string, value: string): void { - const response = null; - + set( + projectId: string, + key: string, + value: string, + args?: { + res: Response | FastifyReply; + } + ): void { + const response = args?.res; + console.log("set resp def", response !== undefined); if (!response) return; const cookieKey = getABStorageKey(projectId, key); - const cookieValue = `${cookieKey}=${value}`; - if (response.setCookie) { - //TODO fix typecheck + if (this.isFastifyReply(response)) { //fastify - response.setCookie(cookieKey, cookieValue); - } else { + console.log("stecookie fastify"); + response.setCookie(cookieKey, value); + } else if (this.isExpressResponse(response)) { //express - response.cookie(cookieKey, cookieValue); + console.log("setCookie"); + response.cookie(cookieKey, value); } } remove(projectId: string, key: string): void { throw new Error("Method not implemented."); } + + parseCookies(req: Request | FastifyRequest) { + if (this.isExpressRequest(req)) { + return parseCookies(req); + } else if (this.isFastifyRequest(req)) { + return parseCookies(req); + } else { + throw new Error("req must be an instance of either Request or Fastify Request"); + } + } + + isFastifyRequest(req: unknown): req is FastifyRequest { + const possibleRequest = req as FastifyRequest; + return possibleRequest.cookies !== undefined; + } + + isExpressRequest(args: unknown): args is Request { + const possibleRequest = args as Request; + return possibleRequest.app !== undefined; + } + + isFastifyReply(res: unknown): res is FastifyReply { + const possibleReply = res as FastifyReply; + return possibleReply.setCookie !== undefined; + } + + isExpressResponse(res: unknown): res is Response { + const possibleRequest = res as Response; + return possibleRequest.cookie !== null; + } } class FFStorageService implements IStorageService { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b7ca912..182afcbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -783,6 +783,9 @@ importers: '@tryabby/core': specifier: workspace:^ version: link:../core + cookie-parser: + specifier: ^1.4.6 + version: 1.4.6 express: specifier: ^4.18.2 version: 4.18.2 @@ -793,6 +796,9 @@ importers: specifier: ^9.6.0 version: 9.6.0 devDependencies: + '@types/cookie-parser': + specifier: ^1.4.3 + version: 1.4.3 '@types/express': specifier: ^4.17.17 version: 4.17.17 @@ -9331,6 +9337,12 @@ packages: dependencies: '@types/node': 18.16.17 + /@types/cookie-parser@1.4.3: + resolution: {integrity: sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==} + dependencies: + '@types/express': 4.17.17 + dev: true + /@types/cookie@0.4.1: resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} @@ -11693,9 +11705,22 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /cookie-parser@1.4.6: + resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} + engines: {node: '>= 0.8.0'} + dependencies: + cookie: 0.4.1 + cookie-signature: 1.0.6 + dev: false + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + /cookie@0.4.1: + resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} + engines: {node: '>= 0.6'} + dev: false + /cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} From 860b35b360b9ed7dd05dc01daea4c502295a63c9 Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 19:20:41 +0200 Subject: [PATCH 65/68] fix tests and clean up --- packages/core/src/index.ts | 1 - packages/nodejs/src/fastify/fastifyHookFactory.ts | 1 - packages/nodejs/src/fastify/index.ts | 2 -- packages/nodejs/src/index.ts | 2 -- packages/nodejs/src/shared/StorageService.ts | 3 --- packages/nodejs/src/tests/abbyExpress.test.ts | 11 +++++------ packages/nodejs/src/tests/abbyFastify.test.ts | 6 +++--- 7 files changed, 8 insertions(+), 18 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 33c89c37..5f3b9993 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -338,7 +338,6 @@ export class Abby< } const weightedVariant = getWeightedRandomVariant(variants, weights); - console.log("args", args !== undefined); this.persistantTestStorage?.set(key as string, weightedVariant, args); this.log(`getTestVariant() => weightedVariant:`, weightedVariant); diff --git a/packages/nodejs/src/fastify/fastifyHookFactory.ts b/packages/nodejs/src/fastify/fastifyHookFactory.ts index 29b84947..5904a9f7 100644 --- a/packages/nodejs/src/fastify/fastifyHookFactory.ts +++ b/packages/nodejs/src/fastify/fastifyHookFactory.ts @@ -70,7 +70,6 @@ export const abbyFastifyFactory = < key: T, reqRes: { req: FastifyRequest; res: FastifyReply } ) => { - console.log("isdef reqRes", reqRes !== undefined); return abbyNodeInstance.getABTestValue(key, reqRes); }; diff --git a/packages/nodejs/src/fastify/index.ts b/packages/nodejs/src/fastify/index.ts index bff4fe82..69cf876c 100644 --- a/packages/nodejs/src/fastify/index.ts +++ b/packages/nodejs/src/fastify/index.ts @@ -37,12 +37,10 @@ const { featureFlagHook, ABTestHook, getTestValue } = abbyFastifyFactory({ // }); const port = 3000; -console.log("start fastify"); fastify.get("/", function (request, reply) { // setResponse(reply); const variant = getTestValue("New Test3", { req: request, res: reply }); // const variant2 = getTestValue("New Test6"); - console.log("reply before send", variant); reply.send("hi"); }); diff --git a/packages/nodejs/src/index.ts b/packages/nodejs/src/index.ts index 2cc9bbf3..bb839bf3 100644 --- a/packages/nodejs/src/index.ts +++ b/packages/nodejs/src/index.ts @@ -41,8 +41,6 @@ app.use(express.json()); app.get("/", async (req, res) => { const variant = getVariant("New Test3", { req, res }); - res.cookie("yo", 222); - console.log(variant); res.send(variant === "B" ? "very nice content that needs to be protected" : "vriant B"); }); diff --git a/packages/nodejs/src/shared/StorageService.ts b/packages/nodejs/src/shared/StorageService.ts index 0914306e..5e1db32a 100644 --- a/packages/nodejs/src/shared/StorageService.ts +++ b/packages/nodejs/src/shared/StorageService.ts @@ -27,17 +27,14 @@ export class ABStorageService implements IStorageService { } ): void { const response = args?.res; - console.log("set resp def", response !== undefined); if (!response) return; const cookieKey = getABStorageKey(projectId, key); if (this.isFastifyReply(response)) { //fastify - console.log("stecookie fastify"); response.setCookie(cookieKey, value); } else if (this.isExpressResponse(response)) { //express - console.log("setCookie"); response.cookie(cookieKey, value); } } diff --git a/packages/nodejs/src/tests/abbyExpress.test.ts b/packages/nodejs/src/tests/abbyExpress.test.ts index 3b86bc3c..44552406 100644 --- a/packages/nodejs/src/tests/abbyExpress.test.ts +++ b/packages/nodejs/src/tests/abbyExpress.test.ts @@ -39,7 +39,7 @@ describe("express middleware working", () => { app.use("/cookie", (req, res, next) => allTestsMiddleWare(req, res, next)); app.get("/cookie/notSet", (req, res) => { - const variant = getVariant("test2"); + const variant = getVariant("test2", { req, res }); if (variant) { res.send(variant); return; @@ -47,13 +47,13 @@ describe("express middleware working", () => { res.sendStatus(404); }); app.get("/cookie/Set", (req, res) => { - const variant = getVariant("test"); + const variant = getVariant("test", { req, res }); res.send(variant); }); }); // TODO for whatever reason middleware tests need to be executed first, else it does not work - test.skip("featureFlag Middleware working", async () => { + test("featureFlag Middleware working", async () => { //check if feature flag value is respected const succesFullResponse = await request(app).get("/featureFlag/Enabled"); @@ -61,7 +61,7 @@ describe("express middleware working", () => { expect(succesFullResponse.statusCode).toBe(200); expect(forbiddenResponse.statusCode).toBe(403); }); - test.skip("abTestMiddleware respects the set cookie", async () => { + test("abTestMiddleware respects the set cookie", async () => { const cookieVariant = "D"; //test cookie retrieval const response = await request(app) @@ -74,7 +74,6 @@ describe("express middleware working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(app).get("/cookie/notSet"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - console.log(cookies); - expect(cookies[0]).toBe("__abby__ab__123_test=__abby__ab__123_test%3DA; Path=/"); + expect(cookies[0]).toBe("__abby__ab__123_test2=A; Path=/"); }); }); diff --git a/packages/nodejs/src/tests/abbyFastify.test.ts b/packages/nodejs/src/tests/abbyFastify.test.ts index 29b7f8f9..1ba7dfd7 100644 --- a/packages/nodejs/src/tests/abbyFastify.test.ts +++ b/packages/nodejs/src/tests/abbyFastify.test.ts @@ -39,11 +39,11 @@ describe("fastify working", () => { reply.send("Hello world!"); }); fastify.get("/cookie/Set", (request, reply) => { - const variant = getTestValue("test"); + const variant = getTestValue("test", { req: request, res: reply }); reply.send(variant); }); fastify.get("/cookie/notSet", (request, reply) => { - const variant = getTestValue("test2"); + const variant = getTestValue("test2", { req: request, res: reply }); reply.send(variant); }); }); @@ -66,6 +66,6 @@ describe("fastify working", () => { test("abTestMiddleware sets the right cookie", async () => { const res = await request(fastify.server).get("/cookie/notSet"); const cookies = res.headers["set-cookie"]; //res headers is any so need to be carefull - expect(cookies[1]).toBe("__abby__ab__123_test2=__abby__ab__123_test2%3DA"); + expect(cookies[0]).toBe("__abby__ab__123_test2=A"); }); }); From 153e5496238346535dee52f93b9c1262fccf9c1b Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 19:26:03 +0200 Subject: [PATCH 66/68] fix lockfile --- pnpm-lock.yaml | 66 +++++++------------------------------------------- 1 file changed, 9 insertions(+), 57 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 182afcbe..b0513171 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -678,7 +678,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@18.16.17) + version: 4.3.9(@types/node@20.3.0) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -796,9 +796,6 @@ importers: specifier: ^9.6.0 version: 9.6.0 devDependencies: - '@types/cookie-parser': - specifier: ^1.4.3 - version: 1.4.3 '@types/express': specifier: ^4.17.17 version: 4.17.17 @@ -1004,7 +1001,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@18.16.17) + version: 4.3.9(@types/node@20.3.0) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -1409,7 +1406,6 @@ packages: /@angular/compiler-cli@15.2.9(@angular/compiler@15.2.9)(typescript@4.9.5): resolution: {integrity: sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler': 15.2.9 typescript: '>=4.8.2 <5.0' @@ -8180,7 +8176,7 @@ packages: remark-slug: 6.1.0 rollup: 3.25.0 typescript: 4.9.5 - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) transitivePeerDependencies: - supports-color dev: true @@ -8565,7 +8561,7 @@ packages: svelte: 3.59.1 sveltedoc-parser: 4.2.1 ts-dedent: 2.2.0 - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) transitivePeerDependencies: - '@preact/preset-vite' - supports-color @@ -8659,7 +8655,6 @@ packages: /@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9): resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==} engines: {node: ^16.14 || >=18} - hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 @@ -8679,7 +8674,7 @@ packages: svelte: 3.59.1 tiny-glob: 0.2.9 undici: 5.22.1 - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) transitivePeerDependencies: - supports-color dev: true @@ -8687,7 +8682,6 @@ packages: /@sveltejs/package@2.0.2(svelte@3.59.1)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} - hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -8711,7 +8705,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.1(svelte@3.59.1)(vite@4.3.9) debug: 4.3.4 svelte: 3.59.1 - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) transitivePeerDependencies: - supports-color dev: true @@ -8730,7 +8724,7 @@ packages: magic-string: 0.30.0 svelte: 3.59.1 svelte-hmr: 0.15.2(svelte@3.59.1) - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) vitefu: 0.2.4(vite@4.3.9) transitivePeerDependencies: - supports-color @@ -9337,12 +9331,6 @@ packages: dependencies: '@types/node': 18.16.17 - /@types/cookie-parser@1.4.3: - resolution: {integrity: sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==} - dependencies: - '@types/express': 4.17.17 - dev: true - /@types/cookie@0.4.1: resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} @@ -10611,7 +10599,6 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10626,7 +10613,6 @@ packages: /autoprefixer@10.4.14(postcss@8.4.24): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} - hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -13019,7 +13005,6 @@ packages: /eslint-config-prettier@8.8.0(eslint@7.32.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} - hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -14488,7 +14473,6 @@ packages: /glob@10.2.7: resolution: {integrity: sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==} engines: {node: '>=16 || 14 >=14.17'} - hasBin: true dependencies: foreground-child: 3.1.1 jackspeak: 2.2.1 @@ -15890,7 +15874,6 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15920,7 +15903,6 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.22.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} - hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -17577,12 +17559,10 @@ packages: /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} - hasBin: true /mkdirp@2.1.6: resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} engines: {node: '>=10'} - hasBin: true dev: true /mlly@1.4.0: @@ -17627,7 +17607,6 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17663,7 +17642,6 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} - hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17805,7 +17783,6 @@ packages: /next-sitemap@3.1.55(@next/env@13.4.5)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -17831,7 +17808,6 @@ packages: /next@13.3.4(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17875,7 +17851,6 @@ packages: /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} - hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17987,7 +17962,6 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.9)(tslib@2.5.3)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} - hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -18882,7 +18856,6 @@ packages: /pino@8.14.1: resolution: {integrity: sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==} - hasBin: true dependencies: atomic-sleep: 1.0.0 fast-redact: 3.2.0 @@ -20101,7 +20074,6 @@ packages: /resolve@1.22.2: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -20109,7 +20081,6 @@ packages: /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} - hasBin: true dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 @@ -20155,14 +20126,12 @@ packages: /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - hasBin: true dependencies: glob: 7.2.3 dev: true /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - hasBin: true dependencies: glob: 7.2.3 dev: true @@ -20385,11 +20354,9 @@ packages: /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true /semver@7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} - hasBin: true dev: true /semver@7.3.8: @@ -20401,7 +20368,6 @@ packages: /semver@7.5.1: resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} engines: {node: '>=10'} - hasBin: true dependencies: lru-cache: 6.0.0 @@ -21237,7 +21203,6 @@ packages: /svelte-check@2.10.3(@babel/core@7.22.5)(svelte@3.59.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} - hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -21766,7 +21731,6 @@ packages: /ts-node-dev@2.0.0(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} engines: {node: '>=0.8.0'} - hasBin: true peerDependencies: node-notifier: '*' typescript: '*' @@ -21793,7 +21757,6 @@ packages: /ts-node@10.9.1(@types/node@18.16.17)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21823,7 +21786,6 @@ packages: /ts-node@10.9.1(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21897,7 +21859,6 @@ packages: /tsup@6.7.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} engines: {node: '>=14.18'} - hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -22374,7 +22335,6 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22384,7 +22344,6 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.7): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22592,7 +22551,7 @@ packages: kolorist: 1.8.0 magic-string: 0.29.0 ts-morph: 18.0.0 - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) transitivePeerDependencies: - '@types/node' - rollup @@ -22602,7 +22561,6 @@ packages: /vite@3.2.7: resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22635,7 +22593,6 @@ packages: /vite@4.3.9(@types/node@18.16.17): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22668,7 +22625,6 @@ packages: /vite@4.3.9(@types/node@20.3.0): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22706,13 +22662,12 @@ packages: vite: optional: true dependencies: - vite: 4.3.9(@types/node@18.16.17) + vite: 4.3.9(@types/node@20.3.0) dev: true /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22758,7 +22713,6 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22971,7 +22925,6 @@ packages: /webpack-dev-server@4.11.1(webpack@5.76.1): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} - hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -23054,7 +23007,6 @@ packages: /webpack@5.76.1(esbuild@0.17.8): resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} - hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: From 76c2a88dbe13c09d6f2147a971186d8f0244c50e Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 19:30:53 +0200 Subject: [PATCH 67/68] add cookie parser types --- packages/nodejs/package.json | 1 + pnpm-lock.yaml | 55 ++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 68d3920c..cb1324f1 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -42,6 +42,7 @@ "ts-toolbelt": "^9.6.0" }, "devDependencies": { + "@types/cookie-parser": "^1.4.3", "@types/express": "^4.17.17", "@types/jest": "^29.5.1", "@types/node": "^20.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0513171..2cde6202 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -678,7 +678,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@20.3.0) + version: 4.3.9(@types/node@18.16.17) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -796,6 +796,9 @@ importers: specifier: ^9.6.0 version: 9.6.0 devDependencies: + '@types/cookie-parser': + specifier: ^1.4.3 + version: 1.4.3 '@types/express': specifier: ^4.17.17 version: 4.17.17 @@ -1001,7 +1004,7 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.3.9(@types/node@20.3.0) + version: 4.3.9(@types/node@18.16.17) vite-plugin-dts: specifier: 2.3.0 version: 2.3.0(vite@4.3.9) @@ -1406,6 +1409,7 @@ packages: /@angular/compiler-cli@15.2.9(@angular/compiler@15.2.9)(typescript@4.9.5): resolution: {integrity: sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler': 15.2.9 typescript: '>=4.8.2 <5.0' @@ -8176,7 +8180,7 @@ packages: remark-slug: 6.1.0 rollup: 3.25.0 typescript: 4.9.5 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8561,7 +8565,7 @@ packages: svelte: 3.59.1 sveltedoc-parser: 4.2.1 ts-dedent: 2.2.0 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - '@preact/preset-vite' - supports-color @@ -8655,6 +8659,7 @@ packages: /@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9): resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==} engines: {node: ^16.14 || >=18} + hasBin: true requiresBuild: true peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 @@ -8674,7 +8679,7 @@ packages: svelte: 3.59.1 tiny-glob: 0.2.9 undici: 5.22.1 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8682,6 +8687,7 @@ packages: /@sveltejs/package@2.0.2(svelte@3.59.1)(typescript@4.9.5): resolution: {integrity: sha512-cCOCcO8yMHnhHyaR51nQtvKZ3o/vSU9UYI1EXLT1j2CKNPMuH1/g6JNwKcNNrtQGwwquudc69ZeYy8D/TDNwEw==} engines: {node: ^16.14 || >=18} + hasBin: true peerDependencies: svelte: ^3.44.0 dependencies: @@ -8705,7 +8711,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.1(svelte@3.59.1)(vite@4.3.9) debug: 4.3.4 svelte: 3.59.1 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - supports-color dev: true @@ -8724,7 +8730,7 @@ packages: magic-string: 0.30.0 svelte: 3.59.1 svelte-hmr: 0.15.2(svelte@3.59.1) - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) vitefu: 0.2.4(vite@4.3.9) transitivePeerDependencies: - supports-color @@ -9331,6 +9337,12 @@ packages: dependencies: '@types/node': 18.16.17 + /@types/cookie-parser@1.4.3: + resolution: {integrity: sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==} + dependencies: + '@types/express': 4.17.17 + dev: true + /@types/cookie@0.4.1: resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} @@ -10599,6 +10611,7 @@ packages: /autoprefixer@10.4.13(postcss@8.4.21): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -10613,6 +10626,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.24): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -13005,6 +13019,7 @@ packages: /eslint-config-prettier@8.8.0(eslint@7.32.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -15874,6 +15889,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.21.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -15903,6 +15919,7 @@ packages: /jscodeshift@0.14.0(@babel/preset-env@7.22.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: @@ -17607,6 +17624,7 @@ packages: /msw@0.49.3(typescript@4.9.5): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17642,6 +17660,7 @@ packages: /msw@0.49.3(typescript@5.0.4): resolution: {integrity: sha512-kRCbDNbNnRq5LC1H/NUceZlrPAvSrMH6Or0mirIuH69NY84xwDruPn/hkXTovIK1KwDwbk+ZdoSyJlpiekLxEA==} engines: {node: '>=14'} + hasBin: true requiresBuild: true peerDependencies: typescript: '>= 4.4.x <= 4.9.x' @@ -17783,6 +17802,7 @@ packages: /next-sitemap@3.1.55(@next/env@13.4.5)(next@13.3.4): resolution: {integrity: sha512-ZjkRfkqoSLbU+e8W9TWWe0zfOGNA47lpvm35kNcUCmj73gpLX2PIn51gwHT/B6bgGVAFYY0OXixJDrxIIwcEHw==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@next/env': '*' next: '*' @@ -17808,6 +17828,7 @@ packages: /next@13.3.4(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17851,6 +17872,7 @@ packages: /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} + hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 fibers: '>= 3.1.0' @@ -17962,6 +17984,7 @@ packages: /ng-packagr@15.2.2(@angular/compiler-cli@15.2.9)(tslib@2.5.3)(typescript@4.9.5): resolution: {integrity: sha512-+042GBD35ztxbHywGJloAiDM/s3Ja3TZtQh361TWqd/xza3K5DMUu6VRGLTgMwG7CW1YsqYHWgMZslP1c+ng7A==} engines: {node: ^14.20.0 || ^16.13.0 || >=18.10.0} + hasBin: true peerDependencies: '@angular/compiler-cli': ^15.0.0 || ^15.2.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 @@ -21203,6 +21226,7 @@ packages: /svelte-check@2.10.3(@babel/core@7.22.5)(svelte@3.59.1): resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true peerDependencies: svelte: ^3.24.0 dependencies: @@ -21731,6 +21755,7 @@ packages: /ts-node-dev@2.0.0(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} engines: {node: '>=0.8.0'} + hasBin: true peerDependencies: node-notifier: '*' typescript: '*' @@ -21757,6 +21782,7 @@ packages: /ts-node@10.9.1(@types/node@18.16.17)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21786,6 +21812,7 @@ packages: /ts-node@10.9.1(@types/node@20.3.0)(typescript@5.0.4): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' @@ -21859,6 +21886,7 @@ packages: /tsup@6.7.0(ts-node@10.9.1)(typescript@5.0.4): resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} engines: {node: '>=14.18'} + hasBin: true peerDependencies: '@swc/core': ^1 postcss: ^8.4.12 @@ -22335,6 +22363,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22344,6 +22373,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.7): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: @@ -22551,7 +22581,7 @@ packages: kolorist: 1.8.0 magic-string: 0.29.0 ts-morph: 18.0.0 - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) transitivePeerDependencies: - '@types/node' - rollup @@ -22561,6 +22591,7 @@ packages: /vite@3.2.7: resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22593,6 +22624,7 @@ packages: /vite@4.3.9(@types/node@18.16.17): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22625,6 +22657,7 @@ packages: /vite@4.3.9(@types/node@20.3.0): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true peerDependencies: '@types/node': '>= 14' less: '*' @@ -22662,12 +22695,13 @@ packages: vite: optional: true dependencies: - vite: 4.3.9(@types/node@20.3.0) + vite: 4.3.9(@types/node@18.16.17) dev: true /vitest@0.25.8(jsdom@20.0.3): resolution: {integrity: sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==} engines: {node: '>=v14.16.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22713,6 +22747,7 @@ packages: /vitest@0.31.4: resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} engines: {node: '>=v14.18.0'} + hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@vitest/browser': '*' @@ -22925,6 +22960,7 @@ packages: /webpack-dev-server@4.11.1(webpack@5.76.1): resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} engines: {node: '>= 12.13.0'} + hasBin: true peerDependencies: webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' @@ -23007,6 +23043,7 @@ packages: /webpack@5.76.1(esbuild@0.17.8): resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} + hasBin: true peerDependencies: webpack-cli: '*' peerDependenciesMeta: From a6b24a7ac7fc3445ddb9da8557fffc17025eca6b Mon Sep 17 00:00:00 2001 From: Tim Trost <82676248+Tim-53@users.noreply.github.com> Date: Thu, 13 Jul 2023 20:01:36 +0200 Subject: [PATCH 68/68] fix core tests --- packages/core/src/shared/helpers.ts | 2 +- packages/core/tests/base.test.ts | 156 +++++++++++++++------------- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/packages/core/src/shared/helpers.ts b/packages/core/src/shared/helpers.ts index c0a8fa9e..3f0e9304 100644 --- a/packages/core/src/shared/helpers.ts +++ b/packages/core/src/shared/helpers.ts @@ -9,5 +9,5 @@ export function getFFStorageKey(projectId: string, flagName: string): string { } export function assertUnreachable(x: never): never { - throw new Error("Reached unreachable code"); + throw new Error(`Reached unreachable code: ${x}`); } diff --git a/packages/core/tests/base.test.ts b/packages/core/tests/base.test.ts index 77215254..12c7de31 100644 --- a/packages/core/tests/base.test.ts +++ b/packages/core/tests/base.test.ts @@ -122,144 +122,158 @@ describe("Abby", () => { expect(abby.getFeatureFlag("flag1")).toBe(false); }); - it("refetches an expired flag", async () =>{ - const date = new Date() //current date - vi.setSystemTime(date) + it("refetches an expired flag", async () => { + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { + flag1: "Boolean", + flag2: "String", + }, flagCacheConfig: { refetchFlags: true, - timeToLive: 2 - } + timeToLive: 2, + }, }); - await abby.loadProjectData() - const expiredDate = new Date(new Date().getTime() + 1000 * 60 * 10) //date in 100 minutes - vi.setSystemTime(expiredDate) - const spy = vi.spyOn(abby, "refetchFlags") + await abby.loadProjectData(); + const expiredDate = new Date(new Date().getTime() + 1000 * 60 * 10); //date in 100 minutes + vi.setSystemTime(expiredDate); + const spy = vi.spyOn(abby, "refetchFlags"); - expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).toBeCalled() - }) + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).toBeCalled(); + }); it("non expired flag does not get refetched", async () => { - const date = new Date() //current date - vi.setSystemTime(date) + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { + flag1: "Boolean", + flag2: "Boolean", + }, flagCacheConfig: { refetchFlags: true, - timeToLive: 2 - } + timeToLive: 2, + }, }); await abby.loadProjectData(); - const spy = vi.spyOn(abby, "refetchFlags") + const spy = vi.spyOn(abby, "refetchFlags"); expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).not.toBeCalled() - }) + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).not.toBeCalled(); + }); it("respects the featureFlagCacheConfig refetchFlags value set to false", async () => { - const date = new Date() //current date - vi.setSystemTime(date) + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { + flag1: "Boolean", + flag2: "Boolean", + }, flagCacheConfig: { refetchFlags: false, - timeToLive: 2 - } + timeToLive: 2, + }, }); await abby.loadProjectData(); - const spy = vi.spyOn(abby, "refetchFlags") + const spy = vi.spyOn(abby, "refetchFlags"); expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).not.toBeCalled() - }) + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).not.toBeCalled(); + }); - it("", async () => { - const date = new Date() //current date - vi.setSystemTime(date) + it("it refetches expired flags", async () => { + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { + flag1: "Boolean", + flag2: "Boolean", + }, flagCacheConfig: { refetchFlags: true, - timeToLive: 2 - } + timeToLive: 2, + }, }); await abby.loadProjectData(); - const spy = vi.spyOn(abby, "refetchFlags") + const spy = vi.spyOn(abby, "refetchFlags"); //set date to 5 Minutes in the future - const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); - vi.setSystemTime(dateIn3Minutes) + const dateIn5Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); + vi.setSystemTime(dateIn5Minutes); expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).toBeCalled() - }) + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).toBeCalled(); + }); it("respects the featureFlagCacheCOnfig expiration time", async () => { - const date = new Date() //current date - vi.setSystemTime(date) + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { + flag1: "Boolean", + flag2: "Boolean", + }, flagCacheConfig: { refetchFlags: true, - timeToLive: 2 - } + timeToLive: 2, + }, }); await abby.loadProjectData(); - - const spy = vi.spyOn(abby, "refetchFlags") - + + const spy = vi.spyOn(abby, "refetchFlags"); + expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).not.toBeCalled() + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).not.toBeCalled(); //set date to 5 Minutes in the future const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); - vi.setSystemTime(dateIn3Minutes) + vi.setSystemTime(dateIn3Minutes); expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).toBeCalled() - }) - + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).toBeCalled(); + }); }); it("respects the default behaviour", async () => { - const date = new Date() //current date - vi.setSystemTime(date) + const date = new Date(); //current date + vi.setSystemTime(date); const abby = new Abby({ projectId: "expired", - flags: ["flag1", "flag2"], + flags: { flag1: "Boolean", flag2: "Boolean" }, }); await abby.loadProjectData(); - - const spy = vi.spyOn(abby, "refetchFlags") - - //set date to 5 Minutes in the future - const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); - vi.setSystemTime(dateIn3Minutes) + + const spy = vi.spyOn(abby, "refetchFlags"); + + //set date to 5 Minutes in the future + const dateIn3Minutes = new Date(new Date().getTime() + 1000 * 60 * 5); + vi.setSystemTime(dateIn3Minutes); expect(abby.getFeatureFlag("flag1")).toBeTruthy(); - expect(abby.getFeatureFlag("flag2")).toBeFalsy(); - expect(spy).not.toBeCalled() -}) + expect(abby.getFeatureFlag("flag2")).toBe("test"); + expect(spy).not.toBeCalled(); +}); describe("Math helpers", () => { it("validates weight", () => {