Unify web SDK Client auth factories#1481
Conversation
Greptile SummaryThis PR unifies the Web SDK into a single generic Confidence Score: 4/5Safe to merge; one minor type-chain quirk in No P0/P1 issues found in the new code. The only finding is a P2 style concern in
Important Files Changed
Reviews (16): Last reviewed commit: "Avoid unused auth imports in dual servic..." | Re-trigger Greptile |
31090ee to
2e8c91b
Compare
8d88082 to
5d5bfba
Compare
5d5bfba to
6d4e4fa
Compare
Adds a ServerClient sibling class to the web SDK alongside the existing Client. Service classes are generic over `Client | ServerClient` when they have any client-tier methods, with TypeScript `this`-types gating admin methods (e.g. `Databases.createCollection` requires `Databases<ServerClient>`). Services with no client-tier methods (Health, Tokens, Sites, Users) are non-generic and require a ServerClient at construction. Tier detection is driven entirely off existing `x-appwrite.platforms` spec tags. The existing Client surface is unchanged — purely additive for current `appwrite` web users; sets up the path to consolidate `appwrite` + `node-appwrite` into a single isomorphic package. - Filter `Key` out of Client header iterations so Client cannot setKey - Add server-client.ts.twig (setKey/setJWT/setLocale + HTTP plumbing, no realtime, no session/devkey/impersonate) - Type-gate service methods via `this: Service<ServerClient>` (or `<Client>` for the few client-only methods like webAuth/location) - Re-export ServerClient from index.ts - Register the new template in Web.php getFiles() Verified on regenerated examples/web/: tsc --noEmit passes; negative tests confirm `new Health(browserClient)` and admin calls on a Client-bound service fail to type-check; djlint passes.
d8a6359 to
071a493
Compare
Summary
Refactors the generated Web SDK so browser and server usage share one
Clientclass instead of emitting separateClientandServerClientclasses. The SDK now exposes typed factory methods for the supported auth modes and uses those auth capabilities to gate service methods at compile time.This keeps the merged web/node SDK direction intact while making the public API simpler: users construct the client from the credential shape they already have, then pass that client to generated services.
Client API
The generated
Clientnow supports these static constructors:Client.anonymous(params)/Client.fromAnonymous(params)anonymousClient.fromSession(params)sessionClient.fromJWT(params)jwtClient.fromDevKey(params)devKeyClient.fromImpersonation(params)impersonationuserId,email, orphone.Client.fromApiKey(params)apiKeyAll factories use object parameters. Common fields are
endpoint,projectId, optionalendpointRealtime, and optionallocale. Auth-specific fields are named by credential type, for examplesession,jwt,devKey, orapiKey.The existing fluent setters are still present for compatibility. Setters that establish an auth mode narrow the TypeScript type, for example
new Client().setEndpoint(...).setProject(...).setKey(...)becomesClient<'apiKey'>and can be used with admin-only methods. These setters continue to mutatethis, so existing imperative usage such asclient.setKey(key)remains valid. They now also update runtime andx-sdk-platformto match the equivalent factory behavior.Type Safety
The generated client is generic over an auth capability:
Service generation uses those types directly:
Client<AdminAuth>.Client<BrowserAuth>.Service<TAuth extends ClientAuth = ClientAuth>and use TypeScriptthisparameter gates for individual methods.Client<BrowserAuth>in the Web SDK. React Native keeps its non-genericClienttype because it reuses the realtime template but has a different client implementation.This means a mixed service like
TablesDBcan expose shared methods to both client kinds while rejecting admin-only calls when constructed withClient.fromSession(...)orClient.fromDevKey(...).Implementation Details
templates/web/src/client.ts.twigClient, adds staticfrom*factories, adds runtime-aware request behavior, exports auth capability types, treats dev keys as browser/client auth, and keeps fluent setters mutation-compatible while aligning runtime/platform headers with factories.templates/web/src/server-client.ts.twigsrc/SDK/Language/Web.phpsrc/server-client.tsfrom the generated Web SDK file list.templates/web/src/services/template.ts.twigtemplates/web/src/services/realtime.ts.twigtemplates/web/src/index.ts.twigClientAuth,AdminAuth, andBrowserAuthfromclient.ts..github/workflows/sdk-build-validation.ymlReview Feedback Addressed
ServerClienttype alias/export so the public surface now matches the intended single-Clientfactory API.setKey,setSession, and impersonation setters so legacy setter chains andClient.from*factories agree on runtime andx-sdk-platformbehavior.client.setKey(key).Client<BrowserAuth>narrowing Web-only so React Native builds do not import Web-only auth capability types.ClientAuth/AdminAuth/BrowserAuthaliases in pure browser or pure server services.location/webAuthmethod gates so dual browser/server-platform methods remain callable from both valid auth tiers.AdminAuth/BrowserAuthaliases.Runtime Behavior
The unified client keeps the same HTTP plumbing but now tracks whether it is being used in
browserorservermode. API-key factories/setters use server runtime. Session, JWT, dev-key, anonymous, and impersonation factories/setters use browser runtime.Browser-only behavior, such as fallback cookies, credential inclusion, opaque response handling, and browser
FormData/Fileassumptions, is kept behind browser-runtime checks. Server auth fields such as API key, forwarded user agent, JWT, and locale are configured on the same client config object.fromImpersonationvalidates that exactly one target is provided at runtime, and the parameter type also rejects multiple targets at compile time.Validation
Local validation performed:
php example.php web servercd examples/web && npm run buildphp example.php react-native clientcd examples/react-native && npm run buildcomposer lint-twigphp example.php web serverafter conditional service import changescd examples/web && npm run buildafter conditional service import changesphp example.php web server,cd examples/web && npm run build, andcomposer lint-twigafter dual-platformlocation/webAuthgate cleanupphp example.php web server,cd examples/web && npm run build, andcomposer lint-twigafter method-level auth import flag cleanupCI has shown Greptile, Twig lint,
web (client),web (server),web (console),react-native (client),node (server), and other validation jobs passing on the prior commit while the broader matrix continues to drain through queued runners. The latest dev-key correction has been pushed and will re-run those checks.The temporary local type-check scripts and regenerated example output were not committed.