@domino-sdk/relay 1.5.2 → 1.6.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.
Files changed (43) hide show
  1. package/dist/{activity-DeKJsRry.d.ts → activity-mPUN4v5Q.d.ts} +147 -116
  2. package/dist/authoring.d.ts +59 -47
  3. package/dist/authoring.js +3 -3
  4. package/dist/{automatic-outcomes-B1xrETxm.d.ts → automatic-outcomes-DmuqzQiH.d.ts} +224 -13
  5. package/dist/browser.d.ts +22 -10
  6. package/dist/browser.js +6 -6
  7. package/dist/{capability-error-DNMwKmlL.d.ts → capability-error-Bv996M-h.d.ts} +2 -0
  8. package/dist/{chunk-GQKYAQM6.js → chunk-23QJ7WH4.js} +1 -1
  9. package/dist/{chunk-XFMSUPNS.js → chunk-6ON4RMEN.js} +1 -1
  10. package/dist/{chunk-VFHHLN6A.js → chunk-6RBF3UDA.js} +49 -6
  11. package/dist/chunk-AXRMT33W.js +112 -0
  12. package/dist/{chunk-24AFCBZN.js → chunk-BFZHJA2B.js} +2 -2
  13. package/dist/{chunk-EYH5RDIE.js → chunk-C25TDFHN.js} +4 -2
  14. package/dist/{chunk-36HTX2BM.js → chunk-GMPPLZKH.js} +61 -4
  15. package/dist/{chunk-BGGKNIRP.js → chunk-JW4G3SY5.js} +1 -1
  16. package/dist/{chunk-JON5SESL.js → chunk-KGJSKGKI.js} +84 -6
  17. package/dist/{chunk-WJSSJ7AF.js → chunk-QGLHZ2E5.js} +24 -4
  18. package/dist/{chunk-DGWMLN35.js → chunk-ZOUEEK5L.js} +16 -5
  19. package/dist/{client-gqnRUHpC.d.ts → client-CQuTAjSs.d.ts} +88 -41
  20. package/dist/{groups-Ck-OxzjD.d.ts → groups-D08JtrZu.d.ts} +175 -3
  21. package/dist/{identity-integration-GxAHdKR2.d.ts → identity-integration-BPovus6e.d.ts} +1 -1
  22. package/dist/{images-Dv-P5VBw.d.ts → images-D7en0Awp.d.ts} +1 -1
  23. package/dist/index.d.ts +9 -9
  24. package/dist/index.js +5 -5
  25. package/dist/internal.d.ts +34 -27
  26. package/dist/internal.js +18 -24
  27. package/dist/{offers-Cy-e4o5x.d.ts → offers-BENZl5l5.d.ts} +3 -2
  28. package/dist/{outcomes-kVB-Juzs.d.ts → pages-CBa-_u_n.d.ts} +142 -99
  29. package/dist/{pages-BBYD21IE.d.ts → participant-activity-DkL3nY5a.d.ts} +1 -14
  30. package/dist/portal-proxy.js +48 -36
  31. package/dist/react/index.d.ts +25 -3949
  32. package/dist/react/index.js +8 -7
  33. package/dist/{request-error-DWduJCGV.d.ts → request-error-D_dUPLwo.d.ts} +5 -0
  34. package/dist/{schema-DfJzH2ci.d.ts → schema-BPdHSCAc.d.ts} +122 -37
  35. package/dist/schema.d.ts +10 -10
  36. package/dist/schema.js +48 -6
  37. package/dist/server/index.d.ts +9672 -66110
  38. package/dist/server/index.js +1009 -548
  39. package/dist/sign-in-options-FPKoZMfo.d.ts +202 -0
  40. package/dist/{submission-input-BZkm6ohU.d.ts → submission-input-BzIWutQi.d.ts} +2 -2
  41. package/package.json +1 -1
  42. package/dist/browser-D_3s8B5e.d.ts +0 -4154
  43. package/dist/chunk-GUP7YRR4.js +0 -42
@@ -1,36 +1,45 @@
1
1
  import {
2
- isActivityParticipantRoute,
3
- isContentParticipantRoute,
4
- isOfferParticipantRoute,
5
- isPointsParticipantRoute,
6
- isProfileParticipantRoute,
7
- isQuestOutcomeParticipantRoute,
8
- isRewardsParticipantRoute,
9
- isWalletParticipantRoute,
10
- isWalletSignInRoute
11
- } from "./chunk-GUP7YRR4.js";
2
+ isParticipantRoute
3
+ } from "./chunk-AXRMT33W.js";
12
4
  import {
13
5
  exchangeResultSchema
14
- } from "./chunk-XFMSUPNS.js";
15
- import "./chunk-JON5SESL.js";
6
+ } from "./chunk-6ON4RMEN.js";
7
+ import "./chunk-KGJSKGKI.js";
16
8
 
17
9
  // src/portal-proxy.ts
10
+ var statusCode = (status) => ({
11
+ 400: "invalid-request",
12
+ 401: "unauthenticated",
13
+ 403: "forbidden",
14
+ 404: "not-found",
15
+ 405: "method-not-allowed",
16
+ 409: "conflict",
17
+ 410: "gone",
18
+ 413: "payload-too-large",
19
+ 415: "unsupported-media-type",
20
+ 422: "validation-failed",
21
+ 429: "rate-limited",
22
+ 500: "internal-error",
23
+ 502: "upstream-failed",
24
+ 503: "unavailable",
25
+ 504: "upstream-timeout"
26
+ })[status] ?? (status >= 500 ? "internal-error" : "invalid-request");
18
27
  async function proxyParticipant(request, upstream) {
19
28
  const incoming = new URL(request.url);
20
29
  const path = incoming.pathname.slice("/relay".length);
21
- const allowed = incoming.pathname.startsWith("/relay/") && (/^\/v1\/auth\/(providers|accounts(?:\/disconnect)?|start|authorize|complete|session|logout|email\/start|email\/verify|callback\/[a-z][a-z0-9-]*)$/.test(
22
- path
23
- ) || /^\/v1\/me\/(progress|experience|attempts|evidence|collection-pass)$/.test(
24
- path
25
- ) || isWalletParticipantRoute(path) || isWalletSignInRoute(path) || path === "/v1/me" && request.method === "GET" || /^\/v1\/attempts\/[\w-]+\/retry$/.test(path) || /^\/v1\/referrals(?:\/(me|history))?$/.test(path) && request.method === "GET" || isContentParticipantRoute(path, request.method) || isQuestOutcomeParticipantRoute(path, request.method) || isProfileParticipantRoute(path, request.method) || isPointsParticipantRoute(path, request.method) || isRewardsParticipantRoute(path, request.method) || isActivityParticipantRoute(path, request.method) || isOfferParticipantRoute(path, request.method) || path === "/v1/reward-deliveries" && request.method === "GET" || path === "/v1/referrals/accept" && request.method === "POST" || request.method === "GET" && /^\/v1\/leaderboards(?:\/[\w-]+)?$/.test(path) || request.method === "GET" && (path === "/v1/point-ledgers" || path === "/v1/tiered-rewards"));
26
- if (!allowed || !["GET", "POST"].includes(request.method)) {
27
- return Response.json({ error: "Route not found" }, { status: 404 });
30
+ const allowed = incoming.pathname.startsWith("/relay/") && isParticipantRoute(path, request.method);
31
+ if (!allowed) {
32
+ return Response.json(
33
+ { error: "Route not found", code: "route-not-found" },
34
+ { status: 404 }
35
+ );
28
36
  }
29
37
  const target = new URL(upstream.baseUrl);
30
38
  if (target.protocol !== "https:" || target.username || target.password || target.pathname !== "/" || target.search || target.hash) {
31
39
  return Response.json(
32
40
  {
33
- error: "Participant API is not configured. Use the API origin, such as https://relay.domino.run, not a management URL."
41
+ error: "Participant API is not configured. Use the API origin, such as https://relay.domino.run, not a management URL.",
42
+ code: "not-configured"
34
43
  },
35
44
  { status: 503 }
36
45
  );
@@ -86,20 +95,23 @@ function createParticipantBackend(options) {
86
95
  const cookie = (token) => `domino_app_session=${token}; Path=/relay; HttpOnly; Secure; SameSite=Lax; Max-Age=${token ? 28800 : 0}`;
87
96
  return async (request) => {
88
97
  const url = new URL(request.url);
89
- const reject = (error, status) => Response.json(
90
- { error },
98
+ const reject = (error, status, code) => Response.json(
99
+ { error, code },
91
100
  { status, headers: { "Cache-Control": "no-store" } }
92
101
  );
93
102
  if (url.origin !== options.origin) {
94
- return reject("Unexpected application origin", 403);
103
+ return reject("Unexpected application origin", 403, "forbidden");
95
104
  }
96
105
  if (request.method !== "GET" && (request.headers.get("Origin") !== options.origin || request.headers.get("X-Relay-CSRF") !== "1")) {
97
- return reject("Untrusted browser request", 403);
106
+ return reject("Untrusted browser request", 403, "forbidden");
98
107
  }
99
108
  const identity = await options.authenticate(request);
100
109
  if (!identity) {
101
110
  return Response.json(
102
- url.pathname === "/relay/v1/auth/session" ? null : { error: "Sign in to the application" },
111
+ url.pathname === "/relay/v1/auth/session" ? null : {
112
+ error: "Sign in to the application",
113
+ code: "unauthenticated"
114
+ },
103
115
  {
104
116
  status: url.pathname === "/relay/v1/auth/session" ? 200 : 401,
105
117
  headers: { "Set-Cookie": cookie(""), "Cache-Control": "no-store" }
@@ -116,25 +128,25 @@ function createParticipantBackend(options) {
116
128
  },
117
129
  body: JSON.stringify({ subject: identity.subject, previousToken })
118
130
  });
119
- if (exchanged.status === 409) {
131
+ if (!exchanged.ok) {
120
132
  const body = await exchanged.json().catch(() => null);
133
+ const code = typeof body?.code === "string" ? body.code : statusCode(exchanged.status);
134
+ const retryAfter = exchanged.headers.get("Retry-After");
121
135
  return Response.json(
122
136
  {
123
- error: typeof body?.error === "string" ? body.error : "Domino refused this account. Ask an organizer.",
124
- ...typeof body?.code === "string" ? { code: body.code } : {}
137
+ error: exchanged.status === 409 && typeof body?.error === "string" ? body.error : exchanged.status === 409 ? "Domino refused this account. Ask an organizer." : "Domino identity exchange failed. Check the server integration key and its expiry in Console Settings.",
138
+ code
125
139
  },
126
140
  {
127
- status: 409,
128
- headers: { "Set-Cookie": cookie(""), "Cache-Control": "no-store" }
141
+ status: exchanged.status,
142
+ headers: {
143
+ "Set-Cookie": cookie(""),
144
+ "Cache-Control": "no-store",
145
+ ...retryAfter ? { "Retry-After": retryAfter } : {}
146
+ }
129
147
  }
130
148
  );
131
149
  }
132
- if (!exchanged.ok) {
133
- return reject(
134
- "Domino identity exchange failed. Check the server integration key and its expiry in Console Settings.",
135
- exchanged.status
136
- );
137
- }
138
150
  const { token } = exchangeResultSchema.parse(await exchanged.json());
139
151
  const response = await proxyParticipant(request, {
140
152
  baseUrl: options.baseUrl,