@fias/arche-sdk 2.31.0 → 2.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/theme.js CHANGED
@@ -15,6 +15,7 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.LIGHT_THEME = exports.DARK_THEME = void 0;
17
17
  exports.getDefaultTheme = getDefaultTheme;
18
+ exports.normalizeFiasBrand = normalizeFiasBrand;
18
19
  const SYSTEM_FONTS = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
19
20
  const MONO_FONTS = '"SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace';
20
21
  const SHARED_SPACING = { xs: '4px', sm: '8px', md: '16px', lg: '24px', xl: '32px' };
@@ -82,4 +83,37 @@ exports.LIGHT_THEME = {
82
83
  function getDefaultTheme(mode) {
83
84
  return mode === 'light' ? exports.LIGHT_THEME : exports.DARK_THEME;
84
85
  }
86
+ const BRAND_HEX = /^#[0-9a-fA-F]{6}$/;
87
+ /** Well above the platform's stored-logo cap (64 KB data URL); refuses a value nobody should draw. */
88
+ const BRAND_LOGO_URL_MAX = 256 * 1024;
89
+ const BRAND_NAME_MAX = 200;
90
+ /**
91
+ * A Company brand in the shape apps receive it (`FiasTheme.brand`), or
92
+ * `undefined` when there is nothing to show. Used by every host — the
93
+ * platform, the builder preview and the dev harness — and again by the SDK on
94
+ * what arrives, so an app can rely on the shape whoever sent it: colours are
95
+ * `#RRGGBB` or null, the logo is a `data:image/` or `https:` URL or null.
96
+ */
97
+ function normalizeFiasBrand(input) {
98
+ if (!input || typeof input !== 'object')
99
+ return undefined;
100
+ const raw = input;
101
+ const color = (v) => (typeof v === 'string' && BRAND_HEX.test(v) ? v : null);
102
+ const name = typeof raw.displayName === 'string' && raw.displayName.trim() !== ''
103
+ ? raw.displayName.trim().slice(0, BRAND_NAME_MAX)
104
+ : null;
105
+ const logo = typeof raw.logoUrl === 'string' &&
106
+ raw.logoUrl.length <= BRAND_LOGO_URL_MAX &&
107
+ (raw.logoUrl.startsWith('data:image/') || raw.logoUrl.startsWith('https://'))
108
+ ? raw.logoUrl
109
+ : null;
110
+ const brand = {
111
+ displayName: name,
112
+ logoUrl: logo,
113
+ primaryColor: color(raw.primaryColor),
114
+ accentColor: color(raw.accentColor),
115
+ headerTextColor: color(raw.headerTextColor),
116
+ };
117
+ return Object.values(brand).some((v) => v !== null) ? brand : undefined;
118
+ }
85
119
  //# sourceMappingURL=theme.js.map
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAwEH,0CAEC;AAtED,MAAM,YAAY,GAAG,mEAAmE,CAAC;AACzF,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAErF,MAAM,cAAc,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AACpF,MAAM,YAAY,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACrF,MAAM,iBAAiB,GAA4B;IACjD,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,UAAU;IACxB,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,UAAU;IACvB,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,sEAAsE;IAChF,QAAQ,EAAE,wEAAwE;IAClF,WAAW,EAAE,KAAK;CACnB,CAAC;AAEW,QAAA,UAAU,GAAc;IACnC,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,SAAS;QACtB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,SAAS;QACrB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,SAAS;QACnB,IAAI,EAAE,SAAS;QACf,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;KAChB;IACD,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,YAAY;IACnB,UAAU,EAAE,iBAAiB;CAC9B,CAAC;AAEW,QAAA,WAAW,GAAc;IACpC,IAAI,EAAE,OAAO;IACb,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,SAAS;QACtB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,SAAS;QACrB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,SAAS;QACnB,IAAI,EAAE,SAAS;QACf,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;KAChB;IACD,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,YAAY;IACnB,UAAU,EAAE,iBAAiB;CAC9B,CAAC;AAEF,SAAgB,eAAe,CAAC,IAAsB;IACpD,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAW,CAAC,CAAC,CAAC,kBAAU,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -13,9 +13,20 @@ export { VALID_PLUGIN_PERMISSIONS, isValidPluginPermission } from './generated/p
13
13
  * User profile data available via useFiasUser() hook.
14
14
  */
15
15
  export interface FiasUser {
16
- userId: string;
16
+ /**
17
+ * Your app's identifier for this person (`aur_…`). The same everywhere in
18
+ * your app, different in every other app, so it can't link people across
19
+ * apps. Store it wherever your data names a person.
20
+ */
21
+ ref: string;
17
22
  displayName: string;
18
23
  avatar: string | null;
24
+ /**
25
+ * @deprecated The platform user id. Present only for apps that existed
26
+ * before app user refs, until the sunset; new apps never receive it. Use
27
+ * `ref`. Removed in the next major version.
28
+ */
29
+ userId?: string;
19
30
  }
20
31
  /**
21
32
  * Platform theme tokens available via useFiasTheme() hook.
@@ -63,6 +74,30 @@ export interface FiasTheme {
63
74
  shadowLg: string;
64
75
  borderWidth: string;
65
76
  };
77
+ /**
78
+ * The Company's brand (ADR-023), present only while the app runs on that
79
+ * Company's portal (ADR-024) and the Company has set one. Absent on fias.io
80
+ * and on a portal without a brand — keep your own palette then. Each field
81
+ * is null when the Company left it unset.
82
+ */
83
+ brand?: FiasBrand;
84
+ }
85
+ /**
86
+ * A Company's brand as an app receives it in {@link FiasTheme.brand}. The same
87
+ * tokens the portal's own shell is drawn with, and already public on the
88
+ * portal: nothing here is about the person using the app.
89
+ */
90
+ export interface FiasBrand {
91
+ /** The name the Company shows people, e.g. on its sign-in page. */
92
+ displayName: string | null;
93
+ /** The Company's logo, as an image URL (today a `data:` URL) for an `<img src>`. */
94
+ logoUrl: string | null;
95
+ /** `#RRGGBB`. The Company's main colour — headers, primary buttons. */
96
+ primaryColor: string | null;
97
+ /** `#RRGGBB`. A second colour for highlights and links. */
98
+ accentColor: string | null;
99
+ /** `#RRGGBB`. Text drawn on `primaryColor`. */
100
+ headerTextColor: string | null;
66
101
  }
67
102
  /**
68
103
  * Storage API available via useFiasStorage() hook.
@@ -2006,11 +2041,17 @@ export interface CommunityAssetsApi {
2006
2041
  }>;
2007
2042
  }
2008
2043
  /**
2009
- * A recipient: a member named by user id (the address is resolved by the
2010
- * platform and never returned to the app), or a raw address — accepted only
2011
- * when the Company allowed this app to email anyone.
2044
+ * A recipient: a member named by your app's ref for them (`FiasUser.ref`, or a
2045
+ * ref you stored — the address is resolved by the platform and never returned
2046
+ * to the app), or a raw address — accepted only when the Company allowed this
2047
+ * app to email anyone. `{ userId }` is deprecated and accepted only from apps
2048
+ * that existed before refs.
2012
2049
  */
2013
2050
  export type CompanyEmailRecipient = {
2051
+ ref: string;
2052
+ }
2053
+ /** @deprecated Use `{ ref }`. Accepted only from apps that existed before refs. */
2054
+ | {
2014
2055
  userId: string;
2015
2056
  } | {
2016
2057
  email: string;
@@ -2100,6 +2141,157 @@ export interface FiasConnectionsApi {
2100
2141
  /** Give up this app's access to one connection. */
2101
2142
  release: (connectionId: string) => Promise<void>;
2102
2143
  }
2144
+ export type FiasWebSourceSiteCategory = 'credit_union' | 'bank' | 'government' | 'other';
2145
+ /** A website Fias approved for apps to read. Any page on it (or its `www.` twin) may be read. */
2146
+ export interface FiasWebSourceSite {
2147
+ host: string;
2148
+ name: string;
2149
+ category: FiasWebSourceSiteCategory;
2150
+ }
2151
+ export interface FiasWebSourceListOptions {
2152
+ category?: FiasWebSourceSiteCategory;
2153
+ /** Matched against the site's name and host. */
2154
+ search?: string;
2155
+ /** 1–200; default 50. */
2156
+ limit?: number;
2157
+ offset?: number;
2158
+ }
2159
+ export interface FiasWebSourceSiteList {
2160
+ sites: FiasWebSourceSite[];
2161
+ total: number;
2162
+ /** Pass as `offset` for the next page; null on the last page. */
2163
+ nextOffset: number | null;
2164
+ }
2165
+ /**
2166
+ * One field of a form. Every value may come back `null` (the page did not
2167
+ * say). Fias enforces the kinds in code: a value that breaks its field's rules
2168
+ * is returned as `null` and named in `discarded`. There is no free-text kind —
2169
+ * a page never gets words of its own in front of your app; describe what you
2170
+ * need as numbers, dates, yes/no and your own `enum` choices.
2171
+ */
2172
+ export type FiasWebSourceFormScalarField = {
2173
+ kind: 'number';
2174
+ description?: string;
2175
+ min?: number;
2176
+ max?: number;
2177
+ } | {
2178
+ kind: 'integer';
2179
+ description?: string;
2180
+ min?: number;
2181
+ max?: number;
2182
+ } | {
2183
+ kind: 'boolean';
2184
+ description?: string;
2185
+ }
2186
+ /** `YYYY-MM-DD`. */
2187
+ | {
2188
+ kind: 'date';
2189
+ description?: string;
2190
+ }
2191
+ /** One of `values` (1–50 values, each ≤ 60 characters). */
2192
+ | {
2193
+ kind: 'enum';
2194
+ description?: string;
2195
+ values: string[];
2196
+ };
2197
+ /** Rows of a table: up to `maxItems` (≤ 200) objects of scalar fields. */
2198
+ export interface FiasWebSourceFormListField {
2199
+ kind: 'list';
2200
+ description?: string;
2201
+ maxItems?: number;
2202
+ item: Record<string, FiasWebSourceFormScalarField>;
2203
+ }
2204
+ export type FiasWebSourceFormField = FiasWebSourceFormScalarField | FiasWebSourceFormListField;
2205
+ /**
2206
+ * What to read off the page: up to 30 fields, names matching
2207
+ * `^[a-zA-Z][a-zA-Z0-9_]{0,39}$`. Descriptions (≤ 200 characters) tell the
2208
+ * reader what each field means.
2209
+ */
2210
+ export interface FiasWebSourceForm {
2211
+ /** What the form is for (≤ 300 characters). */
2212
+ description?: string;
2213
+ fields: Record<string, FiasWebSourceFormField>;
2214
+ }
2215
+ export type FiasWebSourceValue = number | boolean | string | null;
2216
+ export type FiasWebSourceData = Record<string, FiasWebSourceValue | Array<Record<string, FiasWebSourceValue>>>;
2217
+ export interface FiasWebSourceExtractRequest {
2218
+ /** An `https://` page on an approved site. */
2219
+ url: string;
2220
+ form: FiasWebSourceForm;
2221
+ /**
2222
+ * The oldest copy you will accept, in seconds (default one day, up to 30
2223
+ * days). A page is fetched from its site at most once an hour for the
2224
+ * whole platform, so anything under 3600 is treated as 3600.
2225
+ */
2226
+ maxAgeSeconds?: number;
2227
+ /**
2228
+ * How many independent readings the page gets (default 1). With `2`, the
2229
+ * page is read twice and only a value both readings agree on is returned;
2230
+ * a field they disagree on comes back `null` and is named in `disagreed`,
2231
+ * so you can put it in front of a person instead of publishing one
2232
+ * reading's guess. Agreement says a value was stable across two readings,
2233
+ * not that it is right. Two readings are two reader charges. Use it
2234
+ * wherever a wrong number matters, such as money. The platform may raise
2235
+ * the floor for every app.
2236
+ */
2237
+ reads?: 1 | 2;
2238
+ }
2239
+ export interface FiasWebSourceExtraction<T extends FiasWebSourceData = FiasWebSourceData> {
2240
+ url: string;
2241
+ /**
2242
+ * The site redirected this address to another page on the same site, and
2243
+ * that page is what was read. The new address is not returned: it is text
2244
+ * the site chose.
2245
+ */
2246
+ redirected: boolean;
2247
+ site: FiasWebSourceSite;
2248
+ /** When the page was fetched from its site (ISO 8601) — show it beside the figures. */
2249
+ fetchedAt: string;
2250
+ /** Older than `maxAgeSeconds`: the site could not be asked again just now. */
2251
+ stale: boolean;
2252
+ /** Nothing was fetched or read for this call, so nothing was charged. */
2253
+ fromCache: boolean;
2254
+ /** The page's values, in the form's shape. */
2255
+ data: T;
2256
+ /**
2257
+ * Fields (and list rows) whose values broke the form's rules and became
2258
+ * null or were dropped: `rates[3].apy`, `rates[50..]`. With two readings a
2259
+ * list is named whole (`rates`): a row index belongs to one reading's rows,
2260
+ * and the agreed list no longer has them in that order.
2261
+ */
2262
+ discarded: string[];
2263
+ /**
2264
+ * Fields the two readings disagreed on: `null` instead of one reading's
2265
+ * value, or for a list only the rows both readings produced. Check it
2266
+ * whatever you asked for: the platform may require two readings of every
2267
+ * app, and a one-reading call is answered from a two-reading result when
2268
+ * one is already stored for the page and form. A list named here may be missing rows the page
2269
+ * prints: never conclude "absent on the page" (not offered, no such term)
2270
+ * from a field in `disagreed`; treat it as unknown and confirm with a
2271
+ * person.
2272
+ */
2273
+ disagreed: string[];
2274
+ /** The page was longer than the reader reads; values past the cut are missing. */
2275
+ pageTruncated: boolean;
2276
+ /**
2277
+ * Scripts present and almost no text: the page probably builds its content
2278
+ * with JavaScript, which is never run. Read the site's PDF or data address instead.
2279
+ */
2280
+ scriptHeavy: boolean;
2281
+ }
2282
+ export interface FiasWebSourcesApi {
2283
+ /** The sites Fias approved for apps to read. Free. */
2284
+ listSites: (options?: FiasWebSourceListOptions) => Promise<FiasWebSourceSiteList>;
2285
+ /**
2286
+ * A page on an approved site, read into `form`. A fresh fetch (about a
2287
+ * tenth of a cent) and each reading (the reader model's tokens; two with
2288
+ * `reads: 2`) are charged to the user; a cached result is free. The reader's
2289
+ * model, and so a reading's price, is chosen by the platform (a fast model
2290
+ * today, well under a cent for a typical page). Never returns the page's
2291
+ * text.
2292
+ */
2293
+ extract: <T extends FiasWebSourceData = FiasWebSourceData>(request: FiasWebSourceExtractRequest) => Promise<FiasWebSourceExtraction<T>>;
2294
+ }
2103
2295
  export type FiasCreativeItemKind = 'style' | 'character';
2104
2296
  /** A style or character, as the Creative Library returns it. */
2105
2297
  export interface FiasCreativeItem {
@@ -2794,6 +2986,51 @@ export interface DataStoreCollectionConstraints {
2794
2986
  immutableFields?: string[];
2795
2987
  references?: DataStoreReference[];
2796
2988
  ledgerSums?: DataStoreLedgerSum[];
2989
+ /**
2990
+ * Field paths that name people (ADR-040): when present, each holds one app
2991
+ * user ref (`useFiasUser().ref`) or an array of up to 20, and nothing else.
2992
+ * Declare every field your data uses for a person — it is what lets Fias
2993
+ * relate your records to people and carry refs safely between apps.
2994
+ */
2995
+ personFields?: string[];
2996
+ /**
2997
+ * An attested log (ADR-042): Fias stamps every row with who wrote it — see
2998
+ * {@link DataStoreAttestation} — and no app code, user, agent or
2999
+ * contributor can change a row or delete one on its own. The log ends with
3000
+ * your app: no workspace holding one can be archived (`WORKSPACE_ATTESTED`).
3001
+ * Requires `appendOnly: true` and
3002
+ * the `data:attested` permission; declared only in `fias-plugin.json`, and
3003
+ * only on a NEW collection (never added to one that exists). Not allowed on
3004
+ * `shared` scope.
3005
+ */
3006
+ attested?: true;
3007
+ }
3008
+ /**
3009
+ * What Fias records beside a row of an attested collection (ADR-042). Never
3010
+ * part of `data`, never writable by your code.
3011
+ *
3012
+ * It proves which person (or agent key acting for them, or Fias AI) wrote the
3013
+ * row, through which channel, when, and under which release of your app. It
3014
+ * does not prove intent or that `data` is true: your code wrote `data`.
3015
+ * Describe it as "platform-attested", never "tamper-evident".
3016
+ */
3017
+ export interface DataStoreAttestation {
3018
+ /** The app user ref of the person accountable for the write. Name it with `resolvePeople`. */
3019
+ personRef: string;
3020
+ /** The agent key that wrote it, for `channel: 'agent'` only. Never resolves to a name. */
3021
+ agentRef?: string;
3022
+ /**
3023
+ * How the write arrived: a fias.io session, a Company portal session, Fias
3024
+ * AI, an external agent key, or a dev / test / preview sandbox
3025
+ * (`non_production` — never present such a row as real).
3026
+ */
3027
+ channel: 'session' | 'portal' | 'assistant' | 'agent' | 'non_production';
3028
+ /** When Fias stored the row: the database clock at the insert (ISO 8601). */
3029
+ recordedAt: string;
3030
+ /** Your app's manifest version live when the write was accepted. On every production row; never on a test row. */
3031
+ appVersion?: string;
3032
+ /** The hash of that release's bundle. On every production row; never on a test row. */
3033
+ buildHash?: string;
2797
3034
  }
2798
3035
  /**
2799
3036
  * Counter-follows-ledger: `field` on this collection's documents may only
@@ -2896,6 +3133,8 @@ export interface DataStoreBatchResult {
2896
3133
  key: string;
2897
3134
  version?: number;
2898
3135
  audience?: string;
3136
+ /** The row's attestation, for a row of an attested collection (ADR-042). */
3137
+ attestation?: DataStoreAttestation;
2899
3138
  }[];
2900
3139
  }
2901
3140
  /**
@@ -2914,6 +3153,8 @@ export interface DataStorePutResult {
2914
3153
  key?: string;
2915
3154
  /** The audience the document sits in, in a collection with audiences. */
2916
3155
  audience?: string;
3156
+ /** What Fias recorded about the write, for a row of an attested collection (ADR-042). */
3157
+ attestation?: DataStoreAttestation;
2917
3158
  }
2918
3159
  /**
2919
3160
  * A document returned from the data store.
@@ -2945,6 +3186,8 @@ export interface DataStoreDocument<T = Record<string, unknown>> {
2945
3186
  * audience's readers, never by your code. Absent elsewhere.
2946
3187
  */
2947
3188
  audience?: string;
3189
+ /** Present on rows of an attested collection (ADR-042): see {@link DataStoreAttestation}. */
3190
+ attestation?: DataStoreAttestation;
2948
3191
  }
2949
3192
  /**
2950
3193
  * Filter condition for querying documents.
@@ -3035,6 +3278,8 @@ export interface DataStoreSearchMatch<T = Record<string, unknown>> {
3035
3278
  authoredByCollaborator?: boolean;
3036
3279
  /** The match's audience, in a collection with audiences — see {@link DataStoreDocument.audience}. */
3037
3280
  audience?: string;
3281
+ /** Present on rows of an attested collection — see {@link DataStoreDocument.attestation}. */
3282
+ attestation?: DataStoreAttestation;
3038
3283
  }
3039
3284
  /**
3040
3285
  * Data Store API available via useFiasDataStore() hook.
@@ -3208,15 +3453,31 @@ export interface DataStoreWorkspace {
3208
3453
  */
3209
3454
  holderBacked?: boolean;
3210
3455
  }
3211
- /** A member of a workspace. Members are addressed by username — the platform
3212
- * userId is internal and never exposed to plugins or users. */
3456
+ /**
3457
+ * A member of a workspace (ADR-040 §4). Members are named by your app's `ref`
3458
+ * for them, with their display name; the platform userId is never exposed.
3459
+ * Apps that existed before refs still get `username` instead.
3460
+ */
3213
3461
  export interface DataStoreWorkspaceMember {
3214
- username: string;
3462
+ /** Your app's ref for this member — pass it back to `updateMember` / `removeMember`. */
3463
+ ref?: string;
3464
+ displayName?: string;
3465
+ /** @deprecated Only for apps that existed before refs, which get it instead of `ref`. */
3466
+ username?: string;
3215
3467
  role: WorkspaceRole;
3216
3468
  grantedAt: string;
3217
3469
  /** ISO-8601 expiry, or null for a permanent membership. Owners never expire. */
3218
3470
  expiresAt: string | null;
3219
3471
  }
3472
+ /**
3473
+ * Who a membership change is about: `{ ref }` from `listMembers`. A plain
3474
+ * username string works only for apps from before app user refs (until the
3475
+ * sunset) and in the dev harness and Forge test channel; elsewhere it rejects
3476
+ * with `MEMBER_TARGET_USE_REF`.
3477
+ */
3478
+ export type WorkspaceMemberTarget = string | {
3479
+ ref: string;
3480
+ };
3220
3481
  /**
3221
3482
  * Workspace tenancy API available via the `useFiasWorkspaces()` hook.
3222
3483
  *
@@ -3260,14 +3521,57 @@ export interface FiasWorkspacesApi {
3260
3521
  archive: (workspaceId: string) => Promise<void>;
3261
3522
  /** List a workspace's members (any member). */
3262
3523
  listMembers: (workspaceId: string) => Promise<DataStoreWorkspaceMember[]>;
3263
- /** Add a member by username, with a role (owner/admin; cannot grant above your
3264
- * own role). Optionally time-bound the membership with an ISO-8601 `expiresAt`
3265
- * (owners cannot expire). Rejects with `USER_NOT_FOUND` if no such user. */
3524
+ /**
3525
+ * Let the person add people to a workspace, in a sheet Fias draws (ADR-040).
3526
+ * The person picks co-members of their Fias workspace or types an exact
3527
+ * username, and may change the suggested `role`; you never name anyone.
3528
+ * Resolves with who was added (empty if they added no one), by `ref`.
3529
+ * Rejects with `ADD_PEOPLE_UNAVAILABLE` where Fias draws no sheet (the
3530
+ * Forge test channel) and `SHEET_BUSY` while another sheet is open.
3531
+ */
3532
+ addPeople: (workspaceId: string, options?: {
3533
+ role?: 'admin' | 'member' | 'viewer';
3534
+ }) => Promise<{
3535
+ added: AddedWorkspacePerson[];
3536
+ }>;
3537
+ /**
3538
+ * @deprecated Use `addPeople`. Adding by a username your code supplies works
3539
+ * only for apps that existed before app user refs (until the sunset), and in
3540
+ * the dev harness and Forge test channel; elsewhere it rejects with
3541
+ * `ADD_MEMBER_USE_SHEET`. Owner/admin; cannot grant above your own role;
3542
+ * optional ISO-8601 `expiresAt` (owners cannot expire).
3543
+ */
3266
3544
  addMember: (workspaceId: string, username: string, role: WorkspaceRole, expiresAt?: string) => Promise<DataStoreWorkspaceMember>;
3267
- /** Change a member's role by username (owner/admin; keeps the one-owner invariant). */
3268
- updateMember: (workspaceId: string, username: string, role: WorkspaceRole) => Promise<DataStoreWorkspaceMember>;
3269
- /** Remove a member by username (owner/admin, or yourself; keeps the one-owner invariant). */
3270
- removeMember: (workspaceId: string, username: string) => Promise<void>;
3545
+ /** Change a member's role (owner/admin; keeps the one-owner invariant). */
3546
+ updateMember: (workspaceId: string, member: WorkspaceMemberTarget, role: WorkspaceRole) => Promise<DataStoreWorkspaceMember>;
3547
+ /** Remove a member (owner/admin, or yourself; keeps the one-owner invariant). */
3548
+ removeMember: (workspaceId: string, member: WorkspaceMemberTarget) => Promise<void>;
3549
+ /**
3550
+ * Names for people your app knows by ref (`FiasUser.ref`, or refs you
3551
+ * stored), any number (an empty list answers `[]`; the SDK pages large
3552
+ * lists), in the order given. A ref is named only
3553
+ * when it belongs to a current member of `workspaceId` — a workspace you
3554
+ * belong to — and every other ref is `null`: someone who left, an unknown
3555
+ * ref, another app's ref. Without `workspaceId`, only the user's own ref
3556
+ * resolves. In a Fias org workspace, names also need `data:workspace-people:read`
3557
+ * and the workspace's approval of your app covering it; otherwise every ref
3558
+ * is `null`. Never returns an id or an email. Refuses like `get` when you
3559
+ * are not a member.
3560
+ */
3561
+ resolvePeople: (refs: string[], workspaceId?: string) => Promise<(FiasPerson | null)[]>;
3562
+ }
3563
+ /** Someone the person added in the Add people sheet (ADR-040). */
3564
+ export interface AddedWorkspacePerson {
3565
+ /** Your app's ref for them. */
3566
+ ref: string;
3567
+ displayName: string;
3568
+ role: string;
3569
+ }
3570
+ /** A person your app named by ref (ADR-040): display name only, never an id. */
3571
+ export interface FiasPerson {
3572
+ ref: string;
3573
+ displayName: string;
3574
+ avatar: string | null;
3271
3575
  }
3272
3576
  /**
3273
3577
  * The current user's access in one workspace where only workspace TIERS