@auth-craft/client 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -254,7 +254,22 @@ worker file is loaded, so no bundler worker configuration is needed.
254
254
  > `verifyAuthenticator({ body: { method: 'totp', data: { code: '123456' } } })`.
255
255
 
256
256
  ### `oauth`
257
- `oauthState()` *(public)* · `oauthCallback({ body })` *(public, login)* · `linkProvider({ body })` · `unlinkProvider({ body })` · `getProviders()`
257
+ `oauthState()` *(public)* · `oauthStart({ body })` *(public)* · `oauthCallback({ body })` *(public, login)* · `linkProvider({ body })` · `unlinkProvider({ body })` · `getProviders()`
258
+
259
+ Provider sign-in is two calls on `client.oauth` (with `@auth-craft/client/core`, wrap the group: `withOAuthFlow(core.group(oauthContract))`):
260
+
261
+ ```ts
262
+ await client.oauth.start('google') // leaves for the provider; remembers this page
263
+
264
+ // on the page the provider returns to
265
+ const done = await client.oauth.finish() // reads ?code&state
266
+ if (!done.ok) return showError(done.errors) // done.meta?.params?.returnTo: the page to offer going back to
267
+ if (done.data.status === 'cancelled') return location.assign(done.data.returnTo)
268
+ if ('requiresMfa' in done.data.login) return askForCode(done.data.login.mfa)
269
+ location.assign(done.data.returnTo) // always a path on this site
270
+ ```
271
+
272
+ `status` is `'cancelled'` when the visitor declined at the provider (`error=access_denied`), and `'completed'` when the provider step finished: `login` holds tokens or a further step. Any other provider error is `OAUTH_PROVIDER_ERROR`.
258
273
 
259
274
  ### `users`
260
275
  `updateProfile({ body })`
@@ -531,7 +546,10 @@ await client.init()
531
546
  - **MFA codes go in `data`**, and the field is `authenticatorId` (not `id`).
532
547
  - **OAuth never accepts `accessToken`** — the backend rejects it (token
533
548
  substitution). Use `code` or `credential`. For the redirect/code flow, call
534
- `oauth.oauthState()` first and forward the returned `state` to the provider.
549
+ `oauth.oauthState()` first, forward the returned `state` to the provider, and
550
+ send it back with the `code` — a `code` without a matching `state` is rejected
551
+ with `403 OAUTH_STATE_MISMATCH`. This applies to `oauth.linkProvider` too
552
+ (`body: { provider, code, state }`).
535
553
  - **Permissions are string arrays** (`roles`, `authPerms`), not numeric masks.
536
554
  - **Login returns a union** — branch with `isAuthTokens` / `isChallengeRequired`
537
555
  / `isMfaRequired` / `isVerificationRequired` (see
@@ -86,6 +86,8 @@ export declare class ClientCore {
86
86
  destroy(): void;
87
87
  }
88
88
  export declare function createClientCore(config: ClientCoreConfig): Promise<ClientCore>;
89
+ export type { OAuthClient, OAuthEndpoints, OAuthFinish, OAuthFinishOptions, OAuthStartOptions } from './oauth-flow.js';
90
+ export { safeReturnTo, withOAuthFlow } from './oauth-flow.js';
89
91
  export type { AuthResult, ContractClient, EndpointMethod } from './proxy.js';
90
92
  export { buildClient } from './proxy.js';
91
93
  //# sourceMappingURL=core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
package/dist/core/core.js CHANGED
@@ -106,5 +106,6 @@ export async function createClientCore(config) {
106
106
  await core.init();
107
107
  return core;
108
108
  }
109
+ export { safeReturnTo, withOAuthFlow } from './oauth-flow.js';
109
110
  export { buildClient } from './proxy.js';
110
111
  //# sourceMappingURL=core.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Provider sign-in as two calls: `start` leaves for the provider, `finish` runs on
3
+ * the page it sends the visitor back to.
4
+ *
5
+ * Runs on the page, not in the worker: it navigates and needs sessionStorage. The
6
+ * `state` CSRF check is the server's (cookie against body), so what is stored here
7
+ * is only where to carry on; `safeReturnTo` is re-applied on the way out because
8
+ * storage is not trusted either.
9
+ */
10
+ import { type Result } from 'ts-micro-result';
11
+ /**
12
+ * What the flow needs of `core.group(oauthContract)`. Described by shape: core
13
+ * stays free of any specific contract group, and `TLogin` comes from the caller's.
14
+ */
15
+ export interface OAuthEndpoints<TLogin> {
16
+ oauthStart(arg: {
17
+ body: {
18
+ provider: string;
19
+ };
20
+ }): Promise<Result<{
21
+ authorizationUrl: string;
22
+ }>>;
23
+ oauthCallback(arg: {
24
+ body: {
25
+ provider: string;
26
+ code: string;
27
+ state: string;
28
+ tenantId?: string;
29
+ };
30
+ }): Promise<Result<TLogin>>;
31
+ }
32
+ export interface OAuthStartOptions {
33
+ /** Where `finish` hands back to. Default: the current page. */
34
+ returnTo?: string;
35
+ }
36
+ export interface OAuthFinishOptions {
37
+ /** Tenant to sign in to, if the app already knows it. */
38
+ tenantId?: string;
39
+ /** Needed only if the page has no storage left from `start`. */
40
+ provider?: string;
41
+ }
42
+ /**
43
+ * A visitor who declined at the provider is not a failure, so it is a `status` and not
44
+ * an error. `completed` says only that the provider step finished: `login` may still
45
+ * be a further step.
46
+ *
47
+ * Failures after the provider sent the visitor back carry the same path in
48
+ * `meta.params.returnTo`.
49
+ */
50
+ export type OAuthFinish<TLogin> = {
51
+ status: 'completed';
52
+ /** Tokens, or a further step: check `requiresMfa` / `requiresChallenge` as for any login. */
53
+ login: TLogin;
54
+ /** A path on this site, safe to navigate to. */
55
+ returnTo: string;
56
+ } | {
57
+ status: 'cancelled';
58
+ /** A path on this site, safe to navigate to. */
59
+ returnTo: string;
60
+ };
61
+ export type OAuthClient<G> = G extends OAuthEndpoints<infer TLogin> ? G & {
62
+ start(provider: string, options?: OAuthStartOptions): Promise<Result<void>>;
63
+ finish(params?: URLSearchParams | string, options?: OAuthFinishOptions): Promise<Result<OAuthFinish<TLogin>>>;
64
+ } : never;
65
+ /**
66
+ * A path on this origin, or '/' for anything else: an absolute URL, `//host`, and
67
+ * `/\host`, which browsers read as `//host`, would all turn sign-in into an open redirect.
68
+ */
69
+ export declare function safeReturnTo(value: string | null | undefined, origin: string): string;
70
+ /** Add `start` and `finish` to the group from `core.group(oauthContract)`. */
71
+ export declare function withOAuthFlow<TLogin, G extends OAuthEndpoints<TLogin>>(group: G): OAuthClient<G>;
72
+ //# sourceMappingURL=oauth-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM;IACpC,UAAU,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/F,aAAa,CAAC,GAAG,EAAE;QACjB,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5E,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,IAC1B;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,MAAM,MAAM,WAAW,CAAC,CAAC,IACvB,CAAC,SAAS,cAAc,CAAC,MAAM,MAAM,CAAC,GAClC,CAAC,GAAG;IACF,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CAC/G,GACD,KAAK,CAAC;AAEZ;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASrF;AAoBD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,MAAM,EAAE,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CA6ChG"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Provider sign-in as two calls: `start` leaves for the provider, `finish` runs on
3
+ * the page it sends the visitor back to.
4
+ *
5
+ * Runs on the page, not in the worker: it navigates and needs sessionStorage. The
6
+ * `state` CSRF check is the server's (cookie against body), so what is stored here
7
+ * is only where to carry on; `safeReturnTo` is re-applied on the way out because
8
+ * storage is not trusted either.
9
+ */
10
+ import { err, ok } from 'ts-micro-result';
11
+ const STORAGE_KEY = 'auth-craft:oauth';
12
+ /**
13
+ * A path on this origin, or '/' for anything else: an absolute URL, `//host`, and
14
+ * `/\host`, which browsers read as `//host`, would all turn sign-in into an open redirect.
15
+ */
16
+ export function safeReturnTo(value, origin) {
17
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is being refused
18
+ if (!value || !value.startsWith('/') || value.startsWith('//') || /[\\\u0000-\u001f]/.test(value))
19
+ return '/';
20
+ try {
21
+ const url = new URL(value, origin);
22
+ return url.origin === origin ? `${url.pathname}${url.search}${url.hash}` : '/';
23
+ }
24
+ catch {
25
+ return '/';
26
+ }
27
+ }
28
+ function remember(provider, returnTo) {
29
+ try {
30
+ sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ provider, returnTo }));
31
+ }
32
+ catch {
33
+ // No storage: `finish` falls back to the home page.
34
+ }
35
+ }
36
+ function recall() {
37
+ try {
38
+ const stored = sessionStorage.getItem(STORAGE_KEY);
39
+ sessionStorage.removeItem(STORAGE_KEY);
40
+ return stored ? JSON.parse(stored) : {};
41
+ }
42
+ catch {
43
+ return {};
44
+ }
45
+ }
46
+ /** Add `start` and `finish` to the group from `core.group(oauthContract)`. */
47
+ export function withOAuthFlow(group) {
48
+ const flow = {
49
+ async start(provider, options) {
50
+ const { origin, pathname, search } = window.location;
51
+ const started = await group.oauthStart({ body: { provider } });
52
+ if (!started.ok)
53
+ return err(started.errors, started.meta);
54
+ remember(provider, safeReturnTo(options?.returnTo ?? `${pathname}${search}`, origin));
55
+ window.location.assign(started.data.authorizationUrl);
56
+ return ok();
57
+ },
58
+ async finish(params = window.location.search, options) {
59
+ const query = typeof params === 'string' ? new URLSearchParams(params) : params;
60
+ const stored = recall();
61
+ const returnTo = safeReturnTo(typeof stored.returnTo === 'string' ? stored.returnTo : '/', window.location.origin);
62
+ const providerError = query.get('error');
63
+ if (providerError === 'access_denied')
64
+ return ok({ status: 'cancelled', returnTo });
65
+ if (providerError) {
66
+ return err({ code: 'OAUTH_PROVIDER_ERROR', message: 'The provider did not complete the sign-in' }, { params: { returnTo } });
67
+ }
68
+ const code = query.get('code');
69
+ const state = query.get('state');
70
+ const provider = options?.provider ?? (typeof stored.provider === 'string' ? stored.provider : undefined);
71
+ if (!code || !state || !provider) {
72
+ return err({ code: 'OAUTH_CALLBACK_INVALID', message: 'This page was not opened by a provider sign-in' }, { params: { returnTo } });
73
+ }
74
+ const login = await group.oauthCallback({
75
+ body: { provider, code, state, ...(options?.tenantId !== undefined && { tenantId: options.tenantId }) },
76
+ });
77
+ if (!login.ok)
78
+ return err(login.errors, { ...login.meta, params: { ...login.meta?.params, returnTo } });
79
+ return ok({ status: 'completed', login: login.data, returnTo });
80
+ },
81
+ };
82
+ return { ...group, ...flow };
83
+ }
84
+ //# sourceMappingURL=oauth-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-flow.js","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * per-group contract subpaths (`@auth-craft/api-contract/auth`, `/tenant`, …).
14
14
  */
15
15
  import { authContract, mfaContract, oauthContract, passwordContract, sessionContract, tenantsContract, usersContract, verificationContract } from '@auth-craft/api-contract';
16
- import { ClientCore, type ClientCoreConfig, type ContractClient } from './core/core.js';
16
+ import { ClientCore, type ClientCoreConfig, type ContractClient, type OAuthClient } from './core/core.js';
17
17
  export type AuthCraftClientConfig = ClientCoreConfig;
18
18
  export declare class AuthCraftClient extends ClientCore {
19
19
  auth: ContractClient<typeof authContract>;
@@ -21,7 +21,7 @@ export declare class AuthCraftClient extends ClientCore {
21
21
  verification: ContractClient<typeof verificationContract>;
22
22
  session: ContractClient<typeof sessionContract>;
23
23
  mfa: ContractClient<typeof mfaContract>;
24
- oauth: ContractClient<typeof oauthContract>;
24
+ oauth: OAuthClient<ContractClient<typeof oauthContract>>;
25
25
  users: ContractClient<typeof usersContract>;
26
26
  tenant: ContractClient<typeof tenantsContract>;
27
27
  init(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExF,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAErD,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,IAAI,EAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;IAC3C,QAAQ,EAAG,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC;IACnD,YAAY,EAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;IAC3D,OAAO,EAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;IACjD,GAAG,EAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CAAC;IACzC,KAAK,EAAG,cAAc,CAAC,OAAO,aAAa,CAAC,CAAC;IAC7C,KAAK,EAAG,cAAc,CAAC,OAAO,aAAa,CAAC,CAAC;IAC7C,MAAM,EAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;IAE1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1B;CACF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAEpF;AAED,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAErD,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,IAAI,EAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;IAC3C,QAAQ,EAAG,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC;IACnD,YAAY,EAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;IAC3D,OAAO,EAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;IACjD,GAAG,EAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CAAC;IACzC,KAAK,EAAG,WAAW,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAG,cAAc,CAAC,OAAO,aAAa,CAAC,CAAC;IAC7C,MAAM,EAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;IAE1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1B;CACF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAEpF;AAED,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * per-group contract subpaths (`@auth-craft/api-contract/auth`, `/tenant`, …).
14
14
  */
15
15
  import { authContract, mfaContract, oauthContract, passwordContract, sessionContract, tenantsContract, usersContract, verificationContract, } from '@auth-craft/api-contract';
16
- import { ClientCore } from './core/core.js';
16
+ import { ClientCore, withOAuthFlow, } from './core/core.js';
17
17
  export class AuthCraftClient extends ClientCore {
18
18
  auth;
19
19
  password;
@@ -30,7 +30,7 @@ export class AuthCraftClient extends ClientCore {
30
30
  this.verification = this.group(verificationContract);
31
31
  this.session = this.group(sessionContract);
32
32
  this.mfa = this.group(mfaContract);
33
- this.oauth = this.group(oauthContract);
33
+ this.oauth = withOAuthFlow(this.group(oauthContract));
34
34
  this.users = this.group(usersContract);
35
35
  this.tenant = this.group(tenantsContract);
36
36
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAA8C,MAAM,gBAAgB,CAAC;AAIxF,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAC7C,IAAI,CAAuC;IAC3C,QAAQ,CAA2C;IACnD,YAAY,CAA+C;IAC3D,OAAO,CAA0C;IACjD,GAAG,CAAsC;IACzC,KAAK,CAAwC;IAC7C,KAAK,CAAwC;IAC7C,MAAM,CAA0C;IAEhD,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAUD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,UAAU,EAIV,aAAa,GACd,MAAM,gBAAgB,CAAC;AAIxB,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAC7C,IAAI,CAAuC;IAC3C,QAAQ,CAA2C;IACnD,YAAY,CAA+C;IAC3D,OAAO,CAA0C;IACjD,GAAG,CAAsC;IACzC,KAAK,CAAqD;IAC1D,KAAK,CAAwC;IAC7C,MAAM,CAA0C;IAEhD,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAUD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.test-d.js","sourceRoot":"","sources":["../src/types.test-d.ts"],"names":[],"mappings":"AA4CA,KAAM,YAA6B,CAAC;AAIpC,uDAAuD;AACvD,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC;AAEjB,yDAAyD;AACzD,KAAK,MAAM,CAAC,YAAY,CAAC;IACvB,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE;CAC5G,CAAC,CAAC;AAEH,oCAAoC;AACpC,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAEvD,sDAAsD;AACtD,+DAA+D;AAC/D,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAE9D,+CAA+C;AAC/C,iDAAiD;AACjD,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAErD,kCAAkC;AAClC,oDAAoD;AACpD,KAAK,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"types.test-d.js","sourceRoot":"","sources":["../src/types.test-d.ts"],"names":[],"mappings":"AA+CA,KAAM,YAA6B,CAAC;AAIpC,uDAAuD;AACvD,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC;AAEjB,yDAAyD;AACzD,KAAK,MAAM,CAAC,YAAY,CAAC;IACvB,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE;CAC5G,CAAC,CAAC;AAEH,oCAAoC;AACpC,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAEvD,sDAAsD;AACtD,+DAA+D;AAC/D,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAE9D,+CAA+C;AAC/C,iDAAiD;AACjD,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAErD,kCAAkC;AAClC,oDAAoD;AACpD,KAAK,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auth-craft/client",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "description": "Contract-driven typed frontend client for Auth Craft. Methods are generated from @auth-craft/api-contract; tokens are isolated in a Web Worker. Import the root for all groups, or @auth-craft/client/core for a scope-agnostic core you wire per scope.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,11 +27,11 @@
27
27
  "dependencies": {
28
28
  "ts-micro-result": "^3.3.0",
29
29
  "valibot": "^1.5.0",
30
- "@auth-craft/api-contract": "^0.1.3"
30
+ "@auth-craft/api-contract": "^0.5.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "typescript": "^7.0.2",
34
- "vitest": "^5.0.3"
34
+ "vitest": "^5.0.5"
35
35
  },
36
36
  "license": "MIT",
37
37
  "publishConfig": {