Last active
February 26, 2025 15:34
-
-
Save brenoliradev/3717e57d5725189ffb51570bb991ce6b to your computer and use it in GitHub Desktop.
Palmares Authentication RFC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type AdapterMethods<TParams = any, TReturn = any> = { | |
[key: string]: (params: TParams) => Promise<TReturn> | TReturn; | |
} | |
type Adapter<TName extends string, TMethods extends AdapterMethods> = { | |
name: TName; | |
methods: TMethods; | |
} | |
type AuthProxy<TAdapters extends readonly Adapter<string, AdapterMethods>[]> = { | |
[KAdapter in TAdapters[number] as KAdapter['name']]: KAdapter['methods']; | |
}; | |
const createAdapterProxy = <TMethods extends AdapterMethods> | |
(methods: TMethods): TMethods => new Proxy({} as TMethods, { | |
get(_, prop: string) { | |
if (prop in methods) { | |
return methods[prop]; | |
} | |
throw new Error(`Method ${String(prop)} not found`); | |
} | |
}); | |
const createAuthProxy = <TAdapters extends readonly Adapter<string, AdapterMethods>[]> | |
(adapters: TAdapters) => new Proxy({}, { | |
get(_, adapterName: string) { | |
const adapter = adapters.find(a => a.name === adapterName); | |
if (adapter) { | |
return createAdapterProxy(adapter.methods); | |
} | |
throw new Error(`Adapter "${adapterName}" not found`); | |
} | |
}) as AuthProxy<TAdapters>; | |
function createDomain< | |
TAdapters extends readonly Adapter<string, AdapterMethods>[] | |
>(config: { adapters: TAdapters }) { | |
const auth = createAuthProxy(config.adapters); | |
return { | |
auth, | |
// ... other domain properties | |
}; | |
} | |
const DiscordAdapter: Adapter< | |
'discord', | |
{ | |
login: ({ clientId }: { clientId: string }) => void; | |
callback: ({ code }: { code: string }) => void; | |
} | |
> = { | |
name: 'discord', | |
methods: { | |
login: (params) => console.log('Logging in with Discord:', params), | |
callback: (params) => console.log('Handling Discord callback:', params) | |
} | |
}; | |
const GithubAdapter: Adapter< | |
'github', | |
{ | |
handle: ({ clientId }: { clientId: string }) => void; | |
} | |
> = { | |
name: 'github', | |
methods: { | |
handle: (params) => console.log('Logging in with Github:', params), | |
} | |
}; | |
const domain = createDomain({ | |
adapters: [DiscordAdapter, GithubAdapter] | |
}); | |
console.log(domain.auth.discord) | |
// Test usage | |
domain.auth.discord.login({ clientId: '123' }); | |
domain.auth.discord.callback({ code: 'abc' }); | |
domain.auth.github.handle({ clientId: '456' }); | |
domain.auth.discord.login({ wrongParam: true }); | |
domain.auth.nonexistentAdapter.method(); | |
domain.auth.github.nonexistentMethod(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment