diff --git a/api/package.json b/api/package.json index da74c1148ee..10a8b9fc521 100644 --- a/api/package.json +++ b/api/package.json @@ -13,6 +13,7 @@ "@fastify/swagger": "8.14.0", "@fastify/swagger-ui": "1.10.2", "@fastify/type-provider-typebox": "3.6.0", + "@growthbook/growthbook": "1.3.1", "@immobiliarelabs/fastify-sentry": "7.1.1", "@prisma/client": "5.5.2", "ajv": "8.12.0", diff --git a/api/src/app.ts b/api/src/app.ts index 1596468b2ca..317e8d78161 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -2,6 +2,7 @@ import fastifyAccepts from '@fastify/accepts'; import fastifySwagger from '@fastify/swagger'; import fastifySwaggerUI from '@fastify/swagger-ui'; import type { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; +import { GrowthBook } from '@growthbook/growthbook'; import Ajv from 'ajv'; import addFormats from 'ajv-formats'; import uriResolver from 'fast-uri'; @@ -28,6 +29,7 @@ import errorHandling from './plugins/error-handling'; import csrf from './plugins/csrf'; import notFound from './plugins/not-found'; import shadowCapture from './plugins/shadow-capture'; +import growthBook from './plugins/growth-book'; import * as publicRoutes from './routes/public'; import * as protectedRoutes from './routes/protected'; @@ -39,7 +41,9 @@ import { FCC_ENABLE_SWAGGER_UI, FCC_ENABLE_SHADOW_CAPTURE, FCC_ENABLE_EXAM_ENVIRONMENT, - FCC_ENABLE_SENTRY_ROUTES + FCC_ENABLE_SENTRY_ROUTES, + GROWTHBOOK_FASTIFY_API_HOST, + GROWTHBOOK_FASTIFY_CLIENT_KEY } from './utils/env'; import { isObjectID } from './utils/validation'; import { @@ -55,6 +59,12 @@ type FastifyInstanceWithTypeProvider = FastifyInstance< TypeBoxTypeProvider >; +declare module 'fastify' { + interface FastifyInstance { + gb: GrowthBook; + } +} + // Options that fastify uses const ajv = new Ajv({ coerceTypes: 'array', // change data type of data to match type keyword @@ -99,12 +109,17 @@ export const build = async ( await fastify.register(cookies); await fastify.register(csrf); + await fastify.register(growthBook, { + apiHost: GROWTHBOOK_FASTIFY_API_HOST, + clientKey: GROWTHBOOK_FASTIFY_CLIENT_KEY + }); + const provider = EMAIL_PROVIDER === 'ses' ? new SESProvider() : new NodemailerProvider(); void fastify.register(mailer, { provider }); // Swagger plugin - if (FCC_ENABLE_SWAGGER_UI) { + if (FCC_ENABLE_SWAGGER_UI || fastify.gb.isOn('swagger-ui')) { void fastify.register(fastifySwagger, { openapi: { openapi: '3.1.0', @@ -132,7 +147,7 @@ export const build = async ( fastify.log.info(`Swagger UI available at ${API_LOCATION}/documentation`); } - if (FCC_ENABLE_SHADOW_CAPTURE) { + if (FCC_ENABLE_SHADOW_CAPTURE || fastify.gb.isOn('shadow-capture')) { void fastify.register(shadowCapture); } @@ -189,7 +204,7 @@ export const build = async ( } }); - if (FCC_ENABLE_EXAM_ENVIRONMENT) { + if (FCC_ENABLE_EXAM_ENVIRONMENT || fastify.gb.isOn('exam-environment')) { void fastify.register(function (fastify, _opts, done) { fastify.addHook('onRequest', fastify.authorizeExamEnvironmentToken); @@ -199,7 +214,7 @@ export const build = async ( void fastify.register(examEnvironmentOpenRoutes); } - if (FCC_ENABLE_SENTRY_ROUTES) { + if (FCC_ENABLE_SENTRY_ROUTES || fastify.gb.isOn('sentry-routes')) { void fastify.register(publicRoutes.sentryRoutes); } diff --git a/api/src/plugins/growth-book.ts b/api/src/plugins/growth-book.ts new file mode 100644 index 00000000000..3824e95774a --- /dev/null +++ b/api/src/plugins/growth-book.ts @@ -0,0 +1,16 @@ +import { GrowthBook, Options } from '@growthbook/growthbook'; +import { FastifyPluginAsync } from 'fastify'; +import fp from 'fastify-plugin'; + +const growthBook: FastifyPluginAsync = async (fastify, options) => { + const gb = new GrowthBook(options); + await gb.init({ timeout: 3000 }); + + fastify.decorate('gb', gb); + + fastify.addHook('onClose', () => { + gb.destroy(); + }); +}; + +export default fp(growthBook); diff --git a/api/src/utils/env.ts b/api/src/utils/env.ts index 836ab0bc6eb..8485afa9c35 100644 --- a/api/src/utils/env.ts +++ b/api/src/utils/env.ts @@ -126,6 +126,16 @@ if (process.env.FREECODECAMP_NODE_ENV !== 'development') { 'client_secret_from_auth0_dashboard', 'The Auth0 client secret should be changed from the default value.' ); + assert.notEqual( + process.env.GROWTHBOOK_FASTIFY_API_HOST, + 'fastify_api_sdk_api_host_from_growthbook_dashboard', + 'The GROWTHBOOK_FASTIFY_API_HOST env should be changed from the default value.' + ); + assert.notEqual( + process.env.GROWTHBOOK_FASTIFY_CLIENT_KEY, + 'fastify_api_sdk_client_key_from_growthbook_dashboard', + 'The GROWTHBOOK_FASTIFY_CLIENT_KEY env should be changed from the default value.' + ); } export const HOME_LOCATION = process.env.HOME_LOCATION; @@ -178,3 +188,7 @@ export const SES_REGION = process.env.SES_REGION || 'us-east-1'; export const SHOW_UPCOMING_CHANGES = process.env.SHOW_UPCOMING_CHANGES === 'true'; export const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY; +export const GROWTHBOOK_FASTIFY_API_HOST = + process.env.GROWTHBOOK_FASTIFY_API_HOST; +export const GROWTHBOOK_FASTIFY_CLIENT_KEY = + process.env.GROWTHBOOK_FASTIFY_CLIENT_KEY; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d50716be4b8..370cb4b4e50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,6 +159,9 @@ importers: '@fastify/type-provider-typebox': specifier: 3.6.0 version: 3.6.0(@sinclair/typebox@0.32.14) + '@growthbook/growthbook': + specifier: 1.3.1 + version: 1.3.1 '@immobiliarelabs/fastify-sentry': specifier: 7.1.1 version: 7.1.1 @@ -827,7 +830,7 @@ importers: version: 10.9.2(@types/node@20.12.8)(typescript@5.2.2) webpack: specifier: 5.90.3 - version: 5.90.3 + version: 5.90.3(webpack-cli@4.10.0) curriculum: devDependencies: @@ -1116,7 +1119,7 @@ importers: version: 4.3.12 '@types/copy-webpack-plugin': specifier: ^8.0.1 - version: 8.0.1(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3)) + version: 8.0.1(webpack-cli@4.10.0) '@types/enzyme': specifier: 3.10.16 version: 3.10.16 @@ -1134,13 +1137,13 @@ importers: version: 1.6.0(typescript@5.4.5) babel-loader: specifier: 8.3.0 - version: 8.3.0(@babel/core@7.23.7)(webpack@5.90.3(webpack-cli@4.10.0)) + version: 8.3.0(@babel/core@7.23.7)(webpack@5.90.3) chai: specifier: 4.4.1 version: 4.4.1 copy-webpack-plugin: specifier: 9.1.0 - version: 9.1.0(webpack@5.90.3(webpack-cli@4.10.0)) + version: 9.1.0(webpack@5.90.3) enzyme: specifier: 3.11.0 version: 3.11.0 @@ -3163,6 +3166,10 @@ packages: resolution: {integrity: sha512-ennMHKZIhAZokHHcnA9/tOTLFdBB4DQR0WHT8Lf1pD80jWVv8JBCAzsV1jzSjYUQhb8R8pLR2Kho0IfgjzIZGQ==} engines: {node: '>=10'} + '@growthbook/growthbook@1.3.1': + resolution: {integrity: sha512-ewtwq6+86rRKwcYUXEmBVR1JuiEIYZhxow/Z52qyAxJwEHdXmpS4Yk8sVeVD9bphCwE2r0zuifxFkBxmnIL4Mg==} + engines: {node: '>=10'} + '@hapi/address@2.1.4': resolution: {integrity: sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==} deprecated: Moved to 'npm install @sideway/address' @@ -4731,6 +4738,7 @@ packages: acorn-import-assertions@1.9.0: resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + deprecated: package has been renamed to acorn-import-attributes peerDependencies: acorn: ^8 @@ -6994,11 +7002,13 @@ packages: eslint@7.32.0: resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} engines: {node: ^10.12.0 || >=12.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@7.3.1: @@ -12410,6 +12420,7 @@ packages: sudo-prompt@8.2.5: resolution: {integrity: sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. superagent@8.1.2: resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} @@ -17136,6 +17147,10 @@ snapshots: dependencies: dom-mutator: 0.6.0 + '@growthbook/growthbook@1.3.1': + dependencies: + dom-mutator: 0.6.0 + '@hapi/address@2.1.4': {} '@hapi/boom@10.0.1': @@ -17544,7 +17559,7 @@ snapshots: react-refresh: 0.9.0 schema-utils: 2.7.1 source-map: 0.7.4 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) '@polka/url@1.0.0-next.23': {} @@ -18284,7 +18299,7 @@ snapshots: '@types/cookiejar@2.1.2': {} - '@types/copy-webpack-plugin@8.0.1(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3))': + '@types/copy-webpack-plugin@8.0.1(webpack-cli@4.10.0)': dependencies: '@types/node': 20.8.0 tapable: 2.2.1 @@ -19033,17 +19048,17 @@ snapshots: '@webassemblyjs/ast': 1.11.6 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3))(webpack@5.90.3(webpack-cli@4.10.0))': + '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.90.3)': dependencies: webpack: 5.90.3(webpack-cli@4.10.0) webpack-cli: 4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3) - '@webpack-cli/info@1.5.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3))': + '@webpack-cli/info@1.5.0(webpack-cli@4.10.0)': dependencies: envinfo: 7.10.0 webpack-cli: 4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3) - '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3))': + '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0)': dependencies: webpack-cli: 4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3) @@ -19527,9 +19542,9 @@ snapshots: loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) - babel-loader@8.3.0(@babel/core@7.23.7)(webpack@5.90.3(webpack-cli@4.10.0)): + babel-loader@8.3.0(@babel/core@7.23.7)(webpack@5.90.3): dependencies: '@babel/core': 7.23.7 find-cache-dir: 3.3.2 @@ -20650,7 +20665,7 @@ snapshots: copy-descriptor@0.1.1: {} - copy-webpack-plugin@9.1.0(webpack@5.90.3(webpack-cli@4.10.0)): + copy-webpack-plugin@9.1.0(webpack@5.90.3): dependencies: fast-glob: 3.3.1 glob-parent: 6.0.2 @@ -20831,7 +20846,7 @@ snapshots: postcss-value-parser: 4.2.0 schema-utils: 3.3.0 semver: 7.6.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) css-mediaquery@0.1.2: {} @@ -20844,7 +20859,7 @@ snapshots: schema-utils: 3.3.0 serialize-javascript: 5.0.1 source-map: 0.6.1 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) css-select@4.3.0: dependencies: @@ -21774,7 +21789,7 @@ snapshots: debug: 4.3.4(supports-color@8.1.1) enhanced-resolve: 5.15.0 eslint: 8.57.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) get-tsconfig: 4.7.2 globby: 13.2.2 @@ -21798,7 +21813,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0): dependencies: debug: 3.2.7(supports-color@5.5.0) optionalDependencies: @@ -21871,7 +21886,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -22052,7 +22067,7 @@ snapshots: micromatch: 4.0.5 normalize-path: 3.0.0 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) eslint@7.32.0: dependencies: @@ -22531,7 +22546,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) file-type@16.5.4: dependencies: @@ -22657,7 +22672,7 @@ snapshots: semver: 5.7.2 tapable: 1.1.3 typescript: 5.2.2 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) worker-rpc: 0.1.1 optionalDependencies: eslint: 7.32.0 @@ -23232,7 +23247,7 @@ snapshots: url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.3))(webpack@5.90.3) uuid: 3.4.0 v8-compile-cache: 2.4.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) webpack-dev-middleware: 4.3.0(webpack@5.90.3) webpack-merge: 5.9.0 webpack-stats-plugin: 1.1.3 @@ -26325,7 +26340,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) webpack-sources: 1.4.3 minimalistic-assert@1.0.1: {} @@ -26429,7 +26444,7 @@ snapshots: dependencies: loader-utils: 2.0.4 monaco-editor: 0.28.1 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) monaco-editor@0.28.1: {} @@ -26731,7 +26746,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) nwsapi@2.2.7: {} @@ -27310,7 +27325,7 @@ snapshots: postcss: 8.4.35 schema-utils: 3.3.0 semver: 7.6.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) postcss-loader@5.3.0(postcss@8.4.35)(webpack@5.90.3): dependencies: @@ -27318,7 +27333,7 @@ snapshots: klona: 2.0.6 postcss: 8.4.35 semver: 7.6.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) postcss-merge-longhand@5.1.7(postcss@8.4.35): dependencies: @@ -27782,7 +27797,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) rc@1.2.8: dependencies: @@ -27817,7 +27832,7 @@ snapshots: shell-quote: 1.7.2 strip-ansi: 6.0.0 text-table: 0.2.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: @@ -29323,7 +29338,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) style-to-object@0.3.0: dependencies: @@ -29464,7 +29479,7 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.10(webpack@5.90.3(webpack-cli@4.10.0)): + terser-webpack-plugin@5.3.10(webpack@5.90.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 @@ -29473,15 +29488,6 @@ snapshots: terser: 5.28.1 webpack: 5.90.3(webpack-cli@4.10.0) - terser-webpack-plugin@5.3.10(webpack@5.90.3): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.1 - terser: 5.28.1 - webpack: 5.90.3 - terser-webpack-plugin@5.3.9(webpack@5.90.3): dependencies: '@jridgewell/trace-mapping': 0.3.22 @@ -29489,7 +29495,7 @@ snapshots: schema-utils: 3.3.0 serialize-javascript: 6.0.1 terser: 5.20.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) terser@5.20.0: dependencies: @@ -30139,7 +30145,7 @@ snapshots: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) optionalDependencies: file-loader: 6.2.0(webpack@5.90.3) @@ -30354,9 +30360,9 @@ snapshots: webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3))(webpack@5.90.3(webpack-cli@4.10.0)) - '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3)) - '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.1)(webpack@5.90.3)) + '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0)(webpack@5.90.3) + '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0) + '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0) colorette: 2.0.20 commander: 7.2.0 cross-spawn: 7.0.3 @@ -30377,7 +30383,7 @@ snapshots: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 3.3.0 - webpack: 5.90.3 + webpack: 5.90.3(webpack-cli@4.10.0) webpack-merge@5.9.0: dependencies: @@ -30399,37 +30405,6 @@ snapshots: transitivePeerDependencies: - supports-color - webpack@5.90.3: - dependencies: - '@types/eslint-scope': 3.7.5 - '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/wasm-edit': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) - browserslist: 4.23.0 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.3.1 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.90.3) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - webpack@5.90.3(webpack-cli@4.10.0): dependencies: '@types/eslint-scope': 3.7.5 @@ -30453,7 +30428,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.90.3(webpack-cli@4.10.0)) + terser-webpack-plugin: 5.3.10(webpack@5.90.3) watchpack: 2.4.0 webpack-sources: 3.2.3 optionalDependencies: diff --git a/sample.env b/sample.env index c7f2c04c4f8..d572bd1970f 100644 --- a/sample.env +++ b/sample.env @@ -32,6 +32,8 @@ PATREON_CLIENT_ID=id_from_patreon_dashboard # Analytics GROWTHBOOK_URI=api_URI_from_Growthbook_dashboard +GROWTHBOOK_FASTIFY_API_HOST=fastify_api_sdk_api_host_from_growthbook_dashboard +GROWTHBOOK_FASTIFY_CLIENT_KEY=fastify_api_sdk_client_key_from_growthbook_dashboard # Application paths HOME_LOCATION=http://localhost:8000