@ambasada/sdk 0.8.20 → 0.8.21

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
@@ -1,6 +1,6 @@
1
1
  # @ambasada/sdk
2
2
 
3
- The Ambasada platform client: Sign in with Ambasada, mini-app notifications, the project store, files. Node ≥ 22,
3
+ The ambasada platform client: Sign in with ambasada, mini-app notifications, the project store, files. Node ≥ 22,
4
4
  Bun, Cloudflare Workers, Next.js route handlers. No runtime dependencies.
5
5
 
6
6
  ```ts
@@ -9,8 +9,8 @@ import { ambasada } from "@ambasada/sdk"; // AMBASADA_API_KEY, AMBASADA_API_URL
9
9
 
10
10
  | | |
11
11
  |---|---|
12
- | `ambasada.auth.login(req)` / `.callback(req)` / `.user(req)` / `.logout(req)` / `.shell(req)` | Sign in with Ambasada (below) |
13
- | `ambasada.apps.verifyWebhook(req)` / `.notify({ … })` | the Ambasada app's events and push notifications (docs/MINI-APPS.md §7) |
12
+ | `ambasada.auth.login(req)` / `.callback(req)` / `.user(req)` / `.logout(req)` / `.shell(req)` | Sign in with ambasada (below) |
13
+ | `ambasada.apps.verifyWebhook(req)` / `.notify({ … })` | the ambasada app's events and push notifications (docs/MINI-APPS.md §7) |
14
14
  | `ambasada.store.get(key)` / `.put(key, value)` / `.delete(key)` / `.list(prefix)` | JSON key-value, 1 MB per app |
15
15
  | `ambasada.files.put(data)` | a file at a public URL |
16
16
  | `ambasada.project()`, `ambasada.keys()` | the app's id; the API's signing keys |
@@ -25,16 +25,16 @@ The Hack A Ton economy (TON, checkout, offerings, the agent) is the add-on
25
25
  `VillageError`, `offering`, `defineCompany`, …) are still exported here, `@deprecated`, until 2.0. Note that
26
26
  `createAmbasada` returns the platform client from 0.8; selling code uses `createVillage`.
27
27
 
28
- ## Sign in with Ambasada
28
+ ## Sign in with ambasada
29
29
 
30
- People sign in to your product with their Ambasada ID (OAuth 2.0 code flow + PKCE, consent screen). Zero
30
+ People sign in to your product with their ambasada ID (OAuth 2.0 code flow + PKCE, consent screen). Zero
31
31
  setup on `https://<slug>.ambasada.dev`: `ambasada deploy` injects `AMBASADA_AUTH_CLIENT_ID`,
32
32
  `AMBASADA_AUTH_CLIENT_SECRET` and `AMBASADA_AUTH_ISSUER`; `ambasada dev` injects fake ones and its mock signs you in
33
33
  as "Fake Visitor". Fetch-style handlers for Workers and Next.js route handlers, WebCrypto only.
34
34
 
35
35
  ```ts
36
36
  const ambasada = createAmbasada({ env });
37
- // GET /api/auth/login?returnTo=/path → redirect to the Ambasada ID consent screen
37
+ // GET /api/auth/login?returnTo=/path → redirect to the ambasada ID consent screen
38
38
  return ambasada.auth.login(req, { returnTo: "/", email: true }); // email: also ask for their email
39
39
  // GET /api/auth/callback → checks state, exchanges the code, reads the profile, sets the cookie
40
40
  return ambasada.auth.callback(req);
@@ -45,7 +45,7 @@ return ambasada.auth.logout(req, { returnTo: "/" });
45
45
  ```
46
46
 
47
47
  `AmbasadaUser` is `{ id, name, avatar_url, builder, builder_since, member_since, pass, email? }`: `id` is the
48
- stable Ambasada ID (`user_…`), `pass` is `"builder" | "visitor" | "staff" | null` for the current event, `email`
48
+ stable ambasada ID (`user_…`), `pass` is `"builder" | "visitor" | "staff" | null` for the current event, `email`
49
49
  only if you asked and they agreed. The session is an HttpOnly `SameSite=Lax` cookie (`__Host-ambasada_session`
50
50
  on https) holding the signed profile (HMAC-SHA256, key derived from the client secret), valid 7 days; no token is
51
51
  kept. `returnTo` must be a path on your site. `user()` also takes `{ headers }` (Next server components:
@@ -55,4 +55,4 @@ origin of the callback URL when the Worker sees another host. More: docs/AUTH.md
55
55
 
56
56
  `pnpm build` writes `dist/` (one ESM file + `.d.ts`); `publishConfig` points the published package at it.
57
57
 
58
- Built by [CENTYSO](https://centyso.com) for [Ambasada](https://ambasada.id). MIT.
58
+ Built by [CENTYSO](https://centyso.com) for [ambasada](https://ambasada.id). MIT.
package/dist/apps.d.ts CHANGED
@@ -56,7 +56,7 @@ export interface AppNotifyInput {
56
56
  url: string;
57
57
  /** Notification tokens from `notifications_enabled`, ≤ 100 per call. */
58
58
  tokens?: string[];
59
- /** Ambasada user ids, for Verified apps with the identity scope. */
59
+ /** ambasada user ids, for Verified apps with the identity scope. */
60
60
  users?: string[];
61
61
  /** Default "transactional", the only one Listed apps may send. */
62
62
  category?: NotificationCategory;
package/dist/auth.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * "Sign in with Ambasada" (docs/AUTH.md): OAuth 2.0 authorization code + PKCE against Ambasada ID,
2
+ * "Sign in with ambasada" (docs/AUTH.md): OAuth 2.0 authorization code + PKCE against ambasada ID,
3
3
  * for products hosted at https://<slug>.ambasada.dev. The deploy injects AMBASADA_AUTH_CLIENT_ID,
4
4
  * AMBASADA_AUTH_CLIENT_SECRET and AMBASADA_AUTH_ISSUER; `ambasada dev` injects fake ones that point at
5
5
  * the mock. Four fetch handlers, WebCrypto only, no dependencies:
@@ -13,7 +13,7 @@
13
13
  * derived from the client secret), host-only (`__Host-` on https), so no other *.ambasada.dev product
14
14
  * can read, set or forge it. No access token is kept.
15
15
  *
16
- * Silent sign-in inside the Ambasada app (docs/MINI-APPS.md §5): the page asks the shell for a short-lived
16
+ * Silent sign-in inside the ambasada app (docs/MINI-APPS.md §5): the page asks the shell for a short-lived
17
17
  * token (`auth.getToken()` from @ambasada/miniapp) and POSTs it here; the same session cookie comes back:
18
18
  *
19
19
  * POST /api/auth/shell { token } → return ambasada.auth.shell(req) // { user } + cookie
@@ -21,11 +21,11 @@
21
21
  */
22
22
  /** The person signed in, as `GET /v1/auth/profile` returns them. */
23
23
  export interface AmbasadaUser {
24
- /** Ambasada ID user id (`user_…`): stable, use it as your user key. */
24
+ /** ambasada ID user id (`user_…`): stable, use it as your user key. */
25
25
  id: string;
26
26
  name: string | null;
27
27
  avatar_url: string | null;
28
- /** Has the builder flag on their Ambasada ID. */
28
+ /** Has the builder flag on their ambasada ID. */
29
29
  builder: boolean;
30
30
  builder_since: string | null;
31
31
  member_since: string | null;
@@ -42,7 +42,7 @@ export interface AuthConfig {
42
42
  audiences?: string[];
43
43
  /** The hub (default https://hub.ambasada.id): signs shell tokens, and has the full profile behind one (`/api/apps/profile`). */
44
44
  hubUrl?: string;
45
- /** Where `/v1/auth/profile` lives (the Ambasada API). */
45
+ /** Where `/v1/auth/profile` lives (the ambasada API). */
46
46
  apiUrl: string;
47
47
  /** Your public origin if the Worker sees another host (behind a proxy). Default: the request's origin. */
48
48
  publicUrl?: string;
@@ -83,7 +83,7 @@ export declare function readCookie(req: WithHeaders, name: string): string | nul
83
83
  * any control character (browsers drop tabs and newlines, so "/\t/evil" would become "//evil").
84
84
  */
85
85
  export declare function safeReturnTo(value: string | null | undefined): string;
86
- /** Who a verified shell token is for. Name and avatar are what Ambasada ID had when the shell minted it. */
86
+ /** Who a verified shell token is for. Name and avatar are what ambasada ID had when the shell minted it. */
87
87
  export interface ShellUser {
88
88
  user_id: string;
89
89
  name: string | null;
@@ -99,11 +99,11 @@ export declare class AmbasadaAuth {
99
99
  /** True when the product has credentials (hosted on ambasada.dev, or `ambasada dev`). */
100
100
  get configured(): boolean;
101
101
  private settings;
102
- /** Redirects to Ambasada ID (consent screen) with PKCE; a short-lived signed cookie holds the state. */
102
+ /** Redirects to ambasada ID (consent screen) with PKCE; a short-lived signed cookie holds the state. */
103
103
  login(req: Request, options?: LoginOptions): Promise<Response>;
104
104
  /**
105
- * Ambasada ID sends the person back here: checks the state, exchanges the code (with the PKCE
106
- * verifier and the client secret), reads their profile from the Ambasada API, sets the session cookie
105
+ * ambasada ID sends the person back here: checks the state, exchanges the code (with the PKCE
106
+ * verifier and the client secret), reads their profile from the ambasada API, sets the session cookie
107
107
  * and redirects to `returnTo`. A refused consent goes back to `returnTo` signed out.
108
108
  */
109
109
  callback(req: Request): Promise<Response>;
@@ -111,7 +111,7 @@ export declare class AmbasadaAuth {
111
111
  user(req: WithHeaders): Promise<AmbasadaUser | null>;
112
112
  /**
113
113
  * Verifies a shell token (RS256, 60 s) from the hub (`<AMBASADA_HUB_URL>/.well-known/jwks.json`, default
114
- * https://hub.ambasada.id) or Ambasada ID (`<AMBASADA_AUTH_ISSUER>/.well-known/jwks.json`, the Clerk JWT template
114
+ * https://hub.ambasada.id) or ambasada ID (`<AMBASADA_AUTH_ISSUER>/.well-known/jwks.json`, the Clerk JWT template
115
115
  * `ambasada-miniapp`), keys cached 1 h: signature, expiry, issuer, and that its `aud` is this app (its origin or
116
116
  * id). Returns who it is, or throws `AmbasadaError("UNAUTHORIZED")`; `NOT_CONFIGURED` (503) while the issuer
117
117
  * publishes no keys.
package/dist/client.d.ts CHANGED
@@ -20,7 +20,7 @@ export interface AmbasadaOptions {
20
20
  * an `AMBASADA_API` service binding there: the client calls the API through it (no zone in between, so no 522).
21
21
  */
22
22
  env?: Record<string, unknown>;
23
- /** Sign in with Ambasada credentials. Default: `AMBASADA_AUTH_CLIENT_ID`, `_CLIENT_SECRET`, `_ISSUER`, and `PUBLIC_URL`. */
23
+ /** Sign in with ambasada credentials. Default: `AMBASADA_AUTH_CLIENT_ID`, `_CLIENT_SECRET`, `_ISSUER`, and `PUBLIC_URL`. */
24
24
  auth?: {
25
25
  clientId?: string;
26
26
  clientSecret?: string;
@@ -54,7 +54,7 @@ export interface RawResponse {
54
54
  json: unknown;
55
55
  }
56
56
  /**
57
- * The Ambasada client. `import { ambasada } from "@ambasada/sdk"` gives one configured from the
57
+ * The ambasada client. `import { ambasada } from "@ambasada/sdk"` gives one configured from the
58
58
  * environment; `createAmbasada({ env })` makes another (e.g. from a Worker's `env`).
59
59
  */
60
60
  export declare class Ambasada {
@@ -71,7 +71,7 @@ export declare class Ambasada {
71
71
  get apiUrl(): string;
72
72
  protected get apiKey(): string;
73
73
  /**
74
- * Sign in with Ambasada (docs/AUTH.md): `login(req)`, `callback(req)`, `user(req)`, `logout(req)`.
74
+ * Sign in with ambasada (docs/AUTH.md): `login(req)`, `callback(req)`, `user(req)`, `logout(req)`.
75
75
  * Credentials come with the deploy to ambasada.dev, and from `ambasada dev` locally.
76
76
  */
77
77
  readonly auth: AmbasadaAuth;
package/dist/define.d.ts CHANGED
@@ -3,18 +3,18 @@
3
3
  * (`ambasada dev`, `deploy`, `link`, `check`). Add-ons add their own keys (the village: `idea`, `offerings`, `agent`).
4
4
  */
5
5
  /**
6
- * The app's Ambasada mini app (docs/MINI-APPS.md §15, decision 15.6): optional. With it, `ambasada dev` and `deploy`
6
+ * The app's ambasada mini app (docs/MINI-APPS.md §15, decision 15.6): optional. With it, `ambasada dev` and `deploy`
7
7
  * serve /.well-known/ambasada.json (from this and `id`, `name`, `description`), `ambasada check` runs the mini-app
8
- * rules on the entry, and the deploy registers the app with the Ambasada app. `ambasada miniapp enable` adds it.
8
+ * rules on the entry, and the deploy registers the app with the ambasada app. `ambasada miniapp enable` adds it.
9
9
  */
10
10
  export interface MiniAppConfig {
11
- /** The path the Ambasada app opens: "/app" (the in-app layout under it), or "/" for the whole site. */
11
+ /** The path the ambasada app opens: "/app" (the in-app layout under it), or "/" for the whole site. */
12
12
  entry: string;
13
13
  /** A 1024×1024 opaque PNG, a path on the app (default "/icon.png"). */
14
14
  icon?: string;
15
15
  /** Who it is for (default "4+"). The hub refuses to register a mini app without one; above 12+ it opens only for people old enough. */
16
16
  age_rating?: "4+" | "9+" | "12+" | "17+";
17
- /** How the Ambasada app shows it (default "tool"). */
17
+ /** How the ambasada app shows it (default "tool"). */
18
18
  kind?: "product" | "event" | "tool" | "assistant";
19
19
  /** Where people get help: "mailto:you@team.ro" or an https URL (default: the app's `support`). Needed to be Listed. */
20
20
  support?: string;
@@ -57,7 +57,7 @@ export interface AppConfig {
57
57
  product?: {
58
58
  url?: string;
59
59
  };
60
- /** The mini app inside the Ambasada app, at a path of this one. Off without it. */
60
+ /** The mini app inside the ambasada app, at a path of this one. Off without it. */
61
61
  miniapp?: MiniAppConfig;
62
62
  /** age_rating, kind and tags, for an app with or without a mini app (the mini app's own win). */
63
63
  listing?: ListingConfig;
package/dist/errors.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Typed errors. Every Ambasada API failure is `{ "error": { "code", "message", ... } }` with a code
2
+ * Typed errors. Every ambasada API failure is `{ "error": { "code", "message", ... } }` with a code
3
3
  * from `@ambasada/protocol` (packages/protocol/src/errors.ts); the SDK turns it into an `AmbasadaError`
4
4
  * with the same `code`, so you branch on `error.code` instead of parsing messages:
5
5
  *
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @ambasada/sdk: the Ambasada platform client. Sign-in, mini-app notifications, the project store, files.
2
+ * @ambasada/sdk: the ambasada platform client. Sign-in, mini-app notifications, the project store, files.
3
3
  *
4
4
  * import { ambasada } from "@ambasada/sdk"; // AMBASADA_API_KEY, AMBASADA_API_URL from the env
5
- * const user = await ambasada.auth.user(req); // Sign in with Ambasada (docs/AUTH.md)
5
+ * const user = await ambasada.auth.user(req); // Sign in with ambasada (docs/AUTH.md)
6
6
  * await ambasada.apps.notify({ notification_id, title, body, url, users }); // mini-app pushes (docs/MINI-APPS.md §7)
7
7
  * await ambasada.store.put("settings", { theme: "dark" });
8
8
  *
package/dist/platform.js CHANGED
@@ -435,7 +435,7 @@ var AmbasadaAuth = class {
435
435
  settings(req) {
436
436
  const c = this.config();
437
437
  if (!c.clientId || !c.clientSecret || !c.issuer) {
438
- throw new AmbasadaError("CONFIG", "Sign in with Ambasada is not set up: it works on https://<slug>.ambasada.dev after `ambasada deploy`, and locally under `ambasada dev` (AMBASADA_AUTH_CLIENT_ID / _SECRET / _ISSUER)");
438
+ throw new AmbasadaError("CONFIG", "Sign in with ambasada is not set up: it works on https://<slug>.ambasada.dev after `ambasada deploy`, and locally under `ambasada dev` (AMBASADA_AUTH_CLIENT_ID / _SECRET / _ISSUER)");
439
439
  }
440
440
  const origin = (c.publicUrl ? new URL(c.publicUrl) : new URL(req.url)).origin;
441
441
  return {
@@ -450,7 +450,7 @@ var AmbasadaAuth = class {
450
450
  fetch: c.fetch ?? ((input, init) => fetch(input, init))
451
451
  };
452
452
  }
453
- /** Redirects to Ambasada ID (consent screen) with PKCE; a short-lived signed cookie holds the state. */
453
+ /** Redirects to ambasada ID (consent screen) with PKCE; a short-lived signed cookie holds the state. */
454
454
  async login(req, options = {}) {
455
455
  const s = this.settings(req);
456
456
  const { verifier, challenge } = await pkce();
@@ -470,8 +470,8 @@ var AmbasadaAuth = class {
470
470
  return redirect(url.toString(), [setCookie(STATE_COOKIE, value, s.secure, STATE_TTL_S)]);
471
471
  }
472
472
  /**
473
- * Ambasada ID sends the person back here: checks the state, exchanges the code (with the PKCE
474
- * verifier and the client secret), reads their profile from the Ambasada API, sets the session cookie
473
+ * ambasada ID sends the person back here: checks the state, exchanges the code (with the PKCE
474
+ * verifier and the client secret), reads their profile from the ambasada API, sets the session cookie
475
475
  * and redirects to `returnTo`. A refused consent goes back to `returnTo` signed out.
476
476
  */
477
477
  async callback(req) {
@@ -496,9 +496,9 @@ var AmbasadaAuth = class {
496
496
  body: new URLSearchParams({ grant_type: "authorization_code", code, redirect_uri: s.redirectUri, code_verifier: saved.verifier })
497
497
  });
498
498
  const tokens = await token.json().catch(() => ({}));
499
- if (!token.ok || !tokens.access_token) throw new AmbasadaError("UNAUTHORIZED", `Ambasada ID refused the sign-in (${tokens.error ?? token.status})`, 401);
499
+ if (!token.ok || !tokens.access_token) throw new AmbasadaError("UNAUTHORIZED", `ambasada ID refused the sign-in (${tokens.error ?? token.status})`, 401);
500
500
  const res = await s.fetch(`${s.apiUrl}/v1/auth/profile`, { headers: { authorization: `Bearer ${tokens.access_token}`, accept: "application/json" } });
501
- if (!res.ok) throw new AmbasadaError("UPSTREAM_ERROR", `could not read the Ambasada profile (${res.status})`, 502);
501
+ if (!res.ok) throw new AmbasadaError("UPSTREAM_ERROR", `could not read the ambasada profile (${res.status})`, 502);
502
502
  const user = await res.json();
503
503
  const exp = Math.floor(Date.now() / 1e3) + SESSION_TTL_S;
504
504
  const session = await signCookie(s.clientSecret, "session", { user, exp });
@@ -512,7 +512,7 @@ var AmbasadaAuth = class {
512
512
  }
513
513
  /**
514
514
  * Verifies a shell token (RS256, 60 s) from the hub (`<AMBASADA_HUB_URL>/.well-known/jwks.json`, default
515
- * https://hub.ambasada.id) or Ambasada ID (`<AMBASADA_AUTH_ISSUER>/.well-known/jwks.json`, the Clerk JWT template
515
+ * https://hub.ambasada.id) or ambasada ID (`<AMBASADA_AUTH_ISSUER>/.well-known/jwks.json`, the Clerk JWT template
516
516
  * `ambasada-miniapp`), keys cached 1 h: signature, expiry, issuer, and that its `aud` is this app (its origin or
517
517
  * id). Returns who it is, or throws `AmbasadaError("UNAUTHORIZED")`; `NOT_CONFIGURED` (503) while the issuer
518
518
  * publishes no keys.
@@ -564,7 +564,7 @@ var AmbasadaAuth = class {
564
564
  * Answers `{ user }`.
565
565
  */
566
566
  async shell(req) {
567
- if (!this.configured) throw notConfigured("this app has no Sign in with Ambasada credentials (AMBASADA_AUTH_*: on ambasada.dev after `ambasada deploy`, and under `ambasada dev`)");
567
+ if (!this.configured) throw notConfigured("this app has no Sign in with ambasada credentials (AMBASADA_AUTH_*: on ambasada.dev after `ambasada deploy`, and under `ambasada dev`)");
568
568
  const s = this.settings(req);
569
569
  if (req.method !== "POST") throw new AmbasadaError("INVALID_REQUEST", "POST the shell token as JSON { token }", 405);
570
570
  let token = /^Bearer\s+(.+)$/i.exec(req.headers.get("authorization") ?? "")?.[1]?.trim();
@@ -645,7 +645,7 @@ var Ambasada = class {
645
645
  return key;
646
646
  }
647
647
  /**
648
- * Sign in with Ambasada (docs/AUTH.md): `login(req)`, `callback(req)`, `user(req)`, `logout(req)`.
648
+ * Sign in with ambasada (docs/AUTH.md): `login(req)`, `callback(req)`, `user(req)`, `logout(req)`.
649
649
  * Credentials come with the deploy to ambasada.dev, and from `ambasada dev` locally.
650
650
  */
651
651
  auth = new AmbasadaAuth(() => ({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ambasada/sdk",
3
- "version": "0.8.20",
4
- "description": "The Ambasada platform SDK: Sign in with Ambasada, mini-app notifications, the project store, files.",
3
+ "version": "0.8.21",
4
+ "description": "The ambasada platform SDK: Sign in with ambasada, mini-app notifications, the project store, files.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
@@ -27,7 +27,7 @@
27
27
  "node": ">=22"
28
28
  },
29
29
  "dependencies": {
30
- "@ambasada/village": "^0.8.20"
30
+ "@ambasada/village": "^0.8.21"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.20.5",