From 57043fc94d4b9077ed4bbf2ed91c595f621147f7 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Tue, 2 Nov 2021 23:46:28 +0530 Subject: [PATCH 1/7] adds override usage in email password (contains a bug though) --- lib/build/override.d.ts | 13 ++++ lib/build/override.js | 70 ++++++++++++++++++ lib/build/recipe/emailpassword/recipe.js | 15 +++- lib/build/recipe/emailpassword/types.d.ts | 20 +++-- lib/ts/override.ts | 89 +++++++++++++++++++++++ lib/ts/recipe/emailpassword/recipe.ts | 13 +++- lib/ts/recipe/emailpassword/types.ts | 20 +++-- 7 files changed, 220 insertions(+), 20 deletions(-) create mode 100644 lib/build/override.d.ts create mode 100644 lib/build/override.js create mode 100644 lib/ts/override.ts diff --git a/lib/build/override.d.ts b/lib/build/override.d.ts new file mode 100644 index 000000000..dae8c2fd2 --- /dev/null +++ b/lib/build/override.d.ts @@ -0,0 +1,13 @@ +// @ts-nocheck +export default class OverrideableBuilder any)>> { + private layers; + private proxies; + result?: T; + constructor(originalImplementation: T); + addLayer( + overrideFunc: + | ((originalImplementation: T) => T) + | ((originalImplementation: T, builder: OverrideableBuilder) => T) + ): OverrideableBuilder; + build(): T; +} diff --git a/lib/build/override.js b/lib/build/override.js new file mode 100644 index 000000000..ed6d284cf --- /dev/null +++ b/lib/build/override.js @@ -0,0 +1,70 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function getProxyObject(orig) { + const ret = Object.assign(Object.assign({}, orig), { + _call: (_, __) => { + throw new Error("This function should only be called through the recipe object"); + }, + }); + const keys = Object.keys(ret); + for (const k of keys) { + if (k !== "_call") { + ret[k] = function (...args) { + return this._call(k, args); + }; + } + } + return ret; +} +class OverrideableBuilder { + constructor(originalImplementation) { + this.layers = [originalImplementation]; + this.proxies = []; + } + addLayer(overrideFunc) { + const proxy = getProxyObject(this.layers[0]); + const layer = overrideFunc(proxy, this); + for (const key of Object.keys(this.layers[0])) { + if (layer[key] === proxy[key] || key === "_call") { + delete layer[key]; + } + if (layer[key] === undefined) { + layer[key] = null; + } + } + this.layers.push(layer); + this.proxies.push(proxy); + return this; + } + build() { + if (this.result) { + return this.result; + } + this.result = {}; + for (const layer of this.layers) { + for (const key of Object.keys(layer)) { + const func = layer[key]; + if (func !== undefined) { + if (func === null) { + this.result[key] = undefined; + } else { + this.result[key] = func.bind(this.result); + } + } + } + } + for (let proxyInd = 0; proxyInd < this.proxies.length; ++proxyInd) { + const proxy = this.proxies[proxyInd]; + proxy._call = (fname, args) => { + for (let i = proxyInd; i >= 0; --i) { + const func = this.layers[i][fname]; + if (func !== undefined) { + return func.bind(this.result)(...args); + } + } + }; + } + return this.result; + } +} +exports.default = OverrideableBuilder; diff --git a/lib/build/recipe/emailpassword/recipe.js b/lib/build/recipe/emailpassword/recipe.js index 58ec1d510..59f6df265 100644 --- a/lib/build/recipe/emailpassword/recipe.js +++ b/lib/build/recipe/emailpassword/recipe.js @@ -60,6 +60,7 @@ const recipe_1 = require("../emailverification/recipe"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); +const override_1 = require("../../override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -170,10 +171,16 @@ class Recipe extends recipeModule_1.default { isInServerlessEnv, Object.assign({}, this.config.emailVerificationFeature) ); - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) + ); + this.recipeInterfaceImpl = builder.addLayer(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.addLayer(this.config.override.apis).build(); + } } static getInstanceOrThrowError() { if (Recipe.instance !== undefined) { diff --git a/lib/build/recipe/emailpassword/types.d.ts b/lib/build/recipe/emailpassword/types.d.ts index c543617a1..19be07c3f 100644 --- a/lib/build/recipe/emailpassword/types.d.ts +++ b/lib/build/recipe/emailpassword/types.d.ts @@ -5,14 +5,22 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export declare type TypeNormalisedInput = { signUpFeature: TypeNormalisedInputSignUp; signInFeature: TypeNormalisedInputSignIn; resetPasswordUsingTokenFeature: TypeNormalisedInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: + | ((originalImplementation: RecipeInterface) => RecipeInterface) + | (( + originalImplementation: RecipeInterface, + builder: OverrideableBuilder + ) => RecipeInterface); + apis: + | ((originalImplementation: APIInterface) => APIInterface) + | ((originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface); emailVerificationFeature?: { functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; @@ -144,7 +152,7 @@ export declare const InputSchema: { }; additionalProperties: boolean; }; -export interface RecipeInterface { +export declare type RecipeInterface = { signUp(input: { email: string; password: string; @@ -195,7 +203,7 @@ export interface RecipeInterface { }): Promise<{ status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; }>; -} +}; export declare type APIOptions = { recipeImplementation: RecipeInterface; emailVerificationRecipeImplementation: EmailVerificationRecipeInterface; @@ -205,7 +213,7 @@ export declare type APIOptions = { req: BaseRequest; res: BaseResponse; }; -export interface APIInterface { +export declare type APIInterface = { emailExistsGET: | undefined | ((input: { @@ -272,4 +280,4 @@ export interface APIInterface { status: "EMAIL_ALREADY_EXISTS_ERROR"; } >); -} +}; diff --git a/lib/ts/override.ts b/lib/ts/override.ts new file mode 100644 index 000000000..e9df3d755 --- /dev/null +++ b/lib/ts/override.ts @@ -0,0 +1,89 @@ +type ProxiedImplementation = { + [P in keyof T]: T[P]; +} & { + _call: (fname: K, args: any[]) => T[K]; +}; + +function getProxyObject any)>>(orig: T): T { + const ret: ProxiedImplementation = { + ...orig, + _call: (_, __) => { + throw new Error("This function should only be called through the recipe object"); + }, + }; + const keys = Object.keys(ret) as (keyof typeof ret)[]; + for (const k of keys) { + if (k !== "_call") { + ret[k] = function (this: ProxiedImplementation, ...args: any[]) { + return this._call(k, args); + } as ProxiedImplementation[keyof T]; + } + } + return ret; +} + +export default class OverrideableBuilder any)>> { + private layers: [T, ...Partial[]]; + private proxies: T[]; + result?: T; + + constructor(originalImplementation: T) { + this.layers = [originalImplementation]; + this.proxies = []; + } + + addLayer( + overrideFunc: + | ((originalImplementation: T) => T) + | ((originalImplementation: T, builder: OverrideableBuilder) => T) + ): OverrideableBuilder { + const proxy = getProxyObject(this.layers[0]) as T; + const layer = overrideFunc(proxy, this); + for (const key of Object.keys(this.layers[0]) as (keyof T)[]) { + if (layer[key] === proxy[key] || key === "_call") { + delete layer[key]; + } + if (layer[key] === undefined) { + layer[key] = null as any; + } + } + + this.layers.push(layer); + this.proxies.push(proxy); + + return this; + } + + build() { + if (this.result) { + return this.result; + } + + this.result = {} as T; + for (const layer of this.layers) { + for (const key of Object.keys(layer) as (keyof T)[]) { + const func = layer[key]; + if (func !== undefined) { + if (func === null) { + this.result[key] = undefined as any; + } else { + this.result[key] = func.bind(this.result) as T[keyof T]; + } + } + } + } + + for (let proxyInd = 0; proxyInd < this.proxies.length; ++proxyInd) { + const proxy = this.proxies[proxyInd]; + (proxy as any)._call = (fname: K, args: any) => { + for (let i = proxyInd; i >= 0; --i) { + const func = this.layers[i][fname]; + if (func !== undefined) { + return func.bind(this.result)(...args); + } + } + }; + } + return this.result; + } +} diff --git a/lib/ts/recipe/emailpassword/recipe.ts b/lib/ts/recipe/emailpassword/recipe.ts index 00122db82..1504692e8 100644 --- a/lib/ts/recipe/emailpassword/recipe.ts +++ b/lib/ts/recipe/emailpassword/recipe.ts @@ -37,6 +37,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; @@ -70,10 +71,14 @@ export default class Recipe extends RecipeModule { : new EmailVerificationRecipe(recipeId, appInfo, isInServerlessEnv, { ...this.config.emailVerificationFeature, }); - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(APIImplementation()); + { + let builder = new OverrideableBuilder(RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId))); + this.recipeInterfaceImpl = builder.addLayer(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.addLayer(this.config.override.apis).build(); + } } static getInstanceOrThrowError(): Recipe { diff --git a/lib/ts/recipe/emailpassword/types.ts b/lib/ts/recipe/emailpassword/types.ts index 8774119ed..6ffc8225a 100644 --- a/lib/ts/recipe/emailpassword/types.ts +++ b/lib/ts/recipe/emailpassword/types.ts @@ -19,6 +19,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; const TypeString = { type: "string", @@ -38,8 +39,15 @@ export type TypeNormalisedInput = { resetPasswordUsingTokenFeature: TypeNormalisedInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: + | ((originalImplementation: RecipeInterface) => RecipeInterface) + | (( + originalImplementation: RecipeInterface, + builder: OverrideableBuilder + ) => RecipeInterface); + apis: + | ((originalImplementation: APIInterface) => APIInterface) + | ((originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface); emailVerificationFeature?: { functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; @@ -159,7 +167,7 @@ export const InputSchema = { additionalProperties: false, }; -export interface RecipeInterface { +export type RecipeInterface = { signUp(input: { email: string; password: string; @@ -188,7 +196,7 @@ export interface RecipeInterface { email?: string; password?: string; }): Promise<{ status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR" }>; -} +}; export type APIOptions = { recipeImplementation: RecipeInterface; @@ -200,7 +208,7 @@ export type APIOptions = { res: BaseResponse; }; -export interface APIInterface { +export type APIInterface = { emailExistsGET: | undefined | ((input: { @@ -271,4 +279,4 @@ export interface APIInterface { status: "EMAIL_ALREADY_EXISTS_ERROR"; } >); -} +}; From 75a757b9d8775754da5f50a15cfac19981c09992 Mon Sep 17 00:00:00 2001 From: Mihaly Lengyel Date: Tue, 2 Nov 2021 19:45:22 +0100 Subject: [PATCH 2/7] Fixed disabling APIs in overrides --- lib/build/override.js | 3 +-- lib/ts/override.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/build/override.js b/lib/build/override.js index ed6d284cf..dd333855c 100644 --- a/lib/build/override.js +++ b/lib/build/override.js @@ -27,8 +27,7 @@ class OverrideableBuilder { for (const key of Object.keys(this.layers[0])) { if (layer[key] === proxy[key] || key === "_call") { delete layer[key]; - } - if (layer[key] === undefined) { + } else if (layer[key] === undefined) { layer[key] = null; } } diff --git a/lib/ts/override.ts b/lib/ts/override.ts index e9df3d755..b8ff3d276 100644 --- a/lib/ts/override.ts +++ b/lib/ts/override.ts @@ -42,8 +42,7 @@ export default class OverrideableBuilder Date: Wed, 3 Nov 2021 01:22:19 +0530 Subject: [PATCH 3/7] adds override to email verification --- lib/build/override.d.ts | 6 +- lib/build/override.js | 2 +- lib/build/recipe/emailpassword/recipe.js | 4 +- lib/build/recipe/emailpassword/types.d.ts | 41 +++++--- lib/build/recipe/emailverification/recipe.js | 15 ++- lib/build/recipe/emailverification/types.d.ts | 23 +++-- lib/build/recipe/thirdparty/types.d.ts | 21 +++- .../recipe/thirdpartyemailpassword/types.d.ts | 21 +++- lib/ts/override.ts | 6 +- lib/ts/recipe/emailpassword/recipe.ts | 4 +- lib/ts/recipe/emailpassword/types.ts | 41 +++++--- lib/ts/recipe/emailverification/recipe.ts | 14 ++- lib/ts/recipe/emailverification/types.ts | 23 +++-- lib/ts/recipe/thirdparty/types.ts | 21 +++- .../recipe/thirdpartyemailpassword/types.ts | 21 +++- test/recipeModuleManager.test.js | 99 ------------------- 16 files changed, 178 insertions(+), 184 deletions(-) diff --git a/lib/build/override.d.ts b/lib/build/override.d.ts index dae8c2fd2..db5c5d4cb 100644 --- a/lib/build/override.d.ts +++ b/lib/build/override.d.ts @@ -4,10 +4,6 @@ export default class OverrideableBuilder T) - | ((originalImplementation: T, builder: OverrideableBuilder) => T) - ): OverrideableBuilder; + override(overrideFunc: (originalImplementation: T, builder?: OverrideableBuilder) => T): OverrideableBuilder; build(): T; } diff --git a/lib/build/override.js b/lib/build/override.js index dd333855c..b8a0221e4 100644 --- a/lib/build/override.js +++ b/lib/build/override.js @@ -21,7 +21,7 @@ class OverrideableBuilder { this.layers = [originalImplementation]; this.proxies = []; } - addLayer(overrideFunc) { + override(overrideFunc) { const proxy = getProxyObject(this.layers[0]); const layer = overrideFunc(proxy, this); for (const key of Object.keys(this.layers[0])) { diff --git a/lib/build/recipe/emailpassword/recipe.js b/lib/build/recipe/emailpassword/recipe.js index 59f6df265..ea4b1ba4d 100644 --- a/lib/build/recipe/emailpassword/recipe.js +++ b/lib/build/recipe/emailpassword/recipe.js @@ -175,11 +175,11 @@ class Recipe extends recipeModule_1.default { let builder = new override_1.default( recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) ); - this.recipeInterfaceImpl = builder.addLayer(this.config.override.functions).build(); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { let builder = new override_1.default(implementation_1.default()); - this.apiImpl = builder.addLayer(this.config.override.apis).build(); + this.apiImpl = builder.override(this.config.override.apis).build(); } } static getInstanceOrThrowError() { diff --git a/lib/build/recipe/emailpassword/types.d.ts b/lib/build/recipe/emailpassword/types.d.ts index 19be07c3f..9df51a2e3 100644 --- a/lib/build/recipe/emailpassword/types.d.ts +++ b/lib/build/recipe/emailpassword/types.d.ts @@ -12,18 +12,20 @@ export declare type TypeNormalisedInput = { resetPasswordUsingTokenFeature: TypeNormalisedInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: - | ((originalImplementation: RecipeInterface) => RecipeInterface) - | (( - originalImplementation: RecipeInterface, - builder: OverrideableBuilder - ) => RecipeInterface); - apis: - | ((originalImplementation: APIInterface) => APIInterface) - | ((originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface); + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -86,11 +88,20 @@ export declare type TypeInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/lib/build/recipe/emailverification/recipe.js b/lib/build/recipe/emailverification/recipe.js index 5d1b2351a..44571be68 100644 --- a/lib/build/recipe/emailverification/recipe.js +++ b/lib/build/recipe/emailverification/recipe.js @@ -55,6 +55,7 @@ const emailVerify_1 = require("./api/emailVerify"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); +const override_1 = require("../../override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { super(recipeId, appInfo); @@ -111,10 +112,16 @@ class Recipe extends recipeModule_1.default { }; this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static getInstanceOrThrowError() { if (Recipe.instance !== undefined) { diff --git a/lib/build/recipe/emailverification/types.d.ts b/lib/build/recipe/emailverification/types.d.ts index 41c9ef603..9950730be 100644 --- a/lib/build/recipe/emailverification/types.d.ts +++ b/lib/build/recipe/emailverification/types.d.ts @@ -1,12 +1,16 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export declare type TypeInput = { getEmailForUserId: (userId: string) => Promise; getEmailVerificationURL?: (user: User) => Promise; createAndSendCustomEmail?: (user: User, emailVerificationURLWithToken: string) => Promise; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export declare type TypeNormalisedInput = { @@ -14,15 +18,18 @@ export declare type TypeNormalisedInput = { getEmailVerificationURL: (user: User) => Promise; createAndSendCustomEmail: (user: User, emailVerificationURLWithToken: string) => Promise; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export declare type User = { id: string; email: string; }; -export interface RecipeInterface { +export declare type RecipeInterface = { createEmailVerificationToken(input: { userId: string; email: string; @@ -59,7 +66,7 @@ export interface RecipeInterface { }): Promise<{ status: "OK"; }>; -} +}; export declare type APIOptions = { recipeImplementation: RecipeInterface; config: TypeNormalisedInput; @@ -68,7 +75,7 @@ export declare type APIOptions = { req: BaseRequest; res: BaseResponse; }; -export interface APIInterface { +export declare type APIInterface = { verifyEmailPOST: | undefined | ((input: { @@ -98,4 +105,4 @@ export interface APIInterface { }) => Promise<{ status: "EMAIL_ALREADY_VERIFIED_ERROR" | "OK"; }>); -} +}; diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index ba1249bb0..828f72364 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -5,6 +5,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export declare type UserInfo = { id: string; email?: { @@ -58,8 +59,14 @@ export declare type TypeInput = { functions?: (originalImplementation: RecipeInterface) => RecipeInterface; apis?: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -102,8 +109,14 @@ export declare type TypeNormalisedInput = { functions: (originalImplementation: RecipeInterface) => RecipeInterface; apis: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/lib/build/recipe/thirdpartyemailpassword/types.d.ts b/lib/build/recipe/thirdpartyemailpassword/types.d.ts index 2a204f7d7..996c29e4d 100644 --- a/lib/build/recipe/thirdpartyemailpassword/types.d.ts +++ b/lib/build/recipe/thirdpartyemailpassword/types.d.ts @@ -12,6 +12,7 @@ import { TypeInputResetPasswordUsingTokenFeature, APIOptions as EmailPasswordAPIOptionsOriginal, } from "../emailpassword/types"; +import OverrideableBuilder from "../../override"; export declare type User = { id: string; timeJoined: number; @@ -51,8 +52,14 @@ export declare type TypeInput = { functions?: (originalImplementation: RecipeInterface) => RecipeInterface; apis?: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -122,8 +129,14 @@ export declare type TypeNormalisedInput = { functions: (originalImplementation: RecipeInterface) => RecipeInterface; apis: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/lib/ts/override.ts b/lib/ts/override.ts index b8ff3d276..b318bc6ea 100644 --- a/lib/ts/override.ts +++ b/lib/ts/override.ts @@ -32,11 +32,7 @@ export default class OverrideableBuilder T) - | ((originalImplementation: T, builder: OverrideableBuilder) => T) - ): OverrideableBuilder { + override(overrideFunc: (originalImplementation: T, builder?: OverrideableBuilder) => T): OverrideableBuilder { const proxy = getProxyObject(this.layers[0]) as T; const layer = overrideFunc(proxy, this); for (const key of Object.keys(this.layers[0]) as (keyof T)[]) { diff --git a/lib/ts/recipe/emailpassword/recipe.ts b/lib/ts/recipe/emailpassword/recipe.ts index 1504692e8..a6514f6d8 100644 --- a/lib/ts/recipe/emailpassword/recipe.ts +++ b/lib/ts/recipe/emailpassword/recipe.ts @@ -73,11 +73,11 @@ export default class Recipe extends RecipeModule { }); { let builder = new OverrideableBuilder(RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId))); - this.recipeInterfaceImpl = builder.addLayer(this.config.override.functions).build(); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { let builder = new OverrideableBuilder(APIImplementation()); - this.apiImpl = builder.addLayer(this.config.override.apis).build(); + this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/ts/recipe/emailpassword/types.ts b/lib/ts/recipe/emailpassword/types.ts index 6ffc8225a..f65a62af1 100644 --- a/lib/ts/recipe/emailpassword/types.ts +++ b/lib/ts/recipe/emailpassword/types.ts @@ -39,18 +39,20 @@ export type TypeNormalisedInput = { resetPasswordUsingTokenFeature: TypeNormalisedInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: - | ((originalImplementation: RecipeInterface) => RecipeInterface) - | (( - originalImplementation: RecipeInterface, - builder: OverrideableBuilder - ) => RecipeInterface); - apis: - | ((originalImplementation: APIInterface) => APIInterface) - | ((originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface); + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -147,11 +149,20 @@ export type TypeInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/lib/ts/recipe/emailverification/recipe.ts b/lib/ts/recipe/emailverification/recipe.ts index a1249bb75..a19deefbd 100644 --- a/lib/ts/recipe/emailverification/recipe.ts +++ b/lib/ts/recipe/emailverification/recipe.ts @@ -26,6 +26,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; @@ -43,10 +44,15 @@ export default class Recipe extends RecipeModule { super(recipeId, appInfo); this.config = validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(APIImplementation()); + + { + let builder = new OverrideableBuilder(RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId))); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static getInstanceOrThrowError(): Recipe { diff --git a/lib/ts/recipe/emailverification/types.ts b/lib/ts/recipe/emailverification/types.ts index 28c4e9880..54b6863e5 100644 --- a/lib/ts/recipe/emailverification/types.ts +++ b/lib/ts/recipe/emailverification/types.ts @@ -14,14 +14,18 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export type TypeInput = { getEmailForUserId: (userId: string) => Promise; getEmailVerificationURL?: (user: User) => Promise; createAndSendCustomEmail?: (user: User, emailVerificationURLWithToken: string) => Promise; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; @@ -30,8 +34,11 @@ export type TypeNormalisedInput = { getEmailVerificationURL: (user: User) => Promise; createAndSendCustomEmail: (user: User, emailVerificationURLWithToken: string) => Promise; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; @@ -40,7 +47,7 @@ export type User = { email: string; }; -export interface RecipeInterface { +export type RecipeInterface = { createEmailVerificationToken(input: { userId: string; email: string; @@ -61,7 +68,7 @@ export interface RecipeInterface { revokeEmailVerificationTokens(input: { userId: string; email: string }): Promise<{ status: "OK" }>; unverifyEmail(input: { userId: string; email: string }): Promise<{ status: "OK" }>; -} +}; export type APIOptions = { recipeImplementation: RecipeInterface; @@ -72,7 +79,7 @@ export type APIOptions = { res: BaseResponse; }; -export interface APIInterface { +export type APIInterface = { verifyEmailPOST: | undefined | ((input: { @@ -92,4 +99,4 @@ export interface APIInterface { generateEmailVerifyTokenPOST: | undefined | ((input: { options: APIOptions }) => Promise<{ status: "EMAIL_ALREADY_VERIFIED_ERROR" | "OK" }>); -} +}; diff --git a/lib/ts/recipe/thirdparty/types.ts b/lib/ts/recipe/thirdparty/types.ts index ef7e6960b..29dd7240e 100644 --- a/lib/ts/recipe/thirdparty/types.ts +++ b/lib/ts/recipe/thirdparty/types.ts @@ -19,6 +19,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; const TypeAny = { type: "any", @@ -95,8 +96,14 @@ export type TypeInput = { functions?: (originalImplementation: RecipeInterface) => RecipeInterface; apis?: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -119,8 +126,14 @@ export type TypeNormalisedInput = { functions: (originalImplementation: RecipeInterface) => RecipeInterface; apis: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/lib/ts/recipe/thirdpartyemailpassword/types.ts b/lib/ts/recipe/thirdpartyemailpassword/types.ts index 1ee3f2678..d4a21cfa7 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/types.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/types.ts @@ -26,6 +26,7 @@ import { InputResetPasswordUsingTokenFeatureSchema, APIOptions as EmailPasswordAPIOptionsOriginal, } from "../emailpassword/types"; +import OverrideableBuilder from "../../override"; const TypeString = { type: "string", @@ -114,8 +115,14 @@ export type TypeInput = { functions?: (originalImplementation: RecipeInterface) => RecipeInterface; apis?: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; @@ -141,8 +148,14 @@ export type TypeNormalisedInput = { functions: (originalImplementation: RecipeInterface) => RecipeInterface; apis: (originalImplementation: APIInterface) => APIInterface; emailVerificationFeature?: { - functions?: (originalImplementation: EmailVerificationRecipeInterface) => EmailVerificationRecipeInterface; - apis?: (originalImplementation: EmailVerificationAPIInterface) => EmailVerificationAPIInterface; + functions?: ( + originalImplementation: EmailVerificationRecipeInterface, + builder?: OverrideableBuilder + ) => EmailVerificationRecipeInterface; + apis?: ( + originalImplementation: EmailVerificationAPIInterface, + builder?: OverrideableBuilder + ) => EmailVerificationAPIInterface; }; }; }; diff --git a/test/recipeModuleManager.test.js b/test/recipeModuleManager.test.js index d746059bc..775c672b3 100644 --- a/test/recipeModuleManager.test.js +++ b/test/recipeModuleManager.test.js @@ -625,105 +625,6 @@ describe(`recipeModuleManagerTest: ${printPath("[test/recipeModuleManager.test.j headers.includes("test-recipe-1") && headers.includes("test-recipe-2") && headers.includes("test-recipe-3") ); }); - - it("override bind tests", async function () { - // see https://github.com/supertokens/supertokens-node/issues/199 - m = 0; - let oI = { - someFunc: function () { - this.someOtherFunc(); - }, - someOtherFunc: function () { - m = 1; - }, - }; - let a = { - ...oI, - someFunc: function () { - oI.someFunc.bind(this)(); - }, - someOtherFunc: function () { - m = 2; - }, - }; - - let b = { - ...a, - someFunc: function () { - a.someFunc.bind(this)(); - }, - someOtherFunc: function () { - m = 4; - }, - }; - - b.someFunc(); - - assert(m === 4); - }); - - it("override 2 for super recipe bind tests", async function () { - // see https://github.com/supertokens/supertokens-node/issues/199 (issue 2 tests) - let m = 0; - let ep = { - signIn: function () { - this.getUserByEmail(); - }, - getUserByEmail: function () { - m = 1; - }, - }; - - let tpep = { - signIn: function () { - ep.signIn.bind(derivedEp(this))(); - }, - getUsersByEmail: function () { - ep.getUserByEmail.bind(derivedEp(this))(); - }, - }; - - let derivedEp = (tpep) => { - // cannot be overrided, but can be called on it's own - return { - signIn: function () { - tpep.signIn(); - }, - getUserByEmail: function () { - tpep.getUsersByEmail(); - }, - }; - }; - - { - // user override - let override = { - ...tpep, - signIn: function () { - tpep.signIn.bind(this)(); - }, - getUsersByEmail: function () { - m = 5; - tpep.getUsersByEmail.bind(this)(); - if (m === 1) { - m = 2; - } - }, - }; - - override.signIn(); - - assert(m === 2); - - m = 1; - - let derivedEpInstance = derivedEp(override); // created after user has created their override - - derivedEpInstance.getUserByEmail(); - - assert(m === 2); - } - }); }); class TestRecipe extends RecipeModule { From ca167787d2feff1d970ab8cc9f00eb3b45efb932 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 3 Nov 2021 10:38:12 +0530 Subject: [PATCH 4/7] adds new override builder to more recipes --- lib/build/recipe/jwt/recipe.js | 19 +++++++++++++++---- lib/build/recipe/jwt/types.d.ts | 23 +++++++++++++++-------- lib/build/recipe/session/recipe.js | 15 +++++++++++---- lib/build/recipe/session/types.d.ts | 23 +++++++++++++++-------- lib/ts/recipe/jwt/recipe.ts | 16 ++++++++++++---- lib/ts/recipe/jwt/types.ts | 23 +++++++++++++++-------- lib/ts/recipe/session/recipe.ts | 16 ++++++++++++---- lib/ts/recipe/session/types.ts | 23 +++++++++++++++-------- test/faunadb.test.js | 18 +++++++++++------- 9 files changed, 121 insertions(+), 55 deletions(-) diff --git a/lib/build/recipe/jwt/recipe.js b/lib/build/recipe/jwt/recipe.js index 1799335f7..7fbbf7867 100644 --- a/lib/build/recipe/jwt/recipe.js +++ b/lib/build/recipe/jwt/recipe.js @@ -54,6 +54,7 @@ const implementation_1 = require("./api/implementation"); const constants_1 = require("./constants"); const recipeImplementation_1 = require("./recipeImplementation"); const utils_1 = require("./utils"); +const override_1 = require("../../override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { super(recipeId, appInfo); @@ -71,10 +72,20 @@ class Recipe extends recipeModule_1.default { }); this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId), this.config, appInfo) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default( + querier_1.Querier.getNewInstanceOrThrowError(recipeId), + this.config, + appInfo + ) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } /* Init functions */ static getInstanceOrThrowError() { diff --git a/lib/build/recipe/jwt/types.d.ts b/lib/build/recipe/jwt/types.d.ts index 007fbe0e6..daabc1c3b 100644 --- a/lib/build/recipe/jwt/types.d.ts +++ b/lib/build/recipe/jwt/types.d.ts @@ -1,5 +1,6 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export declare type JsonWebKey = { kty: string; kid: string; @@ -11,15 +12,21 @@ export declare type JsonWebKey = { export declare type TypeInput = { jwtValiditySeconds?: number; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export declare type TypeNormalisedInput = { jwtValiditySeconds: number; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export declare type APIOptions = { @@ -30,7 +37,7 @@ export declare type APIOptions = { req: BaseRequest; res: BaseResponse; }; -export interface RecipeInterface { +export declare type RecipeInterface = { createJWT(input: { payload?: any; validitySeconds?: number; @@ -47,8 +54,8 @@ export interface RecipeInterface { status: "OK"; keys: JsonWebKey[]; }>; -} -export interface APIInterface { +}; +export declare type APIInterface = { getJWKSGET: | undefined | ((input: { @@ -57,4 +64,4 @@ export interface APIInterface { status: "OK"; keys: JsonWebKey[]; }>); -} +}; diff --git a/lib/build/recipe/session/recipe.js b/lib/build/recipe/session/recipe.js index f66e4478e..f53ffb33b 100644 --- a/lib/build/recipe/session/recipe.js +++ b/lib/build/recipe/session/recipe.js @@ -56,6 +56,7 @@ const cookieAndHeaders_1 = require("./cookieAndHeaders"); const recipeImplementation_1 = require("./recipeImplementation"); const querier_1 = require("../../querier"); const implementation_1 = require("./api/implementation"); +const override_1 = require("../../override"); // For Express class SessionRecipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { @@ -136,10 +137,16 @@ class SessionRecipe extends recipeModule_1.default { }); this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId), this.config) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId), this.config) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static getInstanceOrThrowError() { if (SessionRecipe.instance !== undefined) { diff --git a/lib/build/recipe/session/types.d.ts b/lib/build/recipe/session/types.d.ts index 66a4d7a8e..36c99a3f8 100644 --- a/lib/build/recipe/session/types.d.ts +++ b/lib/build/recipe/session/types.d.ts @@ -1,6 +1,7 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; import NormalisedURLPath from "../../normalisedURLPath"; +import OverrideableBuilder from "../../override"; export declare type KeyInfo = { publicKey: string; expiryTime: number; @@ -69,8 +70,11 @@ export declare type TypeInput = { errorHandlers?: ErrorHandlers; antiCsrf?: "VIA_TOKEN" | "VIA_CUSTOM_HEADER" | "NONE"; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export declare const InputSchema: { @@ -118,8 +122,11 @@ export declare type TypeNormalisedInput = { errorHandlers: NormalisedErrorHandlers; antiCsrf: "VIA_TOKEN" | "VIA_CUSTOM_HEADER" | "NONE"; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export interface SessionRequest extends BaseRequest { @@ -140,7 +147,7 @@ export interface VerifySessionOptions { antiCsrfCheck?: boolean; sessionRequired?: boolean; } -export interface RecipeInterface { +export declare type RecipeInterface = { createNewSession(input: { res: any; userId: string; @@ -167,7 +174,7 @@ export interface RecipeInterface { updateAccessTokenPayload(input: { sessionHandle: string; newAccessTokenPayload: any }): Promise; getAccessTokenLifeTimeMS(): Promise; getRefreshTokenLifeTimeMS(): Promise; -} +}; export interface SessionContainerInterface { revokeSession(): Promise; getSessionData(): Promise; @@ -188,7 +195,7 @@ export declare type APIOptions = { req: BaseRequest; res: BaseResponse; }; -export interface APIInterface { +export declare type APIInterface = { refreshPOST: undefined | ((input: { options: APIOptions }) => Promise); signOutPOST: | undefined @@ -201,7 +208,7 @@ export interface APIInterface { verifySessionOptions: VerifySessionOptions | undefined; options: APIOptions; }): Promise; -} +}; export declare type SessionInformation = { sessionHandle: string; userId: string; diff --git a/lib/ts/recipe/jwt/recipe.ts b/lib/ts/recipe/jwt/recipe.ts index cbbe5e430..f974d41ec 100644 --- a/lib/ts/recipe/jwt/recipe.ts +++ b/lib/ts/recipe/jwt/recipe.ts @@ -27,6 +27,7 @@ import { GET_JWKS_API } from "./constants"; import RecipeImplementation from "./recipeImplementation"; import { APIInterface, RecipeInterface, TypeInput, TypeNormalisedInput } from "./types"; import { validateAndNormaliseUserInput } from "./utils"; +import OverrideableBuilder from "../../override"; export default class Recipe extends RecipeModule { static RECIPE_ID = "jwt"; @@ -41,10 +42,17 @@ export default class Recipe extends RecipeModule { super(recipeId, appInfo); this.config = validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId), this.config, appInfo) - ); - this.apiImpl = this.config.override.apis(APIImplementation()); + + { + let builder = new OverrideableBuilder( + RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId), this.config, appInfo) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } /* Init functions */ diff --git a/lib/ts/recipe/jwt/types.ts b/lib/ts/recipe/jwt/types.ts index c4edb121f..688defb6d 100644 --- a/lib/ts/recipe/jwt/types.ts +++ b/lib/ts/recipe/jwt/types.ts @@ -14,6 +14,7 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export type JsonWebKey = { kty: string; @@ -27,16 +28,22 @@ export type JsonWebKey = { export type TypeInput = { jwtValiditySeconds?: number; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; export type TypeNormalisedInput = { jwtValiditySeconds: number; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; @@ -49,7 +56,7 @@ export type APIOptions = { res: BaseResponse; }; -export interface RecipeInterface { +export type RecipeInterface = { createJWT(input: { payload?: any; validitySeconds?: number; @@ -67,8 +74,8 @@ export interface RecipeInterface { status: "OK"; keys: JsonWebKey[]; }>; -} +}; -export interface APIInterface { +export type APIInterface = { getJWKSGET: undefined | ((input: { options: APIOptions }) => Promise<{ status: "OK"; keys: JsonWebKey[] }>); -} +}; diff --git a/lib/ts/recipe/session/recipe.ts b/lib/ts/recipe/session/recipe.ts index d1ffa28a4..5e2bba495 100644 --- a/lib/ts/recipe/session/recipe.ts +++ b/lib/ts/recipe/session/recipe.ts @@ -27,6 +27,7 @@ import RecipeImplementation from "./recipeImplementation"; import { Querier } from "../../querier"; import APIImplementation from "./api/implementation"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; // For Express export default class SessionRecipe extends RecipeModule { @@ -45,10 +46,17 @@ export default class SessionRecipe extends RecipeModule { super(recipeId, appInfo); this.config = validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId), this.config) - ); - this.apiImpl = this.config.override.apis(APIImplementation()); + + { + let builder = new OverrideableBuilder( + RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId), this.config) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static getInstanceOrThrowError(): SessionRecipe { diff --git a/lib/ts/recipe/session/types.ts b/lib/ts/recipe/session/types.ts index 061369030..a38c81870 100644 --- a/lib/ts/recipe/session/types.ts +++ b/lib/ts/recipe/session/types.ts @@ -14,6 +14,7 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; import NormalisedURLPath from "../../normalisedURLPath"; +import OverrideableBuilder from "../../override"; export type KeyInfo = { publicKey: string; @@ -102,8 +103,11 @@ export type TypeInput = { errorHandlers?: ErrorHandlers; antiCsrf?: "VIA_TOKEN" | "VIA_CUSTOM_HEADER" | "NONE"; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; @@ -130,8 +134,11 @@ export type TypeNormalisedInput = { errorHandlers: NormalisedErrorHandlers; antiCsrf: "VIA_TOKEN" | "VIA_CUSTOM_HEADER" | "NONE"; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; }; }; @@ -158,7 +165,7 @@ export interface VerifySessionOptions { sessionRequired?: boolean; } -export interface RecipeInterface { +export type RecipeInterface = { createNewSession(input: { res: any; userId: string; @@ -195,7 +202,7 @@ export interface RecipeInterface { getAccessTokenLifeTimeMS(): Promise; getRefreshTokenLifeTimeMS(): Promise; -} +}; export interface SessionContainerInterface { revokeSession(): Promise; @@ -228,7 +235,7 @@ export type APIOptions = { res: BaseResponse; }; -export interface APIInterface { +export type APIInterface = { refreshPOST: undefined | ((input: { options: APIOptions }) => Promise); signOutPOST: @@ -243,7 +250,7 @@ export interface APIInterface { verifySessionOptions: VerifySessionOptions | undefined; options: APIOptions; }): Promise; -} +}; export type SessionInformation = { sessionHandle: string; diff --git a/test/faunadb.test.js b/test/faunadb.test.js index 541426c82..4f06f11af 100644 --- a/test/faunadb.test.js +++ b/test/faunadb.test.js @@ -192,14 +192,18 @@ describe(`faunaDB: ${printPath("[test/faunadb.test.js]")}`, function () { Session.init({ antiCsrf: "VIA_TOKEN", override: { - functions: (oI) => { - return new RecipeImplementation(oI, { - userCollectionName: "users", - accessFaunadbTokenFromFrontend: true, - faunaDBClient: new faunadb.Client({ - secret: "fnAD2HH-Q6ACBSJxMjwU5YT7hvkaVo6Te8PJWqsT", - }), + functions: (originalImpl, builder) => { + builder.override((oI) => { + return new RecipeImplementation(oI, { + userCollectionName: "users", + accessFaunadbTokenFromFrontend: true, + faunaDBClient: new faunadb.Client({ + secret: "fnAD2HH-Q6ACBSJxMjwU5YT7hvkaVo6Te8PJWqsT", + }), + }); }); + + return originalImpl; }, }, }), From 6e99820bab453a3e61901444cf4d4d6058f251a1 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 3 Nov 2021 10:46:08 +0530 Subject: [PATCH 5/7] adds override builder to all recipes --- lib/build/recipe/thirdparty/recipe.js | 15 +++++++++---- lib/build/recipe/thirdparty/types.d.ts | 22 ++++++++++++------- .../recipe/thirdpartyemailpassword/recipe.js | 21 ++++++++++++------ .../recipe/thirdpartyemailpassword/types.d.ts | 22 ++++++++++++------- lib/ts/recipe/thirdparty/recipe.ts | 14 ++++++++---- lib/ts/recipe/thirdparty/types.ts | 22 ++++++++++++------- .../recipe/thirdpartyemailpassword/recipe.ts | 22 ++++++++++++------- .../recipe/thirdpartyemailpassword/types.ts | 22 ++++++++++++------- 8 files changed, 105 insertions(+), 55 deletions(-) diff --git a/lib/build/recipe/thirdparty/recipe.js b/lib/build/recipe/thirdparty/recipe.js index b12cb3e9f..70003256b 100644 --- a/lib/build/recipe/thirdparty/recipe.js +++ b/lib/build/recipe/thirdparty/recipe.js @@ -56,6 +56,7 @@ const authorisationUrl_1 = require("./api/authorisationUrl"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); +const override_1 = require("../../override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -134,10 +135,16 @@ class Recipe extends recipeModule_1.default { Object.assign({}, this.config.emailVerificationFeature) ); this.providers = this.config.signInAndUpFeature.providers; - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static init(config) { return (appInfo, isInServerlessEnv) => { diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index 828f72364..7dbb18180 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -56,8 +56,11 @@ export declare type TypeInput = { signInAndUpFeature: TypeInputSignInAndUp; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -106,8 +109,11 @@ export declare type TypeNormalisedInput = { signInAndUpFeature: TypeNormalisedInputSignInAndUp; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -120,7 +126,7 @@ export declare type TypeNormalisedInput = { }; }; }; -export interface RecipeInterface { +export declare type RecipeInterface = { getUserById(input: { userId: string }): Promise; getUsersByEmail(input: { email: string }): Promise; getUserByThirdPartyInfo(input: { thirdPartyId: string; thirdPartyUserId: string }): Promise; @@ -142,7 +148,7 @@ export interface RecipeInterface { error: string; } >; -} +}; export declare type APIOptions = { recipeImplementation: RecipeInterface; emailVerificationRecipeImplementation: EmailVerificationRecipeInterface; @@ -153,7 +159,7 @@ export declare type APIOptions = { req: BaseRequest; res: BaseResponse; }; -export interface APIInterface { +export declare type APIInterface = { authorisationUrlGET: | undefined | ((input: { @@ -186,4 +192,4 @@ export interface APIInterface { error: string; } >); -} +}; diff --git a/lib/build/recipe/thirdpartyemailpassword/recipe.js b/lib/build/recipe/thirdpartyemailpassword/recipe.js index 925ed5229..5f1d14ab6 100644 --- a/lib/build/recipe/thirdpartyemailpassword/recipe.js +++ b/lib/build/recipe/thirdpartyemailpassword/recipe.js @@ -58,6 +58,7 @@ const thirdPartyAPIImplementation_1 = require("./api/thirdPartyAPIImplementation const emailPasswordAPIImplementation_1 = require("./api/emailPasswordAPIImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); +const override_1 = require("../../override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -129,13 +130,19 @@ class Recipe extends recipeModule_1.default { return userInfo.email; }); this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); - this.recipeInterfaceImpl = this.config.override.functions( - recipeImplementation_1.default( - querier_1.Querier.getNewInstanceOrThrowError(recipe_2.default.RECIPE_ID), - querier_1.Querier.getNewInstanceOrThrowError(recipe_3.default.RECIPE_ID) - ) - ); - this.apiImpl = this.config.override.apis(implementation_1.default()); + { + let builder = new override_1.default( + recipeImplementation_1.default( + querier_1.Querier.getNewInstanceOrThrowError(recipe_2.default.RECIPE_ID), + querier_1.Querier.getNewInstanceOrThrowError(recipe_3.default.RECIPE_ID) + ) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new override_1.default(implementation_1.default()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } this.emailVerificationRecipe = recipes.emailVerificationInstance !== undefined ? recipes.emailVerificationInstance diff --git a/lib/build/recipe/thirdpartyemailpassword/types.d.ts b/lib/build/recipe/thirdpartyemailpassword/types.d.ts index 996c29e4d..86e4d6e82 100644 --- a/lib/build/recipe/thirdpartyemailpassword/types.d.ts +++ b/lib/build/recipe/thirdpartyemailpassword/types.d.ts @@ -49,8 +49,11 @@ export declare type TypeInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -126,8 +129,11 @@ export declare type TypeNormalisedInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -140,7 +146,7 @@ export declare type TypeNormalisedInput = { }; }; }; -export interface RecipeInterface { +export declare type RecipeInterface = { getUserById(input: { userId: string }): Promise; getUsersByEmail(input: { email: string }): Promise; getUserByThirdPartyInfo(input: { thirdPartyId: string; thirdPartyUserId: string }): Promise; @@ -210,10 +216,10 @@ export interface RecipeInterface { }): Promise<{ status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; }>; -} +}; export declare type EmailPasswordAPIOptions = EmailPasswordAPIOptionsOriginal; export declare type ThirdPartyAPIOptions = ThirdPartyAPIOptionsOriginal; -export interface APIInterface { +export declare type APIInterface = { authorisationUrlGET: | undefined | ((input: { @@ -312,4 +318,4 @@ export interface APIInterface { status: "EMAIL_ALREADY_EXISTS_ERROR"; } >); -} +}; diff --git a/lib/ts/recipe/thirdparty/recipe.ts b/lib/ts/recipe/thirdparty/recipe.ts index cf87450c8..b4ef2d5a3 100644 --- a/lib/ts/recipe/thirdparty/recipe.ts +++ b/lib/ts/recipe/thirdparty/recipe.ts @@ -28,6 +28,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; +import OverrideableBuilder from "../../override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; @@ -65,10 +66,15 @@ export default class Recipe extends RecipeModule { }); this.providers = this.config.signInAndUpFeature.providers; - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId)) - ); - this.apiImpl = this.config.override.apis(APIImplementation()); + + { + let builder = new OverrideableBuilder(RecipeImplementation(Querier.getNewInstanceOrThrowError(recipeId))); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } } static init(config: TypeInput): RecipeListFunction { diff --git a/lib/ts/recipe/thirdparty/types.ts b/lib/ts/recipe/thirdparty/types.ts index 29dd7240e..070086cab 100644 --- a/lib/ts/recipe/thirdparty/types.ts +++ b/lib/ts/recipe/thirdparty/types.ts @@ -93,8 +93,11 @@ export type TypeInput = { signInAndUpFeature: TypeInputSignInAndUp; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -123,8 +126,11 @@ export type TypeNormalisedInput = { signInAndUpFeature: TypeNormalisedInputSignInAndUp; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -138,7 +144,7 @@ export type TypeNormalisedInput = { }; }; -export interface RecipeInterface { +export type RecipeInterface = { getUserById(input: { userId: string }): Promise; getUsersByEmail(input: { email: string }): Promise; @@ -159,7 +165,7 @@ export interface RecipeInterface { error: string; } >; -} +}; export type APIOptions = { recipeImplementation: RecipeInterface; @@ -172,7 +178,7 @@ export type APIOptions = { res: BaseResponse; }; -export interface APIInterface { +export type APIInterface = { authorisationUrlGET: | undefined | ((input: { @@ -204,4 +210,4 @@ export interface APIInterface { error: string; } >); -} +}; diff --git a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts index 8380ba0a0..a5e373c2f 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts @@ -31,6 +31,7 @@ import getThirdPartyIterfaceImpl from "./api/thirdPartyAPIImplementation"; import getEmailPasswordIterfaceImpl from "./api/emailPasswordAPIImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; +import OverrideableBuilder from "../../override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; @@ -62,14 +63,19 @@ export default class Recipe extends RecipeModule { super(recipeId, appInfo); this.config = validateAndNormaliseUserInput(this, appInfo, config); - this.recipeInterfaceImpl = this.config.override.functions( - RecipeImplementation( - Querier.getNewInstanceOrThrowError(EmailPasswordRecipe.RECIPE_ID), - Querier.getNewInstanceOrThrowError(ThirdPartyRecipe.RECIPE_ID) - ) - ); - - this.apiImpl = this.config.override.apis(APIImplementation()); + { + let builder = new OverrideableBuilder( + RecipeImplementation( + Querier.getNewInstanceOrThrowError(EmailPasswordRecipe.RECIPE_ID), + Querier.getNewInstanceOrThrowError(ThirdPartyRecipe.RECIPE_ID) + ) + ); + this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); + } + { + let builder = new OverrideableBuilder(APIImplementation()); + this.apiImpl = builder.override(this.config.override.apis).build(); + } this.emailVerificationRecipe = recipes.emailVerificationInstance !== undefined diff --git a/lib/ts/recipe/thirdpartyemailpassword/types.ts b/lib/ts/recipe/thirdpartyemailpassword/types.ts index d4a21cfa7..5245a96d7 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/types.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/types.ts @@ -112,8 +112,11 @@ export type TypeInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature?: TypeInputEmailVerificationFeature; override?: { - functions?: (originalImplementation: RecipeInterface) => RecipeInterface; - apis?: (originalImplementation: APIInterface) => APIInterface; + functions?: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis?: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -145,8 +148,11 @@ export type TypeNormalisedInput = { resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; emailVerificationFeature: TypeInputEmailVerification; override: { - functions: (originalImplementation: RecipeInterface) => RecipeInterface; - apis: (originalImplementation: APIInterface) => APIInterface; + functions: ( + originalImplementation: RecipeInterface, + builder?: OverrideableBuilder + ) => RecipeInterface; + apis: (originalImplementation: APIInterface, builder?: OverrideableBuilder) => APIInterface; emailVerificationFeature?: { functions?: ( originalImplementation: EmailVerificationRecipeInterface, @@ -160,7 +166,7 @@ export type TypeNormalisedInput = { }; }; -export interface RecipeInterface { +export type RecipeInterface = { getUserById(input: { userId: string }): Promise; getUsersByEmail(input: { email: string }): Promise; @@ -206,12 +212,12 @@ export interface RecipeInterface { email?: string; password?: string; }): Promise<{ status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR" }>; -} +}; export type EmailPasswordAPIOptions = EmailPasswordAPIOptionsOriginal; export type ThirdPartyAPIOptions = ThirdPartyAPIOptionsOriginal; -export interface APIInterface { +export type APIInterface = { authorisationUrlGET: | undefined | ((input: { @@ -316,4 +322,4 @@ export interface APIInterface { status: "EMAIL_ALREADY_EXISTS_ERROR"; } >); -} +}; From 72e4def2eed85090f31fa868ed8fe33c84e4d7d7 Mon Sep 17 00:00:00 2001 From: Mihaly Lengyel Date: Wed, 3 Nov 2021 11:51:05 +0100 Subject: [PATCH 6/7] Fixing tests by removing binds from faunadb overrides and copying non-functions --- lib/build/override.js | 4 ++- .../session/faunadb/recipeImplementation.js | 26 +++++++++---------- lib/ts/override.ts | 4 ++- .../session/faunadb/recipeImplementation.ts | 26 +++++++++---------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lib/build/override.js b/lib/build/override.js index b8a0221e4..89340ac1b 100644 --- a/lib/build/override.js +++ b/lib/build/override.js @@ -46,8 +46,10 @@ class OverrideableBuilder { if (func !== undefined) { if (func === null) { this.result[key] = undefined; - } else { + } else if (typeof func === "function") { this.result[key] = func.bind(this.result); + } else { + this.result[key] = func; } } } diff --git a/lib/build/recipe/session/faunadb/recipeImplementation.js b/lib/build/recipe/session/faunadb/recipeImplementation.js index 614c952ec..df5f1d267 100644 --- a/lib/build/recipe/session/faunadb/recipeImplementation.js +++ b/lib/build/recipe/session/faunadb/recipeImplementation.js @@ -45,7 +45,7 @@ class RecipeImplementation { } return constants_1.FAUNADB_TOKEN_TIME_LAG_MILLI; } - let accessTokenLifetime = yield this.originalImplementation.getAccessTokenLifeTimeMS.bind(this)(); + let accessTokenLifetime = yield this.originalImplementation.getAccessTokenLifeTimeMS(); let faunaResponse = yield this.config.faunaDBClient.query( this.q.Create(this.q.Tokens(), { instance: this.q.Ref(this.q.Collection(this.config.userCollectionName), userId), @@ -69,7 +69,7 @@ class RecipeImplementation { sessionData[constants_1.FAUNADB_SESSION_KEY] = fdat; } return getModifiedSession( - yield this.originalImplementation.createNewSession.bind(this)({ + yield this.originalImplementation.createNewSession({ res, userId, accessTokenPayload, @@ -80,7 +80,7 @@ class RecipeImplementation { }; this.getSession = function ({ req, res, options }) { return __awaiter(this, void 0, void 0, function* () { - let originalSession = yield this.originalImplementation.getSession.bind(this)({ req, res, options }); + let originalSession = yield this.originalImplementation.getSession({ req, res, options }); if (originalSession === undefined) { return undefined; } @@ -88,11 +88,11 @@ class RecipeImplementation { }); }; this.getSessionInformation = function ({ sessionHandle }) { - return this.originalImplementation.getSessionInformation.bind(this)({ sessionHandle }); + return this.originalImplementation.getSessionInformation({ sessionHandle }); }; this.refreshSession = function ({ req, res }) { return __awaiter(this, void 0, void 0, function* () { - let originalSession = yield this.originalImplementation.refreshSession.bind(this)({ req, res }); + let originalSession = yield this.originalImplementation.refreshSession({ req, res }); let session = getModifiedSession(originalSession); let fdat = yield this.getFDAT(session.getUserId()); // we do not use the accessFaunaDBTokenFromFrontend boolean here so that @@ -110,31 +110,31 @@ class RecipeImplementation { }); }; this.revokeAllSessionsForUser = function ({ userId }) { - return this.originalImplementation.revokeAllSessionsForUser.bind(this)({ userId }); + return this.originalImplementation.revokeAllSessionsForUser({ userId }); }; this.getAllSessionHandlesForUser = function ({ userId }) { - return this.originalImplementation.getAllSessionHandlesForUser.bind(this)({ userId }); + return this.originalImplementation.getAllSessionHandlesForUser({ userId }); }; this.revokeSession = function ({ sessionHandle }) { - return this.originalImplementation.revokeSession.bind(this)({ sessionHandle }); + return this.originalImplementation.revokeSession({ sessionHandle }); }; this.revokeMultipleSessions = function ({ sessionHandles }) { - return this.originalImplementation.revokeMultipleSessions.bind(this)({ sessionHandles }); + return this.originalImplementation.revokeMultipleSessions({ sessionHandles }); }; this.updateSessionData = function ({ sessionHandle, newSessionData }) { - return this.originalImplementation.updateSessionData.bind(this)({ sessionHandle, newSessionData }); + return this.originalImplementation.updateSessionData({ sessionHandle, newSessionData }); }; this.updateAccessTokenPayload = function (input) { - return this.originalImplementation.updateAccessTokenPayload.bind(this)(input); + return this.originalImplementation.updateAccessTokenPayload(input); }; this.getAccessTokenLifeTimeMS = function () { return __awaiter(this, void 0, void 0, function* () { - return this.originalImplementation.getAccessTokenLifeTimeMS.bind(this)(); + return this.originalImplementation.getAccessTokenLifeTimeMS(); }); }; this.getRefreshTokenLifeTimeMS = function () { return __awaiter(this, void 0, void 0, function* () { - return this.originalImplementation.getRefreshTokenLifeTimeMS.bind(this)(); + return this.originalImplementation.getRefreshTokenLifeTimeMS(); }); }; this.originalImplementation = originalImplementation; diff --git a/lib/ts/override.ts b/lib/ts/override.ts index b318bc6ea..c4c267328 100644 --- a/lib/ts/override.ts +++ b/lib/ts/override.ts @@ -61,8 +61,10 @@ export default class OverrideableBuilder { - let originalSession = await this.originalImplementation.getSession.bind(this)({ req, res, options }); + let originalSession = await this.originalImplementation.getSession({ req, res, options }); if (originalSession === undefined) { return undefined; } @@ -113,7 +113,7 @@ export default class RecipeImplementation implements RecipeInterface { this: RecipeImplementation, { sessionHandle }: { sessionHandle: string } ): Promise { - return this.originalImplementation.getSessionInformation.bind(this)({ sessionHandle }); + return this.originalImplementation.getSessionInformation({ sessionHandle }); }; refreshSession = async function ( @@ -126,7 +126,7 @@ export default class RecipeImplementation implements RecipeInterface { res: BaseResponse; } ): Promise { - let originalSession = await this.originalImplementation.refreshSession.bind(this)({ req, res }); + let originalSession = await this.originalImplementation.refreshSession({ req, res }); let session = getModifiedSession(originalSession); let fdat = await this.getFDAT(session.getUserId()); @@ -150,47 +150,47 @@ export default class RecipeImplementation implements RecipeInterface { }; revokeAllSessionsForUser = function (this: RecipeImplementation, { userId }: { userId: string }) { - return this.originalImplementation.revokeAllSessionsForUser.bind(this)({ userId }); + return this.originalImplementation.revokeAllSessionsForUser({ userId }); }; getAllSessionHandlesForUser = function ( this: RecipeImplementation, { userId }: { userId: string } ): Promise { - return this.originalImplementation.getAllSessionHandlesForUser.bind(this)({ userId }); + return this.originalImplementation.getAllSessionHandlesForUser({ userId }); }; revokeSession = function ( this: RecipeImplementation, { sessionHandle }: { sessionHandle: string } ): Promise { - return this.originalImplementation.revokeSession.bind(this)({ sessionHandle }); + return this.originalImplementation.revokeSession({ sessionHandle }); }; revokeMultipleSessions = function (this: RecipeImplementation, { sessionHandles }: { sessionHandles: string[] }) { - return this.originalImplementation.revokeMultipleSessions.bind(this)({ sessionHandles }); + return this.originalImplementation.revokeMultipleSessions({ sessionHandles }); }; updateSessionData = function ( this: RecipeImplementation, { sessionHandle, newSessionData }: { sessionHandle: string; newSessionData: any } ) { - return this.originalImplementation.updateSessionData.bind(this)({ sessionHandle, newSessionData }); + return this.originalImplementation.updateSessionData({ sessionHandle, newSessionData }); }; updateAccessTokenPayload = function ( this: RecipeImplementation, input: { sessionHandle: string; newAccessTokenPayload: any } ) { - return this.originalImplementation.updateAccessTokenPayload.bind(this)(input); + return this.originalImplementation.updateAccessTokenPayload(input); }; getAccessTokenLifeTimeMS = async function (this: RecipeImplementation): Promise { - return this.originalImplementation.getAccessTokenLifeTimeMS.bind(this)(); + return this.originalImplementation.getAccessTokenLifeTimeMS(); }; getRefreshTokenLifeTimeMS = async function (this: RecipeImplementation): Promise { - return this.originalImplementation.getRefreshTokenLifeTimeMS.bind(this)(); + return this.originalImplementation.getRefreshTokenLifeTimeMS(); }; } From f97470d37539dc308c658636fe4ed08eddccb445 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 3 Nov 2021 22:42:05 +0530 Subject: [PATCH 7/7] uses lib for override --- lib/build/override.d.ts | 9 -- lib/build/override.js | 71 --------------- lib/build/recipe/emailpassword/recipe.js | 6 +- lib/build/recipe/emailpassword/types.d.ts | 2 +- lib/build/recipe/emailverification/recipe.js | 6 +- lib/build/recipe/emailverification/types.d.ts | 2 +- lib/build/recipe/jwt/recipe.js | 6 +- lib/build/recipe/jwt/types.d.ts | 2 +- lib/build/recipe/session/recipe.js | 6 +- lib/build/recipe/session/types.d.ts | 2 +- lib/build/recipe/thirdparty/recipe.js | 6 +- lib/build/recipe/thirdparty/types.d.ts | 2 +- .../recipe/thirdpartyemailpassword/recipe.js | 6 +- .../recipe/thirdpartyemailpassword/types.d.ts | 2 +- lib/ts/override.ts | 86 ------------------- lib/ts/recipe/emailpassword/recipe.ts | 2 +- lib/ts/recipe/emailpassword/types.ts | 2 +- lib/ts/recipe/emailverification/recipe.ts | 2 +- lib/ts/recipe/emailverification/types.ts | 2 +- lib/ts/recipe/jwt/recipe.ts | 2 +- lib/ts/recipe/jwt/types.ts | 2 +- lib/ts/recipe/session/recipe.ts | 2 +- lib/ts/recipe/session/types.ts | 2 +- lib/ts/recipe/thirdparty/recipe.ts | 2 +- lib/ts/recipe/thirdparty/types.ts | 2 +- .../recipe/thirdpartyemailpassword/recipe.ts | 2 +- .../recipe/thirdpartyemailpassword/types.ts | 2 +- package-lock.json | 4 + package.json | 3 +- 29 files changed, 42 insertions(+), 203 deletions(-) delete mode 100644 lib/build/override.d.ts delete mode 100644 lib/build/override.js delete mode 100644 lib/ts/override.ts diff --git a/lib/build/override.d.ts b/lib/build/override.d.ts deleted file mode 100644 index db5c5d4cb..000000000 --- a/lib/build/override.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-nocheck -export default class OverrideableBuilder any)>> { - private layers; - private proxies; - result?: T; - constructor(originalImplementation: T); - override(overrideFunc: (originalImplementation: T, builder?: OverrideableBuilder) => T): OverrideableBuilder; - build(): T; -} diff --git a/lib/build/override.js b/lib/build/override.js deleted file mode 100644 index 89340ac1b..000000000 --- a/lib/build/override.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function getProxyObject(orig) { - const ret = Object.assign(Object.assign({}, orig), { - _call: (_, __) => { - throw new Error("This function should only be called through the recipe object"); - }, - }); - const keys = Object.keys(ret); - for (const k of keys) { - if (k !== "_call") { - ret[k] = function (...args) { - return this._call(k, args); - }; - } - } - return ret; -} -class OverrideableBuilder { - constructor(originalImplementation) { - this.layers = [originalImplementation]; - this.proxies = []; - } - override(overrideFunc) { - const proxy = getProxyObject(this.layers[0]); - const layer = overrideFunc(proxy, this); - for (const key of Object.keys(this.layers[0])) { - if (layer[key] === proxy[key] || key === "_call") { - delete layer[key]; - } else if (layer[key] === undefined) { - layer[key] = null; - } - } - this.layers.push(layer); - this.proxies.push(proxy); - return this; - } - build() { - if (this.result) { - return this.result; - } - this.result = {}; - for (const layer of this.layers) { - for (const key of Object.keys(layer)) { - const func = layer[key]; - if (func !== undefined) { - if (func === null) { - this.result[key] = undefined; - } else if (typeof func === "function") { - this.result[key] = func.bind(this.result); - } else { - this.result[key] = func; - } - } - } - } - for (let proxyInd = 0; proxyInd < this.proxies.length; ++proxyInd) { - const proxy = this.proxies[proxyInd]; - proxy._call = (fname, args) => { - for (let i = proxyInd; i >= 0; --i) { - const func = this.layers[i][fname]; - if (func !== undefined) { - return func.bind(this.result)(...args); - } - } - }; - } - return this.result; - } -} -exports.default = OverrideableBuilder; diff --git a/lib/build/recipe/emailpassword/recipe.js b/lib/build/recipe/emailpassword/recipe.js index ea4b1ba4d..1d6ce544a 100644 --- a/lib/build/recipe/emailpassword/recipe.js +++ b/lib/build/recipe/emailpassword/recipe.js @@ -60,7 +60,7 @@ const recipe_1 = require("../emailverification/recipe"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -172,13 +172,13 @@ class Recipe extends recipeModule_1.default { Object.assign({}, this.config.emailVerificationFeature) ); { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) ); this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/build/recipe/emailpassword/types.d.ts b/lib/build/recipe/emailpassword/types.d.ts index 9df51a2e3..11728047b 100644 --- a/lib/build/recipe/emailpassword/types.d.ts +++ b/lib/build/recipe/emailpassword/types.d.ts @@ -5,7 +5,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type TypeNormalisedInput = { signUpFeature: TypeNormalisedInputSignUp; signInFeature: TypeNormalisedInputSignIn; diff --git a/lib/build/recipe/emailverification/recipe.js b/lib/build/recipe/emailverification/recipe.js index 44571be68..b51569ef0 100644 --- a/lib/build/recipe/emailverification/recipe.js +++ b/lib/build/recipe/emailverification/recipe.js @@ -55,7 +55,7 @@ const emailVerify_1 = require("./api/emailVerify"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { super(recipeId, appInfo); @@ -113,13 +113,13 @@ class Recipe extends recipeModule_1.default { this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) ); this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/build/recipe/emailverification/types.d.ts b/lib/build/recipe/emailverification/types.d.ts index 9950730be..f0fe2ce01 100644 --- a/lib/build/recipe/emailverification/types.d.ts +++ b/lib/build/recipe/emailverification/types.d.ts @@ -1,6 +1,6 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type TypeInput = { getEmailForUserId: (userId: string) => Promise; getEmailVerificationURL?: (user: User) => Promise; diff --git a/lib/build/recipe/jwt/recipe.js b/lib/build/recipe/jwt/recipe.js index 7fbbf7867..4e472d87b 100644 --- a/lib/build/recipe/jwt/recipe.js +++ b/lib/build/recipe/jwt/recipe.js @@ -54,7 +54,7 @@ const implementation_1 = require("./api/implementation"); const constants_1 = require("./constants"); const recipeImplementation_1 = require("./recipeImplementation"); const utils_1 = require("./utils"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { super(recipeId, appInfo); @@ -73,7 +73,7 @@ class Recipe extends recipeModule_1.default { this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default( querier_1.Querier.getNewInstanceOrThrowError(recipeId), this.config, @@ -83,7 +83,7 @@ class Recipe extends recipeModule_1.default { this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/build/recipe/jwt/types.d.ts b/lib/build/recipe/jwt/types.d.ts index daabc1c3b..ede9cc749 100644 --- a/lib/build/recipe/jwt/types.d.ts +++ b/lib/build/recipe/jwt/types.d.ts @@ -1,6 +1,6 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type JsonWebKey = { kty: string; kid: string; diff --git a/lib/build/recipe/session/recipe.js b/lib/build/recipe/session/recipe.js index f53ffb33b..95ead374b 100644 --- a/lib/build/recipe/session/recipe.js +++ b/lib/build/recipe/session/recipe.js @@ -56,7 +56,7 @@ const cookieAndHeaders_1 = require("./cookieAndHeaders"); const recipeImplementation_1 = require("./recipeImplementation"); const querier_1 = require("../../querier"); const implementation_1 = require("./api/implementation"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); // For Express class SessionRecipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config) { @@ -138,13 +138,13 @@ class SessionRecipe extends recipeModule_1.default { this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); this.isInServerlessEnv = isInServerlessEnv; { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId), this.config) ); this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/build/recipe/session/types.d.ts b/lib/build/recipe/session/types.d.ts index 36c99a3f8..b1f3e7074 100644 --- a/lib/build/recipe/session/types.d.ts +++ b/lib/build/recipe/session/types.d.ts @@ -1,7 +1,7 @@ // @ts-nocheck import { BaseRequest, BaseResponse } from "../../framework"; import NormalisedURLPath from "../../normalisedURLPath"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type KeyInfo = { publicKey: string; expiryTime: number; diff --git a/lib/build/recipe/thirdparty/recipe.js b/lib/build/recipe/thirdparty/recipe.js index 70003256b..e2ecc3367 100644 --- a/lib/build/recipe/thirdparty/recipe.js +++ b/lib/build/recipe/thirdparty/recipe.js @@ -56,7 +56,7 @@ const authorisationUrl_1 = require("./api/authorisationUrl"); const recipeImplementation_1 = require("./recipeImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -136,13 +136,13 @@ class Recipe extends recipeModule_1.default { ); this.providers = this.config.signInAndUpFeature.providers; { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default(querier_1.Querier.getNewInstanceOrThrowError(recipeId)) ); this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } } diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index 7dbb18180..823875c39 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -5,7 +5,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type UserInfo = { id: string; email?: { diff --git a/lib/build/recipe/thirdpartyemailpassword/recipe.js b/lib/build/recipe/thirdpartyemailpassword/recipe.js index 5f1d14ab6..cac31c5b7 100644 --- a/lib/build/recipe/thirdpartyemailpassword/recipe.js +++ b/lib/build/recipe/thirdpartyemailpassword/recipe.js @@ -58,7 +58,7 @@ const thirdPartyAPIImplementation_1 = require("./api/thirdPartyAPIImplementation const emailPasswordAPIImplementation_1 = require("./api/emailPasswordAPIImplementation"); const implementation_1 = require("./api/implementation"); const querier_1 = require("../../querier"); -const override_1 = require("../../override"); +const supertokens_js_override_1 = require("supertokens-js-override"); class Recipe extends recipeModule_1.default { constructor(recipeId, appInfo, isInServerlessEnv, config, recipes) { super(recipeId, appInfo); @@ -131,7 +131,7 @@ class Recipe extends recipeModule_1.default { }); this.config = utils_1.validateAndNormaliseUserInput(this, appInfo, config); { - let builder = new override_1.default( + let builder = new supertokens_js_override_1.default( recipeImplementation_1.default( querier_1.Querier.getNewInstanceOrThrowError(recipe_2.default.RECIPE_ID), querier_1.Querier.getNewInstanceOrThrowError(recipe_3.default.RECIPE_ID) @@ -140,7 +140,7 @@ class Recipe extends recipeModule_1.default { this.recipeInterfaceImpl = builder.override(this.config.override.functions).build(); } { - let builder = new override_1.default(implementation_1.default()); + let builder = new supertokens_js_override_1.default(implementation_1.default()); this.apiImpl = builder.override(this.config.override.apis).build(); } this.emailVerificationRecipe = diff --git a/lib/build/recipe/thirdpartyemailpassword/types.d.ts b/lib/build/recipe/thirdpartyemailpassword/types.d.ts index 86e4d6e82..1263643a1 100644 --- a/lib/build/recipe/thirdpartyemailpassword/types.d.ts +++ b/lib/build/recipe/thirdpartyemailpassword/types.d.ts @@ -12,7 +12,7 @@ import { TypeInputResetPasswordUsingTokenFeature, APIOptions as EmailPasswordAPIOptionsOriginal, } from "../emailpassword/types"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export declare type User = { id: string; timeJoined: number; diff --git a/lib/ts/override.ts b/lib/ts/override.ts deleted file mode 100644 index c4c267328..000000000 --- a/lib/ts/override.ts +++ /dev/null @@ -1,86 +0,0 @@ -type ProxiedImplementation = { - [P in keyof T]: T[P]; -} & { - _call: (fname: K, args: any[]) => T[K]; -}; - -function getProxyObject any)>>(orig: T): T { - const ret: ProxiedImplementation = { - ...orig, - _call: (_, __) => { - throw new Error("This function should only be called through the recipe object"); - }, - }; - const keys = Object.keys(ret) as (keyof typeof ret)[]; - for (const k of keys) { - if (k !== "_call") { - ret[k] = function (this: ProxiedImplementation, ...args: any[]) { - return this._call(k, args); - } as ProxiedImplementation[keyof T]; - } - } - return ret; -} - -export default class OverrideableBuilder any)>> { - private layers: [T, ...Partial[]]; - private proxies: T[]; - result?: T; - - constructor(originalImplementation: T) { - this.layers = [originalImplementation]; - this.proxies = []; - } - - override(overrideFunc: (originalImplementation: T, builder?: OverrideableBuilder) => T): OverrideableBuilder { - const proxy = getProxyObject(this.layers[0]) as T; - const layer = overrideFunc(proxy, this); - for (const key of Object.keys(this.layers[0]) as (keyof T)[]) { - if (layer[key] === proxy[key] || key === "_call") { - delete layer[key]; - } else if (layer[key] === undefined) { - layer[key] = null as any; - } - } - - this.layers.push(layer); - this.proxies.push(proxy); - - return this; - } - - build() { - if (this.result) { - return this.result; - } - - this.result = {} as T; - for (const layer of this.layers) { - for (const key of Object.keys(layer) as (keyof T)[]) { - const func = layer[key]; - if (func !== undefined) { - if (func === null) { - this.result[key] = undefined as any; - } else if (typeof func === "function") { - this.result[key] = func.bind(this.result) as T[keyof T]; - } else { - this.result[key] = func as T[keyof T]; - } - } - } - } - - for (let proxyInd = 0; proxyInd < this.proxies.length; ++proxyInd) { - const proxy = this.proxies[proxyInd]; - (proxy as any)._call = (fname: K, args: any) => { - for (let i = proxyInd; i >= 0; --i) { - const func = this.layers[i][fname]; - if (func !== undefined) { - return func.bind(this.result)(...args); - } - } - }; - } - return this.result; - } -} diff --git a/lib/ts/recipe/emailpassword/recipe.ts b/lib/ts/recipe/emailpassword/recipe.ts index a6514f6d8..40cdf5807 100644 --- a/lib/ts/recipe/emailpassword/recipe.ts +++ b/lib/ts/recipe/emailpassword/recipe.ts @@ -37,7 +37,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; diff --git a/lib/ts/recipe/emailpassword/types.ts b/lib/ts/recipe/emailpassword/types.ts index f65a62af1..8091603e8 100644 --- a/lib/ts/recipe/emailpassword/types.ts +++ b/lib/ts/recipe/emailpassword/types.ts @@ -19,7 +19,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; const TypeString = { type: "string", diff --git a/lib/ts/recipe/emailverification/recipe.ts b/lib/ts/recipe/emailverification/recipe.ts index a19deefbd..b14a1769f 100644 --- a/lib/ts/recipe/emailverification/recipe.ts +++ b/lib/ts/recipe/emailverification/recipe.ts @@ -26,7 +26,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; diff --git a/lib/ts/recipe/emailverification/types.ts b/lib/ts/recipe/emailverification/types.ts index 54b6863e5..228351168 100644 --- a/lib/ts/recipe/emailverification/types.ts +++ b/lib/ts/recipe/emailverification/types.ts @@ -14,7 +14,7 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export type TypeInput = { getEmailForUserId: (userId: string) => Promise; diff --git a/lib/ts/recipe/jwt/recipe.ts b/lib/ts/recipe/jwt/recipe.ts index f974d41ec..ba40ff59a 100644 --- a/lib/ts/recipe/jwt/recipe.ts +++ b/lib/ts/recipe/jwt/recipe.ts @@ -27,7 +27,7 @@ import { GET_JWKS_API } from "./constants"; import RecipeImplementation from "./recipeImplementation"; import { APIInterface, RecipeInterface, TypeInput, TypeNormalisedInput } from "./types"; import { validateAndNormaliseUserInput } from "./utils"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export default class Recipe extends RecipeModule { static RECIPE_ID = "jwt"; diff --git a/lib/ts/recipe/jwt/types.ts b/lib/ts/recipe/jwt/types.ts index 688defb6d..59a6cf909 100644 --- a/lib/ts/recipe/jwt/types.ts +++ b/lib/ts/recipe/jwt/types.ts @@ -14,7 +14,7 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export type JsonWebKey = { kty: string; diff --git a/lib/ts/recipe/session/recipe.ts b/lib/ts/recipe/session/recipe.ts index 5e2bba495..6f0829ec6 100644 --- a/lib/ts/recipe/session/recipe.ts +++ b/lib/ts/recipe/session/recipe.ts @@ -27,7 +27,7 @@ import RecipeImplementation from "./recipeImplementation"; import { Querier } from "../../querier"; import APIImplementation from "./api/implementation"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; // For Express export default class SessionRecipe extends RecipeModule { diff --git a/lib/ts/recipe/session/types.ts b/lib/ts/recipe/session/types.ts index a38c81870..c20b5add0 100644 --- a/lib/ts/recipe/session/types.ts +++ b/lib/ts/recipe/session/types.ts @@ -14,7 +14,7 @@ */ import { BaseRequest, BaseResponse } from "../../framework"; import NormalisedURLPath from "../../normalisedURLPath"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export type KeyInfo = { publicKey: string; diff --git a/lib/ts/recipe/thirdparty/recipe.ts b/lib/ts/recipe/thirdparty/recipe.ts index b4ef2d5a3..cdefa5d16 100644 --- a/lib/ts/recipe/thirdparty/recipe.ts +++ b/lib/ts/recipe/thirdparty/recipe.ts @@ -28,7 +28,7 @@ import RecipeImplementation from "./recipeImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; diff --git a/lib/ts/recipe/thirdparty/types.ts b/lib/ts/recipe/thirdparty/types.ts index 070086cab..135a23a62 100644 --- a/lib/ts/recipe/thirdparty/types.ts +++ b/lib/ts/recipe/thirdparty/types.ts @@ -19,7 +19,7 @@ import { } from "../emailverification"; import { TypeInput as TypeInputEmailVerification } from "../emailverification/types"; import { BaseRequest, BaseResponse } from "../../framework"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; const TypeAny = { type: "any", diff --git a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts index a5e373c2f..6f06b811f 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts @@ -31,7 +31,7 @@ import getThirdPartyIterfaceImpl from "./api/thirdPartyAPIImplementation"; import getEmailPasswordIterfaceImpl from "./api/emailPasswordAPIImplementation"; import APIImplementation from "./api/implementation"; import { Querier } from "../../querier"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; export default class Recipe extends RecipeModule { private static instance: Recipe | undefined = undefined; diff --git a/lib/ts/recipe/thirdpartyemailpassword/types.ts b/lib/ts/recipe/thirdpartyemailpassword/types.ts index 5245a96d7..709a78be5 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/types.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/types.ts @@ -26,7 +26,7 @@ import { InputResetPasswordUsingTokenFeatureSchema, APIOptions as EmailPasswordAPIOptionsOriginal, } from "../emailpassword/types"; -import OverrideableBuilder from "../../override"; +import OverrideableBuilder from "supertokens-js-override"; const TypeString = { type: "string", diff --git a/package-lock.json b/package-lock.json index 9ab206047..92acc6f7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6268,6 +6268,10 @@ "superagent": "^3.8.3" } }, + "supertokens-js-override": { + "version": "git+https://github.com/supertokens/supertokens-js-override.git#983fff930fb013ff3c4c0317dba9e2ef6f70593c", + "from": "git+https://github.com/supertokens/supertokens-js-override.git#v0.0.2" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 105519653..98daf78e3 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ "cookie": "0.4.0", "jsonschema": "1.4.0", "jsonwebtoken": "8.5.1", - "psl": "1.8.0" + "psl": "1.8.0", + "supertokens-js-override": "git+https://github.com/supertokens/supertokens-js-override.git#v0.0.2" }, "devDependencies": { "@hapi/hapi": "^20.2.0",