@foir/sdk 0.21.0 → 0.23.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 (62) hide show
  1. package/CHANGELOG.md +135 -1
  2. package/README.md +15 -15
  3. package/dist/app/client.d.ts +93 -86
  4. package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +14 -13
  5. package/dist/app/dispatch.d.ts +5 -5
  6. package/dist/app/errors.d.ts +17 -15
  7. package/dist/app/index.d.ts +4 -4
  8. package/dist/app/naming.d.ts +1 -1
  9. package/dist/app/ticket.d.ts +2 -2
  10. package/dist/app/vocabulary.generated.d.ts +2 -2
  11. package/dist/app-contract.js +3 -3
  12. package/dist/app.js +92 -90
  13. package/dist/auth/access.d.ts +19 -19
  14. package/dist/auth/auth.d.ts +251 -117
  15. package/dist/auth/grant-table.generated.d.ts +5 -4
  16. package/dist/auth/hosted.d.ts +38 -14
  17. package/dist/auth/index.d.ts +9 -9
  18. package/dist/auth/operations.d.ts +153 -33
  19. package/dist/auth/ops.d.ts +39 -21
  20. package/dist/auth/session-client.d.ts +3 -3
  21. package/dist/auth-session.js +3 -3
  22. package/dist/auth.js +400 -250
  23. package/dist/client.js +5 -8
  24. package/dist/codegen/preset.d.ts +1 -1
  25. package/dist/data/builtins.d.ts +26 -26
  26. package/dist/data/client.d.ts +3 -3
  27. package/dist/data/decimal.d.ts +1 -1
  28. package/dist/data/index.d.ts +1 -1
  29. package/dist/data/manifest.d.ts +1 -1
  30. package/dist/data/schema.d.ts +2 -2
  31. package/dist/data/transport.d.ts +14 -13
  32. package/dist/data/ws-transport.d.ts +1 -1
  33. package/dist/data.js +8 -11
  34. package/dist/graphql/content-client.d.ts +13 -13
  35. package/dist/index.js +1 -4
  36. package/dist/live/drift.d.ts +1 -1
  37. package/dist/media/screen-capture.d.ts +1 -1
  38. package/dist/next/index.d.ts +2 -2
  39. package/dist/next/session.d.ts +10 -10
  40. package/dist/next.js +78 -60
  41. package/dist/placement/index.d.ts +13 -13
  42. package/dist/placement.js +127 -116
  43. package/dist/push.js +62 -44
  44. package/dist/react/FoirFeedback.d.ts +2 -2
  45. package/dist/react/FoirProvider.d.ts +24 -24
  46. package/dist/react/SignIn.d.ts +4 -4
  47. package/dist/react/UserButton.d.ts +1 -1
  48. package/dist/react/feedback-notes.d.ts +8 -6
  49. package/dist/react/index.d.ts +3 -3
  50. package/dist/react.js +238 -209
  51. package/dist/realtime/index.d.ts +1 -1
  52. package/dist/server/callback-client.d.ts +4 -4
  53. package/dist/server/events-client.d.ts +21 -21
  54. package/dist/server/operation-types.d.ts +8 -8
  55. package/dist/server/require-scoped-token.d.ts +3 -3
  56. package/dist/server/types.d.ts +2 -2
  57. package/dist/server/verify-scoped-token.d.ts +3 -3
  58. package/dist/server.js +130 -126
  59. package/dist/transport/foir-http.d.ts +14 -14
  60. package/dist/transport/key-kind.d.ts +1 -12
  61. package/dist/types/index.d.ts +2 -2
  62. package/package.json +1 -1
package/dist/push.js CHANGED
@@ -5,10 +5,7 @@ import { print as print2 } from "graphql";
5
5
  var KEY_PREFIXES = [
6
6
  ["foir_pub_", "publishable"],
7
7
  ["foir_srv_", "server"],
8
- ["foir_adm_", "admin"],
9
- ["pk_", "publishable"],
10
- ["sk_", "older"],
11
- ["tc_", "older"]
8
+ ["foir_adm_", "admin"]
12
9
  ];
13
10
  var FOIR_CREDENTIALS_DOC = "https://docs.foir.dev/credentials";
14
11
  function foirKeyKind(apiKey) {
@@ -217,8 +214,8 @@ var FoirAuthDowngradedError = class extends FoirRequestError {
217
214
  downgrade;
218
215
  constructor(downgrade) {
219
216
  super(
220
- `[foir] your customer token was ${downgrade.customerToken} (${downgrade.reason}), so the request was served as ${downgrade.servedAs}`,
221
- { graphQLErrors: [{ message: "customer token rejected", extensions: { code: "AUTH_DOWNGRADED" } }] }
217
+ `[foir] your user token was ${downgrade.userToken} (${downgrade.reason}), so the request was served as ${downgrade.servedAs}`,
218
+ { graphQLErrors: [{ message: "user token rejected", extensions: { code: "AUTH_DOWNGRADED" } }] }
222
219
  );
223
220
  this.name = "FoirAuthDowngradedError";
224
221
  this.downgrade = downgrade;
@@ -226,7 +223,7 @@ var FoirAuthDowngradedError = class extends FoirRequestError {
226
223
  };
227
224
  var FoirSessionExpiredError = class extends FoirRequestError {
228
225
  constructor(options) {
229
- super("[foir] the customer session has expired and could not be refreshed: sign in again", {
226
+ super("[foir] the user session has expired and could not be refreshed: sign in again", {
230
227
  cause: options?.cause,
231
228
  graphQLErrors: [{ message: "session expired", extensions: { code: "SESSION_EXPIRED" } }]
232
229
  });
@@ -243,7 +240,7 @@ function reportAuthDowngrade(envelope) {
243
240
  if (warnedDowngrade === downgrade.reason) return;
244
241
  warnedDowngrade = downgrade.reason;
245
242
  console.warn(
246
- `[foir] your customer token was ${downgrade.customerToken} (${downgrade.reason}) \u2014 this request was served as ${downgrade.servedAs}, so auth-targeted content resolved to its anonymous variant. ` + (downgrade.reason === "expired" ? "Re-exchange the token and retry." : "Check which credential you are sending.")
243
+ `[foir] your user token was ${downgrade.userToken} (${downgrade.reason}) \u2014 this request was served as ${downgrade.servedAs}, so auth-targeted content resolved to its anonymous variant. ` + (downgrade.reason === "expired" ? "Re-exchange the token and retry." : "Check which credential you are sending.")
247
244
  );
248
245
  }
249
246
  function refusePrunedDocument(json, options) {
@@ -1076,42 +1073,63 @@ var AUTH_OPS = {
1076
1073
  authConfig: "authConfig",
1077
1074
  authProviders: "authProviders",
1078
1075
  defaultAuthProvider: "defaultAuthProvider",
1079
- customerSignupContext: "customerSignupContext",
1076
+ signupContext: "signupContext",
1080
1077
  // Post-credential self reads.
1081
1078
  currentUser: "currentUser",
1082
1079
  myProviderToken: "myProviderToken",
1083
- // What the calling credential may do, and for a signed-in customer the roles
1080
+ // What the calling credential may do, and for a signed-in user the roles
1084
1081
  // they hold. `./access` reads it.
1085
1082
  whoami: "whoami",
1086
1083
  // Methods.
1087
- customerLogin: "customerLogin",
1088
- customerRegister: "customerRegister",
1089
- customerRequestOTP: "customerRequestOTP",
1090
- customerLoginOTP: "customerLoginOTP",
1084
+ login: "login",
1085
+ register: "register",
1086
+ requestOTP: "requestOTP",
1087
+ loginWithOTP: "loginWithOTP",
1091
1088
  // Session lifecycle.
1092
- customerRefreshToken: "customerRefreshToken",
1093
- customerLogout: "customerLogout",
1094
- customerJoinWaitlist: "customerJoinWaitlist",
1095
- // Password management and account lifecycle — the block that had no path.
1096
- customerRequestPasswordReset: "customerRequestPasswordReset",
1097
- customerResetPassword: "customerResetPassword",
1098
- customerUpdatePassword: "customerUpdatePassword",
1099
- customerVerifyEmail: "customerVerifyEmail",
1089
+ refreshToken: "refreshToken",
1090
+ logout: "logout",
1091
+ joinWaitlist: "joinWaitlist",
1092
+ // Password management and account lifecycle.
1093
+ requestPasswordReset: "requestPasswordReset",
1094
+ resetPassword: "resetPassword",
1095
+ updatePassword: "updatePassword",
1096
+ verifyEmail: "verifyEmail",
1100
1097
  deleteMyAccount: "deleteMyAccount",
1101
- // The operator's organization context. TWO ops and no third: one to read
1102
- // which organizations the caller may stand in, one to say which. There is
1103
- // deliberately no per-call org argument anywhere in this SDK — the claim the
1104
- // row layer reads is resolved from the caller's own membership row on every
1105
- // request, so an application that never names an org cannot name the wrong
1106
- // one.
1098
+ // The user's own profile, and the apps they have agreed may act for them.
1099
+ updateMyProfile: "updateMyProfile",
1100
+ myAuthorizedApps: "myAuthorizedApps",
1101
+ revokeAuthorizedApp: "revokeAuthorizedApp",
1102
+ // Where they are signed in, their personal access tokens, and the
1103
+ // providers they sign in with.
1104
+ mySessions: "mySessions",
1105
+ endMySession: "endMySession",
1106
+ signOutEverywhere: "signOutEverywhere",
1107
+ createPersonalAccessToken: "createPersonalAccessToken",
1108
+ mySignInMethods: "mySignInMethods",
1109
+ connectSignInMethod: "connectSignInMethod",
1110
+ disconnectSignInMethod: "disconnectSignInMethod",
1111
+ // Their second factors. A change needs one proven first, by a step-up.
1112
+ myFactors: "myFactors",
1113
+ beginStepUp: "beginStepUp",
1114
+ completeStepUp: "completeStepUp",
1115
+ beginFactorEnrollment: "beginFactorEnrollment",
1116
+ completeFactorEnrollment: "completeFactorEnrollment",
1117
+ removeFactor: "removeFactor",
1118
+ makeRecoveryCodes: "makeRecoveryCodes",
1119
+ // The organizations the caller may stand in. Nothing selects one: a request
1120
+ // names the organization it acts in (`orgId` or `orgUrl` below), and the
1121
+ // platform checks the caller stands there every time.
1107
1122
  myOrganizations: "myOrganizations",
1108
- selectMyOrganization: "selectMyOrganization",
1109
1123
  // Founding one. Present in a manifest only when the project opted in.
1110
- registerOperatorOrganization: "registerOperatorOrganization",
1124
+ registerOrganization: "registerOrganization",
1111
1125
  // External identity providers.
1112
- customerLoginWithProvider: "customerLoginWithProvider",
1113
- customerProviderCallback: "customerProviderCallback",
1114
- customerProviderVerifyOTP: "customerProviderVerifyOTP"
1126
+ loginWithProvider: "loginWithProvider",
1127
+ providerCallback: "providerCallback",
1128
+ providerVerifyOTP: "providerVerifyOTP",
1129
+ // A provider sign-in that names an address somebody already holds, waiting
1130
+ // for the code sent to it.
1131
+ confirmProviderLink: "confirmProviderLink",
1132
+ resendProviderLinkCode: "resendProviderLinkCode"
1115
1133
  };
1116
1134
  function authClientConfig(env, options) {
1117
1135
  const apiKey = resolveFoirApiKey(env);
@@ -1174,32 +1192,32 @@ function stripUndefined(args) {
1174
1192
  // src/auth/auth.ts
1175
1193
  var TOKEN_KEY = "foir:token";
1176
1194
  var REFRESH_KEY = "foir:refreshToken";
1177
- var CUSTOMER_ID_KEY = "foir:customerId";
1195
+ var USER_ID_KEY = "foir:userId";
1178
1196
  var EMAIL_KEY = "foir:email";
1179
- async function customerRefreshToken(env, refreshToken) {
1180
- return authOp(env, AUTH_OPS.customerRefreshToken, { refreshToken });
1197
+ async function refreshTokens(env, refreshToken) {
1198
+ return authOp(env, AUTH_OPS.refreshToken, { refreshToken });
1181
1199
  }
1182
1200
  async function saveSession(adapter, result) {
1183
1201
  await adapter.set(TOKEN_KEY, result.token);
1184
1202
  await adapter.set(REFRESH_KEY, result.refreshToken);
1185
- if (!result.customerId) {
1186
- return await getSessionCustomer(adapter) ?? { id: "", email: "" };
1203
+ if (!result.userId) {
1204
+ return await getSessionUser(adapter) ?? { id: "", email: "" };
1187
1205
  }
1188
- await adapter.set(CUSTOMER_ID_KEY, result.customerId);
1206
+ await adapter.set(USER_ID_KEY, result.userId);
1189
1207
  await adapter.set(EMAIL_KEY, result.email);
1190
- return { id: result.customerId, email: result.email };
1208
+ return { id: result.userId, email: result.email };
1191
1209
  }
1192
1210
  async function clearSession(adapter) {
1193
1211
  await adapter.unset(TOKEN_KEY);
1194
1212
  await adapter.unset(REFRESH_KEY);
1195
- await adapter.unset(CUSTOMER_ID_KEY);
1213
+ await adapter.unset(USER_ID_KEY);
1196
1214
  await adapter.unset(EMAIL_KEY);
1197
1215
  }
1198
1216
  async function getSessionToken(adapter) {
1199
1217
  return await adapter.get(TOKEN_KEY) ?? null;
1200
1218
  }
1201
- async function getSessionCustomer(adapter) {
1202
- const id = await adapter.get(CUSTOMER_ID_KEY) ?? null;
1219
+ async function getSessionUser(adapter) {
1220
+ const id = await adapter.get(USER_ID_KEY) ?? null;
1203
1221
  const email = await adapter.get(EMAIL_KEY) ?? null;
1204
1222
  if (!id) return null;
1205
1223
  return { id, email: email ?? "" };
@@ -1208,7 +1226,7 @@ async function refreshSession(adapter, env) {
1208
1226
  const refreshToken = await adapter.get(REFRESH_KEY) ?? null;
1209
1227
  if (!refreshToken) return null;
1210
1228
  try {
1211
- const result = await customerRefreshToken(env, refreshToken);
1229
+ const result = await refreshTokens(env, refreshToken);
1212
1230
  await saveSession(adapter, result);
1213
1231
  return { token: result.token, refreshToken: result.refreshToken };
1214
1232
  } catch {
@@ -1,4 +1,4 @@
1
- import type { FoirCustomerNote, FoirSubject, FoirSubjectRegistry } from '../data';
1
+ import type { FoirUserNote, FoirSubject, FoirSubjectRegistry } from '../data';
2
2
  import { type FoirFeedbackClient } from './feedback-notes';
3
3
  export type { FoirFeedbackClient } from './feedback-notes';
4
4
  export interface FoirFeedbackProps {
@@ -46,7 +46,7 @@ export interface FoirFeedbackProps {
46
46
  */
47
47
  onSignIn?: () => void;
48
48
  /** Called with the note once it is written. */
49
- onSubmitted?: (note: FoirCustomerNote) => void;
49
+ onSubmitted?: (note: FoirUserNote) => void;
50
50
  /**
51
51
  * Called with anything that failed. The widget also logs it — this is for
52
52
  * routing it into your own error reporting, not for making it visible.
@@ -1,22 +1,22 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { AuthProviderPublic, FoirAccess, FoirCustomer, FoirSessionConfig, SessionAdapter } from '../auth';
2
+ import type { AuthProviderPublic, FoirAccess, FoirUser, FoirSessionConfig, SessionAdapter } from '../auth';
3
3
  import type { ProviderCallbackInput, ProviderLoginInput } from '../auth';
4
4
  import type { FoirEnv } from '../graphql/foir-request';
5
5
  /** Where the session hydration stands. */
6
6
  export type FoirStatus = 'loading' | 'authenticated' | 'unauthenticated';
7
7
  /**
8
- * Where reading the signed-in customer's access stands. `idle` until something
8
+ * Where reading the signed-in user's access stands. `idle` until something
9
9
  * asks for it; `unavailable` when the platform could not be asked.
10
10
  */
11
11
  export type FoirAccessStatus = 'idle' | 'loading' | 'ready' | 'unavailable';
12
12
  /** The full context value. Read it through the hooks below, not directly. */
13
13
  export interface FoirContextValue {
14
14
  status: FoirStatus;
15
- customer: FoirCustomer | null;
16
- /** The signed-in customer's access, once read. See {@link useFoirAccess}. */
15
+ user: FoirUser | null;
16
+ /** The signed-in user's access, once read. See {@link useFoirAccess}. */
17
17
  access: FoirAccess | null;
18
18
  accessStatus: FoirAccessStatus;
19
- /** Ask the platform for the signed-in customer's access, again if it was read before. */
19
+ /** Ask the platform for the signed-in user's access, again if it was read before. */
20
20
  loadAccess(): Promise<void>;
21
21
  /** The same, unless a read is already under way: then that one is awaited. */
22
22
  ensureAccess(): Promise<void>;
@@ -27,22 +27,22 @@ export interface FoirContextValue {
27
27
  signIn(vars: {
28
28
  email: string;
29
29
  password: string;
30
- }): Promise<FoirCustomer>;
30
+ }): Promise<FoirUser>;
31
31
  register(vars: {
32
32
  email: string;
33
33
  password: string;
34
- }): Promise<FoirCustomer>;
34
+ }): Promise<FoirUser>;
35
35
  requestOtp(email: string): Promise<boolean>;
36
36
  signInWithOtp(vars: {
37
37
  email: string;
38
38
  otp: string;
39
- }): Promise<FoirCustomer>;
39
+ }): Promise<FoirUser>;
40
40
  /** Start a provider (OAuth/OIDC) login. Redirect providers navigate away. */
41
41
  signInWithProvider(providerKey: string, opts?: Omit<ProviderLoginInput, 'providerKey'>): Promise<void>;
42
42
  /** Complete a provider login from your callback route (code + state). */
43
43
  completeProviderLogin(input: Omit<ProviderCallbackInput, 'providerKey'> & {
44
44
  providerKey: string;
45
- }): Promise<FoirCustomer>;
45
+ }): Promise<FoirUser>;
46
46
  signOut(): Promise<void>;
47
47
  /** Rotate the access token; returns false (and signs out) if it can't. */
48
48
  refresh(): Promise<boolean>;
@@ -58,7 +58,7 @@ export interface FoirContextValue {
58
58
  hostedSignInUrl: ((returnTo?: string) => string) | null;
59
59
  }
60
60
  export interface FoirProviderProps {
61
- /** API config: `{ PLATFORM_API_URL, PLATFORM_API_KEY }` (a publishable `pk_` key). */
61
+ /** API config: `{ PLATFORM_API_URL, PLATFORM_API_KEY }` (a publishable key). */
62
62
  env: FoirEnv;
63
63
  /** Session store for token mode. Defaults to a browser localStorage adapter. */
64
64
  adapter?: SessionAdapter;
@@ -78,8 +78,8 @@ export interface FoirProviderProps {
78
78
  children: ReactNode;
79
79
  }
80
80
  /**
81
- * Provides Foir customer auth to a React tree. Hydrates the session on mount,
82
- * then exposes the current customer and sign-in/out actions through
81
+ * Provides Foir user auth to a React tree. Hydrates the session on mount,
82
+ * then exposes the current user and sign-in/out actions through
83
83
  * {@link useFoirSession}, {@link useFoirUser}, and {@link useFoirAuth}.
84
84
  *
85
85
  * Two session models:
@@ -93,14 +93,14 @@ export declare function FoirProvider({ env, adapter, hostedSession, children, }:
93
93
  /** The current session state. */
94
94
  export interface FoirSession {
95
95
  status: FoirStatus;
96
- customer: FoirCustomer | null;
96
+ user: FoirUser | null;
97
97
  isLoading: boolean;
98
98
  isAuthenticated: boolean;
99
99
  }
100
- /** Read the current session status and customer. */
100
+ /** Read the current session status and user. */
101
101
  export declare function useFoirSession(): FoirSession;
102
- /** The signed-in customer (`{ id, email }`), or null. */
103
- export declare function useFoirUser(): FoirCustomer | null;
102
+ /** The signed-in user (`{ id, email }`), or null. */
103
+ export declare function useFoirUser(): FoirUser | null;
104
104
  /** What {@link useFoirAccess} returns. */
105
105
  export interface FoirAccessState {
106
106
  /**
@@ -110,17 +110,17 @@ export interface FoirAccessState {
110
110
  */
111
111
  status: 'loading' | 'ready' | 'unavailable';
112
112
  isLoading: boolean;
113
- /** The signed-in customer's access, or null: signed out, loading or unavailable. */
113
+ /** The signed-in user's access, or null: signed out, loading or unavailable. */
114
114
  access: FoirAccess | null;
115
- /** Whether the customer holds the role with this key. False until known. */
115
+ /** Whether the user holds the role with this key. False until known. */
116
116
  hasRole(key: string): boolean;
117
- /** Whether the customer's scopes cover this one. False until known. */
117
+ /** Whether the user's scopes cover this one. False until known. */
118
118
  hasScope(scope: string): boolean;
119
119
  /** Ask the platform again, for a role given or taken away since. */
120
120
  reload(): Promise<void>;
121
121
  }
122
122
  /**
123
- * The roles the signed-in customer holds and the scopes they resolve to, as the
123
+ * The roles the signed-in user holds and the scopes they resolve to, as the
124
124
  * platform resolved them. Read on first use, again when the session refreshes,
125
125
  * and whenever `reload` is called.
126
126
  *
@@ -133,20 +133,20 @@ export declare function useFoirAuth(): {
133
133
  signIn: (vars: {
134
134
  email: string;
135
135
  password: string;
136
- }) => Promise<FoirCustomer>;
136
+ }) => Promise<FoirUser>;
137
137
  register: (vars: {
138
138
  email: string;
139
139
  password: string;
140
- }) => Promise<FoirCustomer>;
140
+ }) => Promise<FoirUser>;
141
141
  requestOtp: (email: string) => Promise<boolean>;
142
142
  signInWithOtp: (vars: {
143
143
  email: string;
144
144
  otp: string;
145
- }) => Promise<FoirCustomer>;
145
+ }) => Promise<FoirUser>;
146
146
  signInWithProvider: (providerKey: string, opts?: Omit<ProviderLoginInput, "providerKey">) => Promise<void>;
147
147
  completeProviderLogin: (input: Omit<ProviderCallbackInput, "providerKey"> & {
148
148
  providerKey: string;
149
- }) => Promise<FoirCustomer>;
149
+ }) => Promise<FoirUser>;
150
150
  signOut: () => Promise<void>;
151
151
  refresh: () => Promise<boolean>;
152
152
  getToken: () => Promise<string | null>;
@@ -1,4 +1,4 @@
1
- import type { FoirCustomer } from '../auth';
1
+ import type { FoirUser } from '../auth';
2
2
  export interface SignInProps {
3
3
  /** `password` (default) or `otp` (email one-time code). Ignored when `hostedUrl` is set. */
4
4
  method?: 'password' | 'otp';
@@ -8,12 +8,12 @@ export interface SignInProps {
8
8
  oauth?: boolean;
9
9
  /** Navigate here after a successful sign-in. */
10
10
  afterSignInUrl?: string;
11
- /** Called with the customer on a successful sign-in (before any redirect). */
12
- onSignIn?(customer: FoirCustomer): void;
11
+ /** Called with the user on a successful sign-in (before any redirect). */
12
+ onSignIn?(user: FoirUser): void;
13
13
  className?: string;
14
14
  }
15
15
  /**
16
- * A drop-in customer sign-in. Renders an email/password (or OTP) form and,
16
+ * A drop-in user sign-in. Renders an email/password (or OTP) form and,
17
17
  * unless disabled, OAuth provider buttons. Set `hostedUrl` to instead render a
18
18
  * button that redirects to a hosted login page. All state is handled through
19
19
  * {@link FoirProvider}; on success it calls `onSignIn` and optionally navigates
@@ -6,7 +6,7 @@ export interface UserButtonProps {
6
6
  className?: string;
7
7
  }
8
8
  /**
9
- * A minimal signed-in affordance: the customer's email plus a sign-out button.
9
+ * A minimal signed-in affordance: the user's email plus a sign-out button.
10
10
  * Renders nothing when signed out. Style it via `className` (the default is an
11
11
  * unopinionated inline layout).
12
12
  */
@@ -7,7 +7,7 @@
7
7
  * shape (see `data/selection.ts`) — so every response here has to be read rather
8
8
  * than cast, and reading is the part worth testing on its own.
9
9
  */
10
- import type { FoirCustomerNote, FoirNoteConfig, FoirSubject } from '../data';
10
+ import type { FoirUserNote, FoirNoteConfig, FoirSubject } from '../data';
11
11
  import type { FoirScreenCapture } from '../media/screen-capture';
12
12
  /**
13
13
  * The client the widget needs, and no more of it.
@@ -44,9 +44,9 @@ export interface FoirFeedbackClient {
44
44
  * widget can name.
45
45
  *
46
46
  * The distinction earns its place because the three have different audiences.
47
- * `signIn` is the visitor's to fix. `scope` is the OPERATOR's — a role that does
47
+ * `signIn` is the visitor's to fix. `scope` is the PROJECT's: a role that does
48
48
  * not grant `notes:create` produces `missing required scope: notes:create`, which
49
- * reads like a bad API key and is not one; the key is fine and the customer's
49
+ * reads like a bad API key and is not one; the key is fine and the user's
50
50
  * role is short a capability. `other` is everything the widget will not pretend
51
51
  * to understand.
52
52
  */
@@ -61,8 +61,10 @@ export type FoirFeedbackFault = {
61
61
  /**
62
62
  * Read the refusal, if it is one of the two the widget can act on.
63
63
  *
64
- * Matched on the platform's own sentences rather than on an error code, because
65
- * these two arrive as plain GraphQL errors with no `extensions.code` to read.
64
+ * Matched on the platform's own sentences rather than on an error code: the
65
+ * sign-in refusal carries no `extensions.code`, and the scope refusal's code
66
+ * (`PERMISSION_DENIED`) does not say which permission, which only its sentence
67
+ * names.
66
68
  * Both the wrapper's message and every individual GraphQL error are scanned: the
67
69
  * transport joins them into one string on the way out, but a partial-error
68
70
  * envelope keeps them apart, and only one of the two forms is guaranteed.
@@ -98,4 +100,4 @@ export interface FoirFeedbackSubmission {
98
100
  * worse than one that did not arrive: they have no way to tell, and the thing
99
101
  * they wrote ("as you can see in the screenshot") stops making sense.
100
102
  */
101
- export declare function submitFeedbackNote(client: FoirFeedbackClient, submission: FoirFeedbackSubmission): Promise<FoirCustomerNote>;
103
+ export declare function submitFeedbackNote(client: FoirFeedbackClient, submission: FoirFeedbackSubmission): Promise<FoirUserNote>;
@@ -1,8 +1,8 @@
1
1
  /**
2
- * `@foir/sdk/react` — drop-in React components for Foir customers.
2
+ * `@foir/sdk/react` — drop-in React components for Foir users.
3
3
  *
4
4
  * Wrap your app in `<FoirProvider>`, then read the session with
5
- * `useFoirSession` / `useFoirUser`, ask what the customer may see with
5
+ * `useFoirSession` / `useFoirUser`, ask what the user may see with
6
6
  * `useFoirAccess`, and drive it with `useFoirAuth` — or drop in
7
7
  * the `<SignIn>`, `<OAuthButtons>`, and `<UserButton>` components. Built entirely
8
8
  * on `@foir/sdk/auth`; `react` is the only peer dependency.
@@ -22,5 +22,5 @@ export type { UserButtonProps } from './UserButton';
22
22
  export { FoirFeedback } from './FoirFeedback';
23
23
  export type { FoirFeedbackProps, FoirFeedbackClient } from './FoirFeedback';
24
24
  export { createLocalStorageAdapter } from './localStorageAdapter';
25
- export type { FoirAccess, FoirCustomer, SessionAdapter, AuthProviderPublic } from '../auth';
25
+ export type { FoirAccess, FoirUser, SessionAdapter, AuthProviderPublic } from '../auth';
26
26
  export type { FoirEnv } from '../graphql/foir-request';