@andco/sdk 0.0.3 → 0.0.4

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.
Files changed (82) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +93 -49
  3. package/dist/auth.d.ts +5 -3
  4. package/dist/auth.d.ts.map +1 -1
  5. package/dist/auth.js +10 -17
  6. package/dist/browser/controller.d.ts +46 -0
  7. package/dist/browser/controller.d.ts.map +1 -1
  8. package/dist/browser/controller.js +102 -12
  9. package/dist/browser/frame.d.ts.map +1 -1
  10. package/dist/browser/frame.js +6 -15
  11. package/dist/browser/index.d.ts +8 -2
  12. package/dist/browser/index.d.ts.map +1 -1
  13. package/dist/browser/index.js +48 -33
  14. package/dist/browser/popup.d.ts +4 -0
  15. package/dist/browser/popup.d.ts.map +1 -1
  16. package/dist/browser/popup.js +23 -7
  17. package/dist/cli/index.d.ts +4 -6
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/index.js +7 -13
  20. package/dist/cli/server.d.ts +5 -0
  21. package/dist/cli/server.d.ts.map +1 -1
  22. package/dist/cli/server.js +5 -0
  23. package/dist/client.d.ts +66 -19
  24. package/dist/client.d.ts.map +1 -1
  25. package/dist/client.js +117 -78
  26. package/dist/config.d.ts +2 -1
  27. package/dist/config.d.ts.map +1 -1
  28. package/dist/config.js +1 -0
  29. package/dist/credentials.d.ts +58 -4
  30. package/dist/credentials.d.ts.map +1 -1
  31. package/dist/credentials.js +0 -0
  32. package/dist/errors.d.ts +23 -21
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +18 -20
  35. package/dist/globals.d.ts +25 -0
  36. package/dist/globals.d.ts.map +1 -0
  37. package/dist/globals.js +15 -0
  38. package/dist/grants-api.d.ts +34 -0
  39. package/dist/grants-api.d.ts.map +1 -0
  40. package/dist/grants-api.js +48 -0
  41. package/dist/grants.d.ts +16 -0
  42. package/dist/grants.d.ts.map +1 -0
  43. package/dist/grants.js +13 -0
  44. package/dist/index.d.ts +12 -6
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +8 -3
  47. package/dist/inflight.d.ts +31 -0
  48. package/dist/inflight.d.ts.map +1 -0
  49. package/dist/inflight.js +26 -0
  50. package/dist/intents.d.ts +346 -70
  51. package/dist/intents.d.ts.map +1 -1
  52. package/dist/intents.js +629 -112
  53. package/dist/oauth.d.ts +55 -6
  54. package/dist/oauth.d.ts.map +1 -1
  55. package/dist/oauth.js +86 -57
  56. package/dist/presenter.d.ts +25 -11
  57. package/dist/presenter.d.ts.map +1 -1
  58. package/dist/presenter.js +39 -6
  59. package/dist/resource.d.ts +109 -0
  60. package/dist/resource.d.ts.map +1 -0
  61. package/dist/resource.js +151 -0
  62. package/dist/rest.d.ts +23 -4
  63. package/dist/rest.d.ts.map +1 -1
  64. package/dist/rest.js +46 -5
  65. package/dist/server/index.d.ts +3 -0
  66. package/dist/server/index.d.ts.map +1 -1
  67. package/dist/server/index.js +1 -0
  68. package/dist/server-metadata.generated.d.ts.map +1 -1
  69. package/dist/server-metadata.generated.js +8 -4
  70. package/dist/service.d.ts +109 -0
  71. package/dist/service.d.ts.map +1 -0
  72. package/dist/service.js +241 -0
  73. package/dist/session-store.d.ts +12 -4
  74. package/dist/session-store.d.ts.map +1 -1
  75. package/dist/session-store.js +64 -14
  76. package/dist/storage.d.ts +16 -23
  77. package/dist/storage.d.ts.map +1 -1
  78. package/dist/storage.js +27 -25
  79. package/dist/tokens.d.ts +46 -0
  80. package/dist/tokens.d.ts.map +1 -0
  81. package/dist/tokens.js +148 -0
  82. package/package.json +13 -3
@@ -1,4 +1,5 @@
1
1
  import { createServer } from "node:http";
2
+ /** Local OAuth callback receiver. The caller owns state/PKCE validation and server cleanup. */
2
3
  export class LoopbackServer {
3
4
  #server;
4
5
  #resolveCallback;
@@ -7,6 +8,7 @@ export class LoopbackServer {
7
8
  this.#redirectUri = configured;
8
9
  this.#server = this.#buildServer();
9
10
  }
11
+ /** Starts listening; a missing port selects an available port reflected in `redirectUri`. */
10
12
  static async start(configured) {
11
13
  const receiver = new LoopbackServer(configured);
12
14
  await receiver.listen();
@@ -19,9 +21,11 @@ export class LoopbackServer {
19
21
  receiver.#redirectUri.port = String(address.port);
20
22
  return receiver;
21
23
  }
24
+ /** Exact callback URL including the port allocated by the operating system. */
22
25
  get redirectUri() {
23
26
  return this.#redirectUri;
24
27
  }
28
+ /** Waits for a callback or returns `null` on timeout. Call `close()` after either outcome. */
25
29
  wait(timeoutMs) {
26
30
  return new Promise((resolve) => {
27
31
  this.#resolveCallback = resolve;
@@ -30,6 +34,7 @@ export class LoopbackServer {
30
34
  timer.unref?.();
31
35
  });
32
36
  }
37
+ /** Closes the listener and any remaining connections. */
33
38
  close() {
34
39
  return new Promise((resolve) => {
35
40
  this.#server.closeAllConnections?.();
package/dist/client.d.ts CHANGED
@@ -1,16 +1,22 @@
1
- import type { AndCoRandomSource } from "@andco/protocol";
2
1
  import { AndcoAuth } from "./auth.js";
3
2
  import { type AndcoConfig, type AndcoConfigInput } from "./config.js";
4
3
  import { type AndcoCredentials, type AndcoSession } from "./credentials.js";
4
+ import { type AndcoGlobals } from "./globals.js";
5
+ import { AndcoGrants } from "./grants-api.js";
6
+ import type { AndcoInflight } from "./inflight.js";
5
7
  import { AndcoIntents } from "./intents.js";
6
8
  import { type AndcoAuthorizationRequest, AndcoOAuth, type AndcoTransportMode } from "./oauth.js";
7
- import type { AndcoPresenter } from "./presenter.js";
9
+ import { AndcoPresenter } from "./presenter.js";
10
+ import { AndcoResource } from "./resource.js";
8
11
  import { AndcoRest } from "./rest.js";
9
12
  import { type AndcoSessionSource, AndcoSessionStore } from "./session-store.js";
10
- import type { AndcoLock, AndcoStorage } from "./storage.js";
13
+ import type { AndcoStorage } from "./storage.js";
14
+ import { AndcoTokens } from "./tokens.js";
11
15
  /** A Resource Server Definition: immutable, and able to bind itself to a client. */
12
16
  export interface AndcoResourceServer<Client> {
17
+ /** Registered Resource Server ID used in authorization contributions. */
13
18
  readonly id: string;
19
+ /** OAuth Resource Indicator used to select the matching bearer credential. */
14
20
  readonly resource: string;
15
21
  /**
16
22
  * Produces an operational client for this Resource Server from resolved credentials.
@@ -21,15 +27,11 @@ export interface AndcoResourceServer<Client> {
21
27
  */
22
28
  use(credentials: AndcoCredentials): Client;
23
29
  }
24
- /** Platform capabilities the SDK reads off the runtime, grouped so a future addition is not a breaking change. */
25
- export type AndcoGlobals = {
26
- fetch: typeof globalThis.fetch;
27
- /** Threaded into the Protocol Contract's `RANDOM_UUID`, so a runtime without Web Crypto can supply its own. */
28
- crypto: AndCoRandomSource;
29
- };
30
+ /** Configuration and runtime capabilities shared by browser, server, and CLI instances. */
30
31
  export type AndcoClientOptions = AndcoConfigInput & {
31
32
  /** Confidential credential. Its presence is what makes this a confidential OAuth client. */
32
33
  clientSecret?: string | null;
34
+ /** Overrides runtime fetch and randomness; omitted capabilities use platform defaults. */
33
35
  globals?: Partial<AndcoGlobals>;
34
36
  /** Authorization Transport Policy. Defaults to `auto`. */
35
37
  transport?: AndcoTransportMode;
@@ -37,14 +39,66 @@ export type AndcoClientOptions = AndcoConfigInput & {
37
39
  presenter?: AndcoPresenter;
38
40
  /** Persists a transaction so it survives a full-page redirect. */
39
41
  persistTransaction?: (request: AndcoAuthorizationRequest) => void | Promise<void>;
42
+ /** Session persistence adapter. Defaults to memory unless a runtime factory supplies one. */
40
43
  storage?: AndcoStorage;
41
44
  /** A session the caller already resolved, so the first snapshot is real rather than unresolved. */
42
45
  initialSession?: AndcoSession | null;
43
- lock?: AndcoLock;
46
+ /** Shares one refresh among concurrent callers. Defaults to sharing within this runtime. */
47
+ inflight?: AndcoInflight;
44
48
  /** Consulted once during the load, before storage. This is where a URL callback enters. */
45
49
  source?: AndcoSessionSource;
50
+ /** Writes session changes to storage unless `false`; defaults to `true`. */
46
51
  persist?: boolean;
47
52
  };
53
+ /**
54
+ * The eight collaborator fields shared, verbatim, by {@link AndcoClient} and both of the authorized
55
+ * views behind `with(...)` and `authorized()`. Declaring them once here is what keeps adding a field
56
+ * to the instance from requiring three synchronized edits.
57
+ *
58
+ * This is a construction seam, not a claim that the three are interchangeable: each subclass still
59
+ * decides for itself — per the ADR-0023 invariants documented at `AndcoAuthedClientImpl` and
60
+ * `AndcoAuthorizedViewImpl` — whether a given field's value is freshly built or borrowed by reference
61
+ * from an owner. The base constructor only stores whatever it is handed.
62
+ */
63
+ declare class AndcoClientFields {
64
+ readonly config: AndcoConfig;
65
+ readonly clientSecret: string | null;
66
+ readonly globals: AndcoGlobals;
67
+ readonly oauth: AndcoOAuth;
68
+ readonly rest: AndcoRest;
69
+ readonly intents: AndcoIntents;
70
+ readonly auth: AndcoAuth;
71
+ readonly session: AndcoSessionStore;
72
+ /** Offline verification of access tokens with the Authorization Server JWKS. */
73
+ readonly tokens: AndcoTokens;
74
+ /** Live Grant lookup for a token. */
75
+ readonly grants: AndcoGrants;
76
+ protected constructor(fields: {
77
+ config: AndcoConfig;
78
+ clientSecret: string | null;
79
+ globals: AndcoGlobals;
80
+ oauth: AndcoOAuth;
81
+ rest: AndcoRest;
82
+ intents: AndcoIntents;
83
+ auth: AndcoAuth;
84
+ session: AndcoSessionStore;
85
+ tokens: AndcoTokens;
86
+ grants: AndcoGrants;
87
+ });
88
+ /**
89
+ * Acts as the Resource Server identified by `resource`: verifies tokens and protects routes.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const orders = andco.resource({ resource: "https://casa-norte.example/api" });
94
+ * app.use("/api/orders/*", orders.protect({ scopes: ["orders:read"] }).hono());
95
+ * ```
96
+ */
97
+ resource(options: {
98
+ resource: string;
99
+ resourceMetadata?: string;
100
+ }): AndcoResource;
101
+ }
48
102
  /**
49
103
  * An Andco Instance without resolved credentials.
50
104
  *
@@ -65,15 +119,7 @@ export type AndcoClientOptions = AndcoConfigInput & {
65
119
  * const bound = andco.with(await sessionFromCookie());
66
120
  * ```
67
121
  */
68
- export declare class AndcoClient {
69
- readonly config: AndcoConfig;
70
- readonly clientSecret: string | null;
71
- readonly globals: AndcoGlobals;
72
- readonly oauth: AndcoOAuth;
73
- readonly rest: AndcoRest;
74
- readonly intents: AndcoIntents;
75
- readonly auth: AndcoAuth;
76
- readonly session: AndcoSessionStore;
122
+ export declare class AndcoClient extends AndcoClientFields {
77
123
  /** Runtime discriminant: `false` here, `true` on the value `with(...)` returns. */
78
124
  readonly isAuthed: false;
79
125
  constructor(options: AndcoClientOptions);
@@ -132,4 +178,5 @@ export declare class AndcoClient {
132
178
  export type AndcoClientAuthed = Omit<AndcoClient, "isAuthed" | "with" | "authorized"> & AndcoCredentials & {
133
179
  readonly isAuthed: true;
134
180
  };
181
+ export {};
135
182
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -2,10 +2,63 @@ import { AndcoAuth } from "./auth.js";
2
2
  import { AndcoConfig as Config } from "./config.js";
3
3
  import { credentialsFromSession, isCredentials } from "./credentials.js";
4
4
  import { Result } from "./errors.js";
5
+ import { resolveGlobals } from "./globals.js";
6
+ import { AndcoGrants } from "./grants-api.js";
5
7
  import { AndcoIntents } from "./intents.js";
6
8
  import { AndcoOAuth } from "./oauth.js";
9
+ import { AndcoPresenter } from "./presenter.js";
10
+ import { AndcoResource } from "./resource.js";
7
11
  import { AndcoRest } from "./rest.js";
8
12
  import { AndcoSessionStore, browserRequired } from "./session-store.js";
13
+ import { AndcoTokens } from "./tokens.js";
14
+ /**
15
+ * The eight collaborator fields shared, verbatim, by {@link AndcoClient} and both of the authorized
16
+ * views behind `with(...)` and `authorized()`. Declaring them once here is what keeps adding a field
17
+ * to the instance from requiring three synchronized edits.
18
+ *
19
+ * This is a construction seam, not a claim that the three are interchangeable: each subclass still
20
+ * decides for itself — per the ADR-0023 invariants documented at `AndcoAuthedClientImpl` and
21
+ * `AndcoAuthorizedViewImpl` — whether a given field's value is freshly built or borrowed by reference
22
+ * from an owner. The base constructor only stores whatever it is handed.
23
+ */
24
+ class AndcoClientFields {
25
+ config;
26
+ clientSecret;
27
+ globals;
28
+ oauth;
29
+ rest;
30
+ intents;
31
+ auth;
32
+ session;
33
+ /** Offline verification of access tokens with the Authorization Server JWKS. */
34
+ tokens;
35
+ /** Live Grant lookup for a token. */
36
+ grants;
37
+ constructor(fields) {
38
+ this.config = fields.config;
39
+ this.clientSecret = fields.clientSecret;
40
+ this.globals = fields.globals;
41
+ this.oauth = fields.oauth;
42
+ this.rest = fields.rest;
43
+ this.intents = fields.intents;
44
+ this.auth = fields.auth;
45
+ this.session = fields.session;
46
+ this.tokens = fields.tokens;
47
+ this.grants = fields.grants;
48
+ }
49
+ /**
50
+ * Acts as the Resource Server identified by `resource`: verifies tokens and protects routes.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * const orders = andco.resource({ resource: "https://casa-norte.example/api" });
55
+ * app.use("/api/orders/*", orders.protect({ scopes: ["orders:read"] }).hono());
56
+ * ```
57
+ */
58
+ resource(options) {
59
+ return new AndcoResource({ ...options, tokens: this.tokens, grants: this.grants });
60
+ }
61
+ }
9
62
  /**
10
63
  * An Andco Instance without resolved credentials.
11
64
  *
@@ -26,60 +79,52 @@ import { AndcoSessionStore, browserRequired } from "./session-store.js";
26
79
  * const bound = andco.with(await sessionFromCookie());
27
80
  * ```
28
81
  */
29
- export class AndcoClient {
30
- config;
31
- clientSecret;
32
- globals;
33
- oauth;
34
- rest;
35
- intents;
36
- auth;
37
- session;
82
+ export class AndcoClient extends AndcoClientFields {
38
83
  /** Runtime discriminant: `false` here, `true` on the value `with(...)` returns. */
39
84
  isAuthed = false;
40
85
  constructor(options) {
41
- this.config = Config.from(options);
42
- this.clientSecret = options.clientSecret ?? null;
43
- this.globals = {
44
- fetch: options.globals?.fetch ?? globalThis.fetch.bind(globalThis),
45
- crypto: options.globals?.crypto ?? globalThis.crypto,
46
- };
47
- this.oauth = new AndcoOAuth({
48
- config: this.config,
49
- fetch: this.globals.fetch,
50
- clientSecret: this.clientSecret,
86
+ const config = Config.from(options);
87
+ const clientSecret = options.clientSecret ?? null;
88
+ const globals = resolveGlobals(options.globals);
89
+ const oauth = new AndcoOAuth({
90
+ config,
91
+ globals,
92
+ clientSecret,
51
93
  transport: options.transport,
52
94
  });
53
95
  // The store is real even without a presenter: it is what lets `rest` stay one object across a
54
96
  // sign-in, and what gives `auth` something to operate on regardless of runtime.
55
- this.session = new AndcoSessionStore({
56
- config: this.config,
57
- oauth: this.oauth,
97
+ const session = new AndcoSessionStore({
98
+ config,
99
+ oauth,
58
100
  storage: options.storage,
59
101
  initialSession: options.initialSession,
60
- lock: options.lock,
102
+ inflight: options.inflight,
61
103
  source: options.source,
62
104
  persist: options.persist,
63
105
  });
64
106
  // One presenter for the whole instance: authorization and Intent are the same seam, so a
65
107
  // runtime that can present one can present the other. Not public — nothing outside the
66
108
  // instance chooses how it presents, and every mirror of this type would have to carry it.
67
- const presenter = options.presenter ?? statelessPresenter();
68
- this.auth = new AndcoAuth({
69
- config: this.config,
70
- oauth: this.oauth,
71
- store: this.session,
109
+ const presenter = options.presenter ?? new AndcoPresenterStateless();
110
+ const auth = new AndcoAuth({
111
+ config,
112
+ oauth,
113
+ store: session,
72
114
  presenter,
73
115
  persistTransaction: options.persistTransaction,
74
- crypto: this.globals.crypto,
116
+ globals,
75
117
  });
76
- this.rest = new AndcoRest({ config: this.config, fetch: this.globals.fetch, credentials: this.session });
77
- this.intents = new AndcoIntents({
78
- rest: this.rest,
79
- config: this.config,
118
+ const rest = new AndcoRest({ config, globals, credentials: session });
119
+ const intents = new AndcoIntents({
120
+ rest,
121
+ config,
80
122
  presenter,
81
- crypto: this.globals.crypto,
123
+ globals,
82
124
  });
125
+ const tokens = new AndcoTokens({ config, globals });
126
+ const grants = new AndcoGrants({ config, globals });
127
+ super({ config, clientSecret, globals, oauth, rest, intents, auth, session, tokens, grants });
83
128
  }
84
129
  /**
85
130
  * Binds *explicit* credentials for one unit of work, owning its own REST surface.
@@ -141,47 +186,45 @@ export class AndcoClient {
141
186
  }
142
187
  }
143
188
  /** Presents nothing; every authorization attempt fails clearly instead of doing nothing silently. */
144
- function statelessPresenter() {
145
- return {
146
- async present() {
147
- return Result.fail(browserRequired());
148
- },
149
- };
189
+ class AndcoPresenterStateless extends AndcoPresenter {
190
+ async present() {
191
+ return Result.fail(browserRequired());
192
+ }
150
193
  }
151
194
  /**
152
195
  * The implementation behind `with(...)`. Not exported: `AndcoClientAuthed` is the entire public
153
196
  * contract, so a caller never has a reason to name this type.
154
197
  */
155
- class AndcoAuthedClientImpl {
198
+ class AndcoAuthedClientImpl extends AndcoClientFields {
156
199
  credentials;
157
200
  isAuthed = true;
158
- config;
159
- clientSecret;
160
- globals;
161
- oauth;
162
- rest;
163
- intents;
164
- auth;
165
- session;
166
201
  constructor(owner, credentials) {
167
- this.credentials = credentials;
168
- this.config = owner.config;
169
- this.clientSecret = owner.clientSecret;
170
- this.globals = owner.globals;
171
- this.oauth = owner.oauth;
172
- this.rest = new AndcoRest({ config: owner.config, fetch: owner.globals.fetch, credentials });
202
+ const rest = new AndcoRest({ config: owner.config, globals: owner.globals, credentials });
173
203
  // No presenter: `with(...)` is the per-request server shape, and a request presents nothing.
174
- this.intents = new AndcoIntents({ rest: this.rest, config: owner.config, crypto: owner.globals.crypto });
204
+ const intents = new AndcoIntents({ rest, config: owner.config, globals: owner.globals });
175
205
  // In-memory and unlinked from `credentials`: it exists only so `auth` has something to operate
176
206
  // on, since a bare token or a caller-supplied resolver carries no persistable session shape.
177
- this.session = new AndcoSessionStore({ config: owner.config, oauth: owner.oauth, persist: false });
178
- this.auth = new AndcoAuth({
207
+ const session = new AndcoSessionStore({ config: owner.config, oauth: owner.oauth, persist: false });
208
+ const auth = new AndcoAuth({
209
+ config: owner.config,
210
+ oauth: owner.oauth,
211
+ store: session,
212
+ presenter: new AndcoPresenterStateless(),
213
+ globals: owner.globals,
214
+ });
215
+ super({
179
216
  config: owner.config,
217
+ clientSecret: owner.clientSecret,
218
+ globals: owner.globals,
180
219
  oauth: owner.oauth,
181
- store: this.session,
182
- presenter: statelessPresenter(),
183
- crypto: owner.globals.crypto,
220
+ rest,
221
+ intents,
222
+ auth,
223
+ session,
224
+ tokens: owner.tokens,
225
+ grants: owner.grants,
184
226
  });
227
+ this.credentials = credentials;
185
228
  }
186
229
  accessTokenFor(resource) {
187
230
  return this.credentials.accessTokenFor(resource);
@@ -193,27 +236,23 @@ class AndcoAuthedClientImpl {
193
236
  * unchanged across a sign-in, satisfying "one REST surface per instance" even where a framework
194
237
  * adapter hands out a fresh `AndcoClientAuthed` reference on every Authorized Identity change.
195
238
  */
196
- class AndcoAuthorizedViewImpl {
239
+ class AndcoAuthorizedViewImpl extends AndcoClientFields {
197
240
  owner;
198
241
  isAuthed = true;
199
- config;
200
- clientSecret;
201
- globals;
202
- oauth;
203
- rest;
204
- intents;
205
- auth;
206
- session;
207
242
  constructor(owner) {
243
+ super({
244
+ config: owner.config,
245
+ clientSecret: owner.clientSecret,
246
+ globals: owner.globals,
247
+ oauth: owner.oauth,
248
+ rest: owner.rest,
249
+ intents: owner.intents,
250
+ auth: owner.auth,
251
+ session: owner.session,
252
+ tokens: owner.tokens,
253
+ grants: owner.grants,
254
+ });
208
255
  this.owner = owner;
209
- this.config = owner.config;
210
- this.clientSecret = owner.clientSecret;
211
- this.globals = owner.globals;
212
- this.oauth = owner.oauth;
213
- this.rest = owner.rest;
214
- this.intents = owner.intents;
215
- this.auth = owner.auth;
216
- this.session = owner.session;
217
256
  }
218
257
  /** Delegates to the instance's own session store on every call, so a rotated token is still picked up. */
219
258
  accessTokenFor(resource) {
package/dist/config.d.ts CHANGED
@@ -5,7 +5,7 @@ export type AndcoTheme = "base";
5
5
  * An OAuth scope. Known Andco scopes are suggested; a Resource Server may define its own.
6
6
  *
7
7
  * The Protocol Contract already knows the scope vocabulary, so this is that type rather than a bare
8
- * `string`: an editor completes `bank_accounts:read` without closing the door on a scope Andco has
8
+ * `string`: an editor completes `offline_access` without closing the door on a scope Andco has
9
9
  * not shipped yet.
10
10
  */
11
11
  export type AndcoScope = AndCoScope;
@@ -75,6 +75,7 @@ export declare class AndcoConfig {
75
75
  widgetURL(release: number, surface?: "button"): URL;
76
76
  /** Whether an origin may participate in popup messaging for this instance. */
77
77
  allowsPopupOrigin(origin: string): boolean;
78
+ /** Serializes configuration to constructor input without credentials or runtime collaborators. */
78
79
  toJSON(): AndcoConfigInput;
79
80
  }
80
81
  /** Loopback over plain HTTP is accepted so local development and CLI callbacks work unmodified. */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAGzB,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAChC;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC;AAEpC,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC3B,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC9B,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,CAAC;AAMF;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,SAAS,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAC1E,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,UAAU,EAAE,GAAG,GAAG,SAAS,CAAC;IAC5C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,KAAK,EAAE,UAAU,CAAC;IAClC,SAAgB,SAAS,EAAE,cAAc,CAAC;IAC1C,SAAgB,aAAa,EAAE,SAAS,UAAU,EAAE,CAAC;IACrD,SAAgB,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzD,OAAO;IAkCP,mGAAmG;WACrF,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW;IAIxD,mDAAmD;IAC5C,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,WAAW;IAI9D;;;OAGG;IACI,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;IAOjC,oDAAoD;IAC7C,MAAM,IAAI,GAAG;IAIpB,qEAAqE;IAC9D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,QAAmB,GAAG,GAAG;IAIpE,8EAA8E;IACvE,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI1C,MAAM,IAAI,gBAAgB;CAelC;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAQ5C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAGzB,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAChC;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC;AAEpC,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC3B,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC9B,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,CAAC;AAMF;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,SAAS,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAC1E,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,UAAU,EAAE,GAAG,GAAG,SAAS,CAAC;IAC5C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,KAAK,EAAE,UAAU,CAAC;IAClC,SAAgB,SAAS,EAAE,cAAc,CAAC;IAC1C,SAAgB,aAAa,EAAE,SAAS,UAAU,EAAE,CAAC;IACrD,SAAgB,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzD,OAAO;IAkCP,mGAAmG;WACrF,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW;IAIxD,mDAAmD;IAC5C,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,WAAW;IAI9D;;;OAGG;IACI,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;IAOjC,oDAAoD;IAC7C,MAAM,IAAI,GAAG;IAIpB,qEAAqE;IAC9D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,QAAmB,GAAG,GAAG;IAIpE,8EAA8E;IACvE,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIjD,kGAAkG;IAC3F,MAAM,IAAI,gBAAgB;CAelC;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAQ5C"}
package/dist/config.js CHANGED
@@ -83,6 +83,7 @@ export class AndcoConfig {
83
83
  allowsPopupOrigin(origin) {
84
84
  return this.allowedPopupOrigins.has(origin);
85
85
  }
86
+ /** Serializes configuration to constructor input without credentials or runtime collaborators. */
86
87
  toJSON() {
87
88
  return {
88
89
  clientId: this.clientId,
@@ -1,9 +1,37 @@
1
+ import type { AndcoConfig } from "./config.js";
2
+ import type { GrantReference } from "./grants.js";
1
3
  /** The authenticated subject of a session, as far as the SDK is concerned. */
2
4
  export type AndcoUser = {
3
5
  id: string;
4
6
  name: string | null;
5
7
  email: string | null;
6
8
  avatarUrl: string | null;
9
+ /**
10
+ * Whether the Authorization Server has verified the email address.
11
+ *
12
+ * `true` and `false` are both affirmative claims the server made; `null` means the server said
13
+ * nothing about it. Absence must never be treated as verified, which is why this is required
14
+ * rather than optional: every constructor of an `AndcoUser` must say what it knows, instead of
15
+ * silently forgetting to say anything.
16
+ */
17
+ emailVerified: boolean | null;
18
+ /**
19
+ * The Profile's phone number, as UserInfo's `phone` claim carries it. `null` unless the `phone`
20
+ * scope was granted and the Profile has a number on file.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * await andco.auth.signIn({ scopes: ["openid", "phone"] });
25
+ * andco.session.getSnapshot()?.user.phone; // "+56999999999"
26
+ * ```
27
+ */
28
+ phone: string | null;
29
+ /**
30
+ * `true` when the Authorization Server confirmed the phone number; `null` when it said nothing,
31
+ * which includes a number not yet confirmed and a session without the `phone` scope. Like
32
+ * `emailVerified`, absence never means verified.
33
+ */
34
+ phoneVerified: boolean | null;
7
35
  };
8
36
  /**
9
37
  * One set of credentials issued by Andco.
@@ -23,12 +51,23 @@ export type AndcoSession = {
23
51
  /** Access tokens keyed by exact Resource Indicator URI. Absent means `accessToken` serves all. */
24
52
  resourceAccessTokens?: Readonly<Record<string, string>>;
25
53
  };
54
+ /**
55
+ * Per-request authorization controls a transport hands to the credentials.
56
+ *
57
+ * Only an explicit `grant` exists: the Authorization Server selects the Grant from the client,
58
+ * the subject and the resource, so the SDK never inspects request paths or bodies to guess it.
59
+ */
60
+ export type AndcoCredentialRequest = {
61
+ /** Exact Grant to use for this request instead of the server's selection. */
62
+ readonly grant?: GrantReference;
63
+ };
26
64
  /**
27
65
  * The entire contract the Andco core knows about authorization.
28
66
  *
29
- * Keeping it to one resource-keyed method is what lets an application go on owning its sessions:
67
+ * Keeping one required resource-keyed method lets an application go on owning its sessions:
30
68
  * a Better Auth account, a Passport session, a row in your own table, or a plain closure all
31
- * satisfy it without adopting the SDK's persistence.
69
+ * satisfy it without adopting the SDK's persistence. Service credentials also receive the explicit
70
+ * `grant` control and may provide request-local authority through `forOperation()`.
32
71
  *
33
72
  * @example
34
73
  * ```ts
@@ -38,8 +77,23 @@ export type AndcoSession = {
38
77
  * ```
39
78
  */
40
79
  export interface AndcoCredentials {
41
- /** Resolves a token for one Resource Indicator, refreshing lazily when the current one is stale. */
42
- accessTokenFor(resource: string): Promise<string | null>;
80
+ /** Resolves a token for one audience, refreshing or reauthenticating lazily. */
81
+ accessTokenFor(resource: string, request?: AndcoCredentialRequest): Promise<string | null>;
82
+ /** Isolates and pins one operation's authority across pages, polling and retries. */
83
+ forOperation?(): AndcoCredentials;
84
+ /**
85
+ * The configuration of the client that issued these credentials, when there is one.
86
+ *
87
+ * `andco.with()`, `andco.authorized()` and `service.credentials()` carry it, so a Resource Server
88
+ * Definition bound to them reads the OAuth `client_id` and API endpoint from here instead of
89
+ * asking for them a second time. A hand-written resolver may omit it.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const bank = new Bank(andco.with(accessToken)); // clientId and endpoint come from andco.config
94
+ * ```
95
+ */
96
+ readonly config?: AndcoConfig;
43
97
  }
44
98
  /** Seconds of remaining lifetime under which a token is treated as stale and refreshed. */
45
99
  export declare const ANDCO_REFRESH_SKEW_SECONDS = 30;
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,kGAAkG;IAClG,oBAAoB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oGAAoG;IACpG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,SAAgC,GAAG,OAAO,CAEpG;AAED,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAE9E;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,GAAG,KAAK,IAAI,gBAAgB,CAE/F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAMnF"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;;;OAOG;IACH,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,kGAAkG;IAClG,oBAAoB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3F,qFAAqF;IACrF,YAAY,CAAC,IAAI,gBAAgB,CAAC;IAClC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,SAAgC,GAAG,OAAO,CAEpG;AAED,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAE9E;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,GAAG,KAAK,IAAI,gBAAgB,CAE/F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWnF"}
Binary file
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type AndcoErrorCode } from "@andco/protocol";
1
2
  /**
2
3
  * The single error type every Andco operation reports.
3
4
  *
@@ -34,7 +35,7 @@ export declare class AndcoError extends Error {
34
35
  details?: Readonly<Record<string, unknown>>;
35
36
  });
36
37
  /** Normalizes anything thrown by a dependency into an `AndcoError`. */
37
- static from(cause: unknown, fallbackCode: string): AndcoError;
38
+ static from(cause: unknown, fallbackCode: SdkErrorCode): AndcoError;
38
39
  /** Whether a value is an `AndcoError`. */
39
40
  static is(cause: unknown): cause is AndcoError;
40
41
  }
@@ -137,29 +138,30 @@ export declare const Result: {
137
138
  /** Wraps a value as a successful result. */
138
139
  ok<T>(data: T): Result<T>;
139
140
  /** Wraps a failure as a result, accepting either a code or an existing error. */
140
- fail<T = never>(error: AndcoError | string, options?: {
141
+ fail<T = never>(error: AndcoError | SdkErrorCode, options?: {
141
142
  message?: string;
142
143
  status?: number;
143
144
  cause?: unknown;
144
145
  }): Result<T>;
145
146
  };
146
- /** Error codes the SDK itself raises, as opposed to those relayed from the Authorization Server. */
147
- export declare const ANDCO_ERROR_CODES: {
148
- readonly BROWSER_REQUIRED: "browser_required";
149
- readonly BROWSER_UNAVAILABLE: "browser_unavailable";
150
- readonly BROWSER_FORBIDDEN: "browser_forbidden";
151
- readonly INVALID_CALLBACK: "invalid_callback";
152
- readonly INVALID_CONFIGURATION: "invalid_configuration";
153
- readonly HANDSHAKE_TIMEOUT: "handshake_timeout";
154
- readonly INVALID_IFRAME: "invalid_iframe";
155
- readonly INVALID_INTENT_ID: "invalid_intent_id";
156
- readonly INVALID_RESPONSE: "invalid_response";
157
- readonly POPUP_BLOCKED: "popup_blocked";
158
- readonly POPUP_TIMEOUT: "popup_timeout";
159
- readonly PRESENTATION_UNSUPPORTED: "presentation_unsupported";
160
- readonly SAME_ORIGIN_ENDPOINT: "same_origin_endpoint";
161
- readonly SESSION_MISSING: "session_missing";
162
- readonly STORAGE_FAILED: "storage_failed";
163
- readonly UNTRUSTED_ORIGIN: "untrusted_origin";
164
- };
147
+ /**
148
+ * Re-exported so `@andco/sdk` consumers reach the one vocabulary without importing `@andco/protocol`
149
+ * directly. It used to be a second catalogue declared here, with the same public name as the one in
150
+ * protocol and different values for the eight conditions both named -- a comparison against the
151
+ * wrong import never matched, and nothing said which was which.
152
+ */
153
+ export { ANDCO_ERROR_CODES, type AndcoErrorCode } from "@andco/protocol";
154
+ /**
155
+ * The vocabulary of codes the SDK may write to `AndcoError.code` on its own initiative — every
156
+ * member of {@link ANDCO_ERROR_CODES}, derived rather than duplicated.
157
+ *
158
+ * This closes the entry points the SDK alone uses to raise its own errors — `AndcoError.from`'s
159
+ * `fallbackCode` and `Result.fail`'s string shorthand — so a typo or an ad hoc string can no longer
160
+ * slip in unnoticed. It does not close `AndcoError.code` itself, nor the `AndcoError` constructor:
161
+ * both must keep accepting a plain `string`, because `AndcoError` is the one error type every Andco
162
+ * operation reports, including codes this repository does not own — the Authorization Server's own
163
+ * OAuth error identifiers (RFC 6749) foremost among them — and integrators are expected to construct
164
+ * one directly for their own domain errors, as `apps/example-oauth-nextjs` already does.
165
+ */
166
+ export type SdkErrorCode = AndcoErrorCode;
165
167
  //# sourceMappingURL=errors.d.ts.map