@foir/sdk 0.16.0 → 0.18.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/CHANGELOG.md +51 -0
- package/dist/app/client.d.ts +33 -6
- package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +71 -4
- package/dist/app/errors.d.ts +20 -0
- package/dist/app/index.d.ts +2 -2
- package/dist/app/vocabulary.generated.d.ts +1 -1
- package/dist/app-contract.js +24 -22
- package/dist/app.js +32 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -108,6 +108,57 @@ nobody asking for `@foir/sdk` gets it early. The push that carries the commit to
|
|
|
108
108
|
|
|
109
109
|
Changes on `dev` that have not been published to npm.
|
|
110
110
|
|
|
111
|
+
## [0.18.0] — 2026-10-02
|
|
112
|
+
|
|
113
|
+
Published under npm's `next` tag from `dev`, because it calls fields the
|
|
114
|
+
platform serves from the next promotion; `latest` moves to it then.
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- **Breaking: an app finds a customer by identity through its install, not
|
|
119
|
+
through a model** (`@foir/sdk/app`). The customer sign-in an app's customers
|
|
120
|
+
come through is paired with the install as a whole, so the two reads that
|
|
121
|
+
walk it no longer name a model and have moved beside the other customer
|
|
122
|
+
reads:
|
|
123
|
+
- `records.customer.identities(model, customerId)` is now
|
|
124
|
+
`customers.identities(customerId)`.
|
|
125
|
+
- `customers.byIdentity(identity)` is new: the id of the customer who holds
|
|
126
|
+
an identity at the app's own system, or `null`. It replaces reading a
|
|
127
|
+
customer's record for its owner.
|
|
128
|
+
|
|
129
|
+
Both need the new capability `customers:read:identity` (or `customers:read`),
|
|
130
|
+
declared by the operation, and are refused at an install that pairs no
|
|
131
|
+
sign-in. Reading or writing a model is no longer what admits them.
|
|
132
|
+
- `install.config()` asks the platform for `customerSignIn`, a field a platform
|
|
133
|
+
older than this release does not have.
|
|
134
|
+
|
|
135
|
+
### Added
|
|
136
|
+
|
|
137
|
+
- `install.config()` answers `customerSignIn`: the key of the customer sign-in
|
|
138
|
+
the install pairs, or `null` when it pairs none.
|
|
139
|
+
|
|
140
|
+
## [0.17.0] — 2026-10-02
|
|
141
|
+
|
|
142
|
+
Published under npm's `next` tag from `dev`, because it reads a field the
|
|
143
|
+
platform serves from the next promotion; `latest` moves to it then.
|
|
144
|
+
|
|
145
|
+
### Added
|
|
146
|
+
|
|
147
|
+
- **An app is told when a project cannot email its customers**
|
|
148
|
+
(`@foir/sdk/app`). A project with no App base URL used to accept a
|
|
149
|
+
notification's email and drop it. The platform now refuses a notification
|
|
150
|
+
that carries an email, and an opt-in to a category confirmed by email, with
|
|
151
|
+
the reason as data. `appCustomerEmailUnavailableOf(error)` reads it:
|
|
152
|
+
`{ reason: 'NO_APP_BASE_URL' }`, or `null` for any other failure.
|
|
153
|
+
- `install.config()` answers `customerEmailUnavailable`: the same reason ahead
|
|
154
|
+
of time, or `null` when the project can send. `AppCustomerEmailUnavailableReason`
|
|
155
|
+
is the type.
|
|
156
|
+
|
|
157
|
+
### Changed
|
|
158
|
+
|
|
159
|
+
- `install.config()` asks the platform for `customerEmailUnavailable`, a field
|
|
160
|
+
a platform older than this release does not have.
|
|
161
|
+
|
|
111
162
|
## [0.16.0] — 2026-10-02
|
|
112
163
|
|
|
113
164
|
Published under npm's `next` tag from `dev`, as 0.15.0 was; `latest` moves to
|
package/dist/app/client.d.ts
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
*/
|
|
29
29
|
import type { FoirDispatchCredential } from '../data/transport';
|
|
30
30
|
import { type FoirRetryPolicy } from '../transport/retry';
|
|
31
|
+
import type { AppCustomerEmailUnavailableReason } from './errors';
|
|
31
32
|
type Json = null | boolean | number | string | Json[] | {
|
|
32
33
|
[key: string]: Json;
|
|
33
34
|
};
|
|
@@ -95,6 +96,21 @@ export interface AppInstallConfig {
|
|
|
95
96
|
settings: JsonObject;
|
|
96
97
|
sources: AppBinding[];
|
|
97
98
|
sinks: AppBinding[];
|
|
99
|
+
/**
|
|
100
|
+
* Why the project cannot send a customer an email at the level this install
|
|
101
|
+
* sits at, or null when it can. While it is set, a notification that carries
|
|
102
|
+
* an email and an opt-in to a category confirmed by email are refused
|
|
103
|
+
* (`appCustomerEmailUnavailableOf`), so say so before one is.
|
|
104
|
+
*/
|
|
105
|
+
customerEmailUnavailable: AppCustomerEmailUnavailableReason | null;
|
|
106
|
+
/**
|
|
107
|
+
* The customer sign-in this install pairs with the app, by key, for an app
|
|
108
|
+
* whose own system has customers; null when it pairs none. Every identity
|
|
109
|
+
* the app names is resolved through it, so while it is null nothing finds a
|
|
110
|
+
* customer by identity: `customers.byIdentity` and `customers.identities`
|
|
111
|
+
* are refused, and an operation that needs them is not registered.
|
|
112
|
+
*/
|
|
113
|
+
customerSignIn: string | null;
|
|
98
114
|
}
|
|
99
115
|
/**
|
|
100
116
|
* The status an install reports. Leaving out `subscriptionHealth`,
|
|
@@ -370,12 +386,6 @@ export interface AppClient {
|
|
|
370
386
|
* else is attached to them. Needs `customers:write` as well.
|
|
371
387
|
*/
|
|
372
388
|
erase(model: string, identity: string): Promise<AppCustomerEraseResult>;
|
|
373
|
-
/**
|
|
374
|
-
* The other direction: the identities a customer the app names by id
|
|
375
|
-
* signs in with there, most recently seen first. Empty when they sign in
|
|
376
|
-
* with none. For an app acting on an event that names the Foir customer.
|
|
377
|
-
*/
|
|
378
|
-
identities(model: string, customerId: string): Promise<string[]>;
|
|
379
389
|
};
|
|
380
390
|
};
|
|
381
391
|
customers: {
|
|
@@ -407,6 +417,23 @@ export interface AppClient {
|
|
|
407
417
|
* `customers:read`.
|
|
408
418
|
*/
|
|
409
419
|
byEmail(email: string): Promise<AppCustomer | null>;
|
|
420
|
+
/**
|
|
421
|
+
* The id of the customer who holds this identity at the app's own system,
|
|
422
|
+
* or null when nobody does: for an app hearing from its system about one
|
|
423
|
+
* of its customers. The identity is the subject of the customer's sign-in
|
|
424
|
+
* with that system, and it is resolved through the customer sign-in the
|
|
425
|
+
* install pairs (`install.config().customerSignIn`) and no other. Never
|
|
426
|
+
* matched by email. Needs `customers:read:identity`, or `customers:read`.
|
|
427
|
+
*/
|
|
428
|
+
byIdentity(identity: string): Promise<string | null>;
|
|
429
|
+
/**
|
|
430
|
+
* The other direction: the identities a customer the app names by id
|
|
431
|
+
* holds at the app's own system, most recently seen first, through the
|
|
432
|
+
* same pairing. Empty when they have never signed in that way. For an app
|
|
433
|
+
* acting on an event that names the Foir customer. Needs
|
|
434
|
+
* `customers:read:identity`, or `customers:read`.
|
|
435
|
+
*/
|
|
436
|
+
identities(customerId: string): Promise<string[]>;
|
|
410
437
|
/**
|
|
411
438
|
* The customers at the install's level, a page at a time, newest first.
|
|
412
439
|
* Needs `customers:read`: an operation declaring only
|
|
@@ -117,6 +117,14 @@ export declare type AppConfig = Message<"apps.v1.AppConfig"> & {
|
|
|
117
117
|
* @generated from field: repeated apps.v1.Feature features = 13;
|
|
118
118
|
*/
|
|
119
119
|
features: Feature[];
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* OPTIONAL. The app's own system has customers who sign in to it. See
|
|
123
|
+
* CustomerSignIn.
|
|
124
|
+
*
|
|
125
|
+
* @generated from field: apps.v1.CustomerSignIn customer_sign_in = 14;
|
|
126
|
+
*/
|
|
127
|
+
customerSignIn?: CustomerSignIn | undefined;
|
|
120
128
|
};
|
|
121
129
|
|
|
122
130
|
/**
|
|
@@ -125,6 +133,42 @@ export declare type AppConfig = Message<"apps.v1.AppConfig"> & {
|
|
|
125
133
|
*/
|
|
126
134
|
export declare const AppConfigSchema: GenMessage<AppConfig>;
|
|
127
135
|
|
|
136
|
+
/**
|
|
137
|
+
* The app's own system has customers, and the app names each by the subject of
|
|
138
|
+
* their sign-in with that system: a store's customer number, which is also who
|
|
139
|
+
* they are when they sign in to the project through the store's sign-in.
|
|
140
|
+
*
|
|
141
|
+
* Declaring it lets an install pair ONE of the project's customer sign-ins with
|
|
142
|
+
* the app (ConfirmInstallAppRequest.customer_sign_in): the operator says which
|
|
143
|
+
* sign-in the app's customers come through, and the platform resolves every
|
|
144
|
+
* identity the app names through that sign-in and no other. The pairing is the
|
|
145
|
+
* operator's, never inferred: the install knows the external account it
|
|
146
|
+
* connects, not which of the project's sign-ins its customers use, and a wrong
|
|
147
|
+
* pairing would attach one person's data to another.
|
|
148
|
+
*
|
|
149
|
+
* The pairing is optional. What needs it says so, and cannot be on without it:
|
|
150
|
+
* a source that names its customers by identity (SourceType.identity), a
|
|
151
|
+
* feature that finds customers through it (Feature.customer_sign_in), and an
|
|
152
|
+
* operation that asks who holds an identity (customers:read:identity).
|
|
153
|
+
*
|
|
154
|
+
* @generated from message apps.v1.CustomerSignIn
|
|
155
|
+
*/
|
|
156
|
+
export declare type CustomerSignIn = Message<"apps.v1.CustomerSignIn"> & {
|
|
157
|
+
/**
|
|
158
|
+
* What the setup tells the operator they are choosing, in a sentence: which
|
|
159
|
+
* customers these are and what identifies them.
|
|
160
|
+
*
|
|
161
|
+
* @generated from field: string description = 1;
|
|
162
|
+
*/
|
|
163
|
+
description: string;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Describes the message apps.v1.CustomerSignIn.
|
|
168
|
+
* Use `create(CustomerSignInSchema)` to create a new message.
|
|
169
|
+
*/
|
|
170
|
+
export declare const CustomerSignInSchema: GenMessage<CustomerSignIn>;
|
|
171
|
+
|
|
128
172
|
/**
|
|
129
173
|
* A feature of the app: something the operator turns on or off as a whole at
|
|
130
174
|
* setup, such as a store's preorders or its back-in-stock alerts.
|
|
@@ -180,6 +224,16 @@ export declare type Feature = Message<"apps.v1.Feature"> & {
|
|
|
180
224
|
* @generated from field: repeated string sources = 5;
|
|
181
225
|
*/
|
|
182
226
|
sources: string[];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The feature finds customers through the install's customer sign-in
|
|
230
|
+
* (AppConfig.customer_sign_in), which the manifest must declare. It cannot
|
|
231
|
+
* be on at an install that pairs none: the setup asks for the sign-in at the
|
|
232
|
+
* switch, and the platform refuses the switch without one.
|
|
233
|
+
*
|
|
234
|
+
* @generated from field: bool customer_sign_in = 6;
|
|
235
|
+
*/
|
|
236
|
+
customerSignIn: boolean;
|
|
183
237
|
};
|
|
184
238
|
|
|
185
239
|
/**
|
|
@@ -586,10 +640,11 @@ export declare type SourceType = Message<"apps.v1.SourceType"> & {
|
|
|
586
640
|
*
|
|
587
641
|
* It is what lets a sync write customer-owned rows. The platform resolves the
|
|
588
642
|
* value to a Foir customer through the customer sign-in the install pairs
|
|
589
|
-
* with the
|
|
590
|
-
* the customer who signs in with that
|
|
591
|
-
* customer holds one row of the source,
|
|
592
|
-
* natural key; the customer is the key.
|
|
643
|
+
* with the app (AppConfig.customer_sign_in, which the manifest must then
|
|
644
|
+
* declare), at the install's level: the customer who signs in with that
|
|
645
|
+
* identity, or one made for it. Each customer holds one row of the source,
|
|
646
|
+
* their profile, so the source has no natural key; the customer is the key.
|
|
647
|
+
* Never matched by email.
|
|
593
648
|
*
|
|
594
649
|
* @generated from field: string identity = 10;
|
|
595
650
|
*/
|
|
@@ -1429,6 +1484,18 @@ export enum ManifestCapability {
|
|
|
1429
1484
|
*/
|
|
1430
1485
|
CUSTOMERS_READ_NAMED = 15,
|
|
1431
1486
|
|
|
1487
|
+
/**
|
|
1488
|
+
* The link between a customer and who they are at the app's own system, and
|
|
1489
|
+
* nothing else about them: the customer who holds an identity, and the
|
|
1490
|
+
* identities a customer the operation names by id holds, both through the
|
|
1491
|
+
* customer sign-in the install pairs with the app and no other. An operation
|
|
1492
|
+
* that declares customers:read holds it too; customers:read:named does not
|
|
1493
|
+
* reach it, nor it what that reaches.
|
|
1494
|
+
*
|
|
1495
|
+
* @generated from enum value: MANIFEST_CAPABILITY_CUSTOMERS_READ_IDENTITY = 16;
|
|
1496
|
+
*/
|
|
1497
|
+
CUSTOMERS_READ_IDENTITY = 16,
|
|
1498
|
+
|
|
1432
1499
|
/**
|
|
1433
1500
|
* Reporting an ASYNC run's outcome.
|
|
1434
1501
|
*
|
package/dist/app/errors.d.ts
CHANGED
|
@@ -34,6 +34,26 @@ export declare function appCustomerUnlinkedOf(error: unknown): {
|
|
|
34
34
|
model: string;
|
|
35
35
|
identityProvider: string;
|
|
36
36
|
} | null;
|
|
37
|
+
/**
|
|
38
|
+
* Why a project cannot send a customer an email. `NO_APP_BASE_URL`: no App base
|
|
39
|
+
* URL is set for the project, or for the customer's organization. A reason
|
|
40
|
+
* this build does not know arrives as the platform spelled it.
|
|
41
|
+
*/
|
|
42
|
+
export type AppCustomerEmailUnavailableReason = 'NO_APP_BASE_URL' | (string & {});
|
|
43
|
+
/** The reason as the platform sent it, or null when it sent none. */
|
|
44
|
+
export declare function customerEmailUnavailableReasonOf(value: unknown): AppCustomerEmailUnavailableReason | null;
|
|
45
|
+
/**
|
|
46
|
+
* A request refused because it would send a customer an email the project
|
|
47
|
+
* cannot send, or null for any other failure. Nothing was written and nothing
|
|
48
|
+
* was queued. An opt-in to a category confirmed by email is refused this way,
|
|
49
|
+
* and so is a notification that carries an email.
|
|
50
|
+
*
|
|
51
|
+
* It is about the project, not the customer: the project's operator fixes it,
|
|
52
|
+
* and the same request goes once they have.
|
|
53
|
+
*/
|
|
54
|
+
export declare function appCustomerEmailUnavailableOf(error: unknown): {
|
|
55
|
+
reason: AppCustomerEmailUnavailableReason;
|
|
56
|
+
} | null;
|
|
37
57
|
/**
|
|
38
58
|
* Whether a read failed because the token is not served the field it asked
|
|
39
59
|
* for: the field is not on the schema this token's capabilities reach. That is
|
package/dist/app/index.d.ts
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
*/
|
|
23
23
|
export { createAppClient } from './client';
|
|
24
24
|
export type { AppBinding, AppClient, AppClientConfig, AppConsentChange, AppCustomer, AppCustomerEraseResult, AppCustomerList, AppCustomerSaveResult, AppFieldMapping, AppInstallConfig, AppNotification, AppOperationStart, AppRecord, AppRecordList, AppStartedOperation, AppStatusReport, AppSyncDirection, AppUpsertResult, AppWhoami, } from './client';
|
|
25
|
-
export { appCustomerUnlinkedOf, appLookupConflictOf, isAppFieldWithheld } from './errors';
|
|
26
|
-
export type { AppLookupConflict } from './errors';
|
|
25
|
+
export { appCustomerEmailUnavailableOf, appCustomerUnlinkedOf, appLookupConflictOf, isAppFieldWithheld } from './errors';
|
|
26
|
+
export type { AppCustomerEmailUnavailableReason, AppLookupConflict } from './errors';
|
|
27
27
|
export { appModelFieldName, appModelTypeName, appSelectorEnumValue } from './naming';
|
|
28
28
|
export { RECORD_KEY_RULE, recordKeyRefusal } from './record-key';
|
|
29
29
|
export { readAppDispatch, readCredentialProbe } from './dispatch';
|
|
@@ -7,7 +7,7 @@ export declare const APP_HOOK_EVENTS: readonly ["RECORD_CREATED", "RECORD_UPDATE
|
|
|
7
7
|
/** An event a hook can name. */
|
|
8
8
|
export type AppHookEvent = (typeof APP_HOOK_EVENTS)[number];
|
|
9
9
|
/** The capabilities an operation declares as written. */
|
|
10
|
-
export declare const APP_CAPABILITIES: readonly ["config:read", "secrets:read.app", "secrets:put.app", "secrets:list.app", "secrets:delete.app", "status:write", "files:read", "files:list", "files:write", "customers:write", "notifications:write", "notifications:consent", "customers:read", "customers:read:named", "operations:complete"];
|
|
10
|
+
export declare const APP_CAPABILITIES: readonly ["config:read", "secrets:read.app", "secrets:put.app", "secrets:list.app", "secrets:delete.app", "status:write", "files:read", "files:list", "files:write", "customers:write", "notifications:write", "notifications:consent", "customers:read", "customers:read:named", "customers:read:identity", "operations:complete"];
|
|
11
11
|
/** A capability an operation declares as written. */
|
|
12
12
|
export type AppCapability = (typeof APP_CAPABILITIES)[number];
|
|
13
13
|
/**
|
package/dist/app-contract.js
CHANGED
|
@@ -8,30 +8,31 @@ var file_buf_validate_validate = /* @__PURE__ */ fileDesc("ChtidWYvdmFsaWRhdGUvd
|
|
|
8
8
|
|
|
9
9
|
// ../proto-ts/src/apps/v1/apps_pb.js
|
|
10
10
|
import { file_google_protobuf_descriptor as file_google_protobuf_descriptor2, file_google_protobuf_struct } from "@bufbuild/protobuf/wkt";
|
|
11
|
-
var file_apps_v1_apps = /* @__PURE__ */ fileDesc2("
|
|
11
|
+
var file_apps_v1_apps = /* @__PURE__ */ fileDesc2("ChJhcHBzL3YxL2FwcHMucHJvdG8SB2FwcHMudjEiyQUKCUFwcENvbmZpZxI0CgRuYW1lGAEgASgJQia6SCNyIRhAMh1eW2Etel1bYS16MC05XSooLVthLXowLTldKykqJBIYCgd2ZXJzaW9uGAIgASgJQge6SARyAhABEiMKCG1ldGFkYXRhGAMgASgLMhEuYXBwcy52MS5NZXRhZGF0YRInCgptaWRkbGV3YXJlGAQgASgLMhMuYXBwcy52MS5NaWRkbGV3YXJlEikKC2NyZWRlbnRpYWxzGAUgASgLMhQuYXBwcy52MS5DcmVkZW50aWFscxIwCg9zZXR0aW5nc19zY2hlbWEYBiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKB3NvdXJjZXMYByADKAsyHy5hcHBzLnYxLkFwcENvbmZpZy5Tb3VyY2VzRW50cnkSLAoFc2lua3MYCCADKAsyHS5hcHBzLnYxLkFwcENvbmZpZy5TaW5rc0VudHJ5EiYKCm9wZXJhdGlvbnMYCSADKAsyEi5hcHBzLnYxLk9wZXJhdGlvbhIcCgVob29rcxgKIAMoCzINLmFwcHMudjEuSG9vaxIXCgJ1aRgLIAEoCzILLmFwcHMudjEuVUkSIQoHaW5ib3VuZBgMIAEoCzIQLmFwcHMudjEuSW5ib3VuZBIiCghmZWF0dXJlcxgNIAMoCzIQLmFwcHMudjEuRmVhdHVyZRIxChBjdXN0b21lcl9zaWduX2luGA4gASgLMhcuYXBwcy52MS5DdXN0b21lclNpZ25JbhpDCgxTb3VyY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMuYXBwcy52MS5Tb3VyY2VUeXBlOgI4ARpDCgpTaW5rc0VudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLmFwcHMudjEuU2lua0NvbnRyYWN0OgI4ASIlCg5DdXN0b21lclNpZ25JbhITCgtkZXNjcmlwdGlvbhgBIAEoCSKnAQoHRmVhdHVyZRIzCgNrZXkYASABKAlCJrpII3IhGEAyHV5bYS16XVthLXowLTldKigtW2EtejAtOV0rKSokEhYKBXRpdGxlGAIgASgJQge6SARyAhABEhMKC2Rlc2NyaXB0aW9uGAMgASgJEg8KB3NldHRpbmcYBCABKAkSDwoHc291cmNlcxgFIAMoCRIYChBjdXN0b21lcl9zaWduX2luGAYgASgIImUKCE1ldGFkYXRhEhQKDGRpc3BsYXlfbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIMCgRpY29uGAMgASgJEg4KBmF1dGhvchgEIAEoCRIQCghob21lcGFnZRgFIAEoCSItCgpNaWRkbGV3YXJlEh8KA3VybBgBIAEoCUISukgPcg0yC15odHRwczovLy4rItcCCgtDcmVkZW50aWFscxIvCghzdHJhdGVneRgBIAEoDjIdLmFwcHMudjEuQ3JlZGVudGlhbHMuU3RyYXRlZ3kSLAoGc2NoZW1hGAIgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgAiAEBEigKBW9hdXRoGAMgASgLMhQuYXBwcy52MS5PQXV0aENvbmZpZ0gBiAEBIqkBCghTdHJhdGVneRIYChRTVFJBVEVHWV9VTlNQRUNJRklFRBAAEhIKDlNUUkFURUdZX09BVVRIEAESFAoQU1RSQVRFR1lfQVBJX0tFWRACEhoKFlNUUkFURUdZX1NIQVJFRF9TRUNSRVQQAxIUChBTVFJBVEVHWV9TU0hfS0VZEAQSEQoNU1RSQVRFR1lfTk9ORRAFEhQKEFNUUkFURUdZX01BTkFHRUQQBkIJCgdfc2NoZW1hQggKBl9vYXV0aCJMCgtPQXV0aENvbmZpZxIcChRhdXRob3JpemVfc3RhcnRfcGF0aBgBIAEoCRIfChdhdXRob3JpemVfY2FsbGJhY2tfcGF0aBgCIAEoCSJWCgdJbmJvdW5kEiEKB3dlYmhvb2sYASABKAsyEC5hcHBzLnYxLldlYmhvb2sSKAoHYWNjb3VudBgCIAEoCzIXLmFwcHMudjEuQWNjb3VudFdlYmhvb2siFwoHV2ViaG9vaxIMCgRwYXRoGAEgASgJIj8KDkFjY291bnRXZWJob29rEgwKBHBhdGgYASABKAkSDwoHc2V0dGluZxgCIAEoCRIOCgZzb3VyY2UYAyABKAki3QIKClNvdXJjZVR5cGUSDQoFbGFiZWwYASABKAkSLwoGZmllbGRzGAIgAygLMh8uYXBwcy52MS5Tb3VyY2VUeXBlLkZpZWxkc0VudHJ5EhMKC25hdHVyYWxfa2V5GAMgASgJEhAKCG9wdGlvbmFsGAQgASgIEhYKDnByb3Zpc2lvbl9vbmx5GAUgASgIEisKCXJlZmVyZW5jZRgGIAEoCzIYLmFwcHMudjEuU291cmNlUmVmZXJlbmNlEiQKBW93bmVyGAcgASgOMhUuYXBwcy52MS5TdG9yYWdlT3duZXISEwoLcmVjb21tZW5kZWQYCCABKAgSDgoGbG9va3VwGAkgAygJEhAKCGlkZW50aXR5GAogASgJGkYKC0ZpZWxkc0VudHJ5EgsKA2tleRgBIAEoCRImCgV2YWx1ZRgCIAEoCzIXLmFwcHMudjEuU3VnZ2VzdGVkRmllbGQ6AjgBIqoCCg9Tb3VyY2VSZWZlcmVuY2USEQoJa2V5X2ZpZWxkGAEgASgJEjQKBmZpZWxkcxgCIAMoCzIkLmFwcHMudjEuU291cmNlUmVmZXJlbmNlLkZpZWxkc0VudHJ5EhAKCGVuZHBvaW50GAMgASgJEg0KBWhvc3RzGAQgAygJEioKB3JlcXVlc3QYBSABKAsyGS5hcHBzLnYxLlJlZmVyZW5jZVJlcXVlc3QSGgoScmVzcG9uc2VfdHJhbnNmb3JtGAYgASgJEh0KFWNhY2hlX21heF9hZ2Vfc2Vjb25kcxgHIAEoBRpGCgtGaWVsZHNFbnRyeRILCgNrZXkYASABKAkSJgoFdmFsdWUYAiABKAsyFy5hcHBzLnYxLlN1Z2dlc3RlZEZpZWxkOgI4ASKzAgoQUmVmZXJlbmNlUmVxdWVzdBIOCgZtZXRob2QYASABKAkSFQoNcGF0aF90ZW1wbGF0ZRgCIAEoCRIzCgVxdWVyeRgDIAMoCzIkLmFwcHMudjEuUmVmZXJlbmNlUmVxdWVzdC5RdWVyeUVudHJ5EjcKB2hlYWRlcnMYBCADKAsyJi5hcHBzLnYxLlJlZmVyZW5jZVJlcXVlc3QuSGVhZGVyc0VudHJ5EhUKDWJvZHlfdGVtcGxhdGUYBSABKAkSFQoNYmF0Y2hfY2FwYWJsZRgGIAEoCBosCgpRdWVyeUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaLgoMSGVhZGVyc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiugEKDFNpbmtDb250cmFjdBINCgVsYWJlbBgBIAEoCRIxCgZmaWVsZHMYAiADKAsyIS5hcHBzLnYxLlNpbmtDb250cmFjdC5GaWVsZHNFbnRyeRITCgtuYXR1cmFsX2tleRgDIAEoCRIQCghvcHRpb25hbBgEIAEoCBpBCgtGaWVsZHNFbnRyeRILCgNrZXkYASABKAkSIQoFdmFsdWUYAiABKAsyEi5hcHBzLnYxLlNpbmtGaWVsZDoCOAEilgIKDlN1Z2dlc3RlZEZpZWxkEgwKBHR5cGUYASABKAkSEgoFbGFiZWwYAiABKAlIAIgBARIVCghyZXF1aXJlZBgDIAEoCEgBiAEBEiwKBmNvbmZpZxgEIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIAogBARI9ChNzdXBwb3J0ZWRfZGlyZWN0aW9uGAUgASgOMhsuYXBwcy52MS5GaWVsZFN5bmNEaXJlY3Rpb25IA4gBARIWCglxdWVyeWFibGUYBiABKAhIBIgBAUIICgZfbGFiZWxCCwoJX3JlcXVpcmVkQgkKB19jb25maWdCFgoUX3N1cHBvcnRlZF9kaXJlY3Rpb25CDAoKX3F1ZXJ5YWJsZSJbCglTaW5rRmllbGQSDAoEdHlwZRgBIAEoCRIQCghzZW1hbnRpYxgCIAEoCRIQCghyZXF1aXJlZBgDIAEoCBISCgVsYWJlbBgEIAEoCUgAiAEBQggKBl9sYWJlbCKYBAoJT3BlcmF0aW9uEjoKA2tleRgBIAEoCUItukgqcigYQDIkXihfXyk/W2Etel1bYS16MC05X10qKC1bYS16MC05X10rKSokEgwKBG5hbWUYAiABKAkSGAoLZGVzY3JpcHRpb24YAyABKAlIAIgBARIdCghlbmRwb2ludBgEIAEoCUILukgIcgYyBF4vLioSFAoMY2FwYWJpbGl0aWVzGAUgAygJEhcKCnRpbWVvdXRfbXMYBiABKAVIAYgBARIyCgxyZXRyeV9wb2xpY3kYByABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0SAKIAQESMgoMaW5wdXRfc2NoZW1hGAggASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgDiAEBEjMKDW91dHB1dF9zY2hlbWEYCSABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0SASIAQESGwoOc3VwcG9ydHNfYXN5bmMYCiABKAhIBYgBARIZChFydW5fYWZ0ZXJfaW5zdGFsbBgLIAEoCBIeChZydW5zX29uX21hcHBlZF9zb3VyY2VzGAwgASgIQg4KDF9kZXNjcmlwdGlvbkINCgtfdGltZW91dF9tc0IPCg1fcmV0cnlfcG9saWN5Qg8KDV9pbnB1dF9zY2hlbWFCEAoOX291dHB1dF9zY2hlbWFCEQoPX3N1cHBvcnRzX2FzeW5jIj0KFk1hbmlmZXN0Q2FwYWJpbGl0eVNwZWMSEAoIZGVjbGFyZXMYASABKAkSEQoJcGVyX21vZGVsGAIgASgIIqYBCgRIb29rEjMKA2tleRgBIAEoCUImukgjciEYQDIdXlthLXpdW2EtejAtOV0qKC1bYS16MC05XSspKiQSDAoEbmFtZRgCIAEoCRIWCgVldmVudBgDIAEoCUIHukgEcgIQARInCgZmaWx0ZXIYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EhoKCW9wZXJhdGlvbhgFIAEoCUIHukgEcgIQASI3CgJVSRIxCgpwbGFjZW1lbnRzGAEgAygLMh0uYXBwcy52MS5QbGFjZW1lbnREZWNsYXJhdGlvbiK2BAoUUGxhY2VtZW50RGVjbGFyYXRpb24SMwoDa2V5GAEgASgJQia6SCNyIRhAMh1eW2Etel1bYS16MC05XSooLVthLXowLTldKykqJBI0CgZ0YXJnZXQYAiABKA4yJC5hcHBzLnYxLlBsYWNlbWVudERlY2xhcmF0aW9uLlRhcmdldBISCgVtb2RlbBgDIAEoCUgAiAEBEhIKBWZpZWxkGAQgASgJSAGIAQESIQoZZmllbGRfc2VsZWN0ZWRfYXRfaW5zdGFsbBgFIAEoCBIQCgN0YWIYBiABKAlIAogBARIWCgV0aXRsZRgHIAEoCUIHukgEcgIQARIfCgN1cmwYCCABKAlCErpID3INMgteaHR0cHM6Ly8uKxIdChByZXBsYWNlc19kZWZhdWx0GAkgASgISAOIAQESKwoFaGludHMYCiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0SASIAQESDgoGc2NvcGVzGAsgAygJEhAKCHNldHRpbmdzGAwgAygJInQKBlRhcmdldBIWChJUQVJHRVRfVU5TUEVDSUZJRUQQABIUChBUQVJHRVRfRlVMTF9QQUdFEAESFgoSVEFSR0VUX01BSU5fRURJVE9SEAISEgoOVEFSR0VUX1NJREVCQVIQAxIQCgxUQVJHRVRfRklFTEQQBEIICgZfbW9kZWxCCAoGX2ZpZWxkQgYKBF90YWJCEwoRX3JlcGxhY2VzX2RlZmF1bHRCCAoGX2hpbnRzKqwBChJGaWVsZFN5bmNEaXJlY3Rpb24SJAogRklFTERfU1lOQ19ESVJFQ1RJT05fVU5TUEVDSUZJRUQQABIkCiBGSUVMRF9TWU5DX0RJUkVDVElPTl9TT1VSQ0VfT05MWRABEiIKHkZJRUxEX1NZTkNfRElSRUNUSU9OX1NJTktfT05MWRACEiYKIkZJRUxEX1NZTkNfRElSRUNUSU9OX0JJRElSRUNUSU9OQUwQAyqEAQoMU3RvcmFnZU93bmVyEh0KGVNUT1JBR0VfT1dORVJfVU5TUEVDSUZJRUQQABIZChVTVE9SQUdFX09XTkVSX1BST0pFQ1QQARIeChpTVE9SQUdFX09XTkVSX09SR0FOSVpBVElPThACEhoKFlNUT1JBR0VfT1dORVJfQ1VTVE9NRVIQAyqUCwoSTWFuaWZlc3RDYXBhYmlsaXR5EiMKH01BTklGRVNUX0NBUEFCSUxJVFlfVU5TUEVDSUZJRUQQABI2Ch9NQU5JRkVTVF9DQVBBQklMSVRZX0NPTkZJR19SRUFEEAEaEZqmHQ0KC2NvbmZpZzpyZWFkEkAKJE1BTklGRVNUX0NBUEFCSUxJVFlfU0VDUkVUU19SRUFEX0FQUBACGhaaph0SChBzZWNyZXRzOnJlYWQuYXBwEj4KI01BTklGRVNUX0NBUEFCSUxJVFlfU0VDUkVUU19QVVRfQVBQEAMaFZqmHREKD3NlY3JldHM6cHV0LmFwcBJACiRNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfTElTVF9BUFAQBBoWmqYdEgoQc2VjcmV0czpsaXN0LmFwcBJECiZNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfREVMRVRFX0FQUBAFGhiaph0UChJzZWNyZXRzOmRlbGV0ZS5hcHASOAogTUFOSUZFU1RfQ0FQQUJJTElUWV9TVEFUVVNfV1JJVEUQBhoSmqYdDgoMc3RhdHVzOndyaXRlEjQKHk1BTklGRVNUX0NBUEFCSUxJVFlfRklMRVNfUkVBRBAHGhCaph0MCgpmaWxlczpyZWFkEjQKHk1BTklGRVNUX0NBUEFCSUxJVFlfRklMRVNfTElTVBAIGhCaph0MCgpmaWxlczpsaXN0EjYKH01BTklGRVNUX0NBUEFCSUxJVFlfRklMRVNfV1JJVEUQCRoRmqYdDQoLZmlsZXM6d3JpdGUSPgojTUFOSUZFU1RfQ0FQQUJJTElUWV9DVVNUT01FUlNfV1JJVEUQChoVmqYdEQoPY3VzdG9tZXJzOndyaXRlEkYKJ01BTklGRVNUX0NBUEFCSUxJVFlfTk9USUZJQ0FUSU9OU19XUklURRALGhmaph0VChNub3RpZmljYXRpb25zOndyaXRlEkoKKU1BTklGRVNUX0NBUEFCSUxJVFlfTk9USUZJQ0FUSU9OU19DT05TRU5UEAwaG5qmHRcKFW5vdGlmaWNhdGlvbnM6Y29uc2VudBI8CiJNQU5JRkVTVF9DQVBBQklMSVRZX0NVU1RPTUVSU19SRUFEEA4aFJqmHRAKDmN1c3RvbWVyczpyZWFkEkgKKE1BTklGRVNUX0NBUEFCSUxJVFlfQ1VTVE9NRVJTX1JFQURfTkFNRUQQDxoamqYdFgoUY3VzdG9tZXJzOnJlYWQ6bmFtZWQSTgorTUFOSUZFU1RfQ0FQQUJJTElUWV9DVVNUT01FUlNfUkVBRF9JREVOVElUWRAQGh2aph0ZChdjdXN0b21lcnM6cmVhZDppZGVudGl0eRJGCidNQU5JRkVTVF9DQVBBQklMSVRZX09QRVJBVElPTlNfQ09NUExFVEUQDRoZmqYdFQoTb3BlcmF0aW9uczpjb21wbGV0ZRI7CiBNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfUkVBRBAUGhWaph0RCg1yZWNvcmRzOnJlYWQ6EAESPQohTUFOSUZFU1RfQ0FQQUJJTElUWV9SRUNPUkRTX1dSSVRFEBUaFpqmHRIKDnJlY29yZHM6d3JpdGU6EAESPwoiTUFOSUZFU1RfQ0FQQUJJTElUWV9SRUNPUkRTX0RFTEVURRAWGheaph0TCg9yZWNvcmRzOmRlbGV0ZToQARJBCiNNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfUFVCTElTSBAXGhiaph0UChByZWNvcmRzOnB1Ymxpc2g6EAESRQolTUFOSUZFU1RfQ0FQQUJJTElUWV9SRUNPUkRTX0FUVFJJQlVURRAYGhqaph0WChJyZWNvcmRzOmF0dHJpYnV0ZToQATp1ChNtYW5pZmVzdF9jYXBhYmlsaXR5EiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY49QDIAEoCzIfLmFwcHMudjEuTWFuaWZlc3RDYXBhYmlsaXR5U3BlY1ISbWFuaWZlc3RDYXBhYmlsaXR5QjVaM2dpdGh1Yi5jb20vZWlkZXN0dWRpby9mb2lyL2dlbi9wcm90by9hcHBzL3YxO2FwcHN2MWIGcHJvdG8z", [file_buf_validate_validate, file_google_protobuf_descriptor2, file_google_protobuf_struct]);
|
|
12
12
|
var AppConfigSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 0);
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var
|
|
13
|
+
var CustomerSignInSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 1);
|
|
14
|
+
var FeatureSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 2);
|
|
15
|
+
var MetadataSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 3);
|
|
16
|
+
var MiddlewareSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 4);
|
|
17
|
+
var CredentialsSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 5);
|
|
18
|
+
var Credentials_StrategySchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps, 5, 0);
|
|
18
19
|
var Credentials_Strategy = /* @__PURE__ */ tsEnum2(Credentials_StrategySchema);
|
|
19
|
-
var OAuthConfigSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
20
|
-
var InboundSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
21
|
-
var WebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
22
|
-
var AccountWebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
23
|
-
var SourceTypeSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
24
|
-
var SourceReferenceSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
25
|
-
var ReferenceRequestSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
26
|
-
var SinkContractSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
27
|
-
var SuggestedFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
28
|
-
var SinkFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
29
|
-
var OperationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
30
|
-
var ManifestCapabilitySpecSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
31
|
-
var HookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
32
|
-
var UISchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
33
|
-
var PlacementDeclarationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps,
|
|
34
|
-
var PlacementDeclaration_TargetSchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps,
|
|
20
|
+
var OAuthConfigSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 6);
|
|
21
|
+
var InboundSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 7);
|
|
22
|
+
var WebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 8);
|
|
23
|
+
var AccountWebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 9);
|
|
24
|
+
var SourceTypeSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 10);
|
|
25
|
+
var SourceReferenceSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 11);
|
|
26
|
+
var ReferenceRequestSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 12);
|
|
27
|
+
var SinkContractSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 13);
|
|
28
|
+
var SuggestedFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 14);
|
|
29
|
+
var SinkFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 15);
|
|
30
|
+
var OperationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 16);
|
|
31
|
+
var ManifestCapabilitySpecSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 17);
|
|
32
|
+
var HookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 18);
|
|
33
|
+
var UISchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 19);
|
|
34
|
+
var PlacementDeclarationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 20);
|
|
35
|
+
var PlacementDeclaration_TargetSchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps, 20, 0);
|
|
35
36
|
var PlacementDeclaration_Target = /* @__PURE__ */ tsEnum2(PlacementDeclaration_TargetSchema);
|
|
36
37
|
var FieldSyncDirectionSchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps, 0);
|
|
37
38
|
var FieldSyncDirection = /* @__PURE__ */ tsEnum2(FieldSyncDirectionSchema);
|
|
@@ -75,6 +76,7 @@ export {
|
|
|
75
76
|
CredentialsSchema,
|
|
76
77
|
Credentials_Strategy,
|
|
77
78
|
Credentials_StrategySchema,
|
|
79
|
+
CustomerSignInSchema,
|
|
78
80
|
DiscoveredAccountSchema,
|
|
79
81
|
DiscoveredCountSchema,
|
|
80
82
|
DiscoveredFieldGroupSchema,
|
package/dist/app.js
CHANGED
|
@@ -251,6 +251,13 @@ function appCustomerUnlinkedOf(error) {
|
|
|
251
251
|
if (typeof model !== "string" || typeof identityProvider !== "string") return null;
|
|
252
252
|
return { model, identityProvider };
|
|
253
253
|
}
|
|
254
|
+
function customerEmailUnavailableReasonOf(value) {
|
|
255
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
256
|
+
}
|
|
257
|
+
function appCustomerEmailUnavailableOf(error) {
|
|
258
|
+
const reason = customerEmailUnavailableReasonOf(extensionOf(error, "customerEmailUnavailable")?.reason);
|
|
259
|
+
return reason ? { reason } : null;
|
|
260
|
+
}
|
|
254
261
|
function isAppFieldWithheld(error, field) {
|
|
255
262
|
if (!(error instanceof FoirRequestError)) return false;
|
|
256
263
|
return (error.prunedSelections ?? []).some((selection) => {
|
|
@@ -490,7 +497,7 @@ function createAppClient(config) {
|
|
|
490
497
|
"integrationConfig",
|
|
491
498
|
`query AppInstallConfig {
|
|
492
499
|
integrationConfig {
|
|
493
|
-
name enabled middlewareUrl targetModels webhookUrl config
|
|
500
|
+
name enabled middlewareUrl targetModels webhookUrl config customerEmailUnavailable customerSignIn
|
|
494
501
|
sources { key model naturalKey mode fields { appField modelField direction } }
|
|
495
502
|
sinks { key model naturalKey fields { appField modelField direction } }
|
|
496
503
|
}
|
|
@@ -506,7 +513,9 @@ function createAppClient(config) {
|
|
|
506
513
|
webhookUrl: got.webhookUrl ?? "",
|
|
507
514
|
settings: got.config ?? {},
|
|
508
515
|
sources: bindingsOf(got.sources),
|
|
509
|
-
sinks: bindingsOf(got.sinks)
|
|
516
|
+
sinks: bindingsOf(got.sinks),
|
|
517
|
+
customerEmailUnavailable: customerEmailUnavailableReasonOf(got.customerEmailUnavailable),
|
|
518
|
+
customerSignIn: typeof got.customerSignIn === "string" && got.customerSignIn !== "" ? got.customerSignIn : null
|
|
510
519
|
};
|
|
511
520
|
},
|
|
512
521
|
async credentials() {
|
|
@@ -724,16 +733,6 @@ function createAppClient(config) {
|
|
|
724
733
|
customerDeleted: answer.customerDeleted === true,
|
|
725
734
|
customerKeptBecause: answer.customerKeptBecause ?? null
|
|
726
735
|
};
|
|
727
|
-
},
|
|
728
|
-
async identities(model, customerId) {
|
|
729
|
-
if (customerId === "") refuse(`a customer's identities on ${model} were asked for with no customer`);
|
|
730
|
-
const answer = await field(
|
|
731
|
-
"customerIdentitiesById",
|
|
732
|
-
`query AppCustomerIdentities($modelKey: String!, $customerId: ID!) { customerIdentitiesById(modelKey: $modelKey, customerId: $customerId) }`,
|
|
733
|
-
{ modelKey: model, customerId }
|
|
734
|
-
);
|
|
735
|
-
if (!Array.isArray(answer)) return refuse(`customerIdentitiesById reported no error and returned no list on ${model}`);
|
|
736
|
-
return answer.filter((identity) => typeof identity === "string");
|
|
737
736
|
}
|
|
738
737
|
}
|
|
739
738
|
},
|
|
@@ -768,6 +767,25 @@ function createAppClient(config) {
|
|
|
768
767
|
);
|
|
769
768
|
return customerOf(customer);
|
|
770
769
|
},
|
|
770
|
+
async byIdentity(identity) {
|
|
771
|
+
if (identity === "") refuse("a customer was asked for with no identity");
|
|
772
|
+
const answer = await field(
|
|
773
|
+
"customerByIdentity",
|
|
774
|
+
`query AppCustomerByIdentity($identity: String!) { customerByIdentity(identity: $identity) }`,
|
|
775
|
+
{ identity }
|
|
776
|
+
);
|
|
777
|
+
return typeof answer === "string" && answer !== "" ? answer : null;
|
|
778
|
+
},
|
|
779
|
+
async identities(customerId) {
|
|
780
|
+
if (customerId === "") refuse("a customer's identities were asked for with no customer");
|
|
781
|
+
const answer = await field(
|
|
782
|
+
"customerIdentitiesById",
|
|
783
|
+
`query AppCustomerIdentities($customerId: ID!) { customerIdentitiesById(customerId: $customerId) }`,
|
|
784
|
+
{ customerId }
|
|
785
|
+
);
|
|
786
|
+
if (!Array.isArray(answer)) return refuse("customerIdentitiesById reported no error and returned no list");
|
|
787
|
+
return answer.filter((identity) => typeof identity === "string");
|
|
788
|
+
},
|
|
771
789
|
async list(query = {}) {
|
|
772
790
|
const search = query.search?.trim() ?? "";
|
|
773
791
|
const page = await field(
|
|
@@ -1129,6 +1147,7 @@ var APP_CAPABILITIES = [
|
|
|
1129
1147
|
"notifications:consent",
|
|
1130
1148
|
"customers:read",
|
|
1131
1149
|
"customers:read:named",
|
|
1150
|
+
"customers:read:identity",
|
|
1132
1151
|
"operations:complete"
|
|
1133
1152
|
];
|
|
1134
1153
|
var APP_RECORD_CAPABILITY_PREFIXES = [
|
|
@@ -1145,6 +1164,7 @@ export {
|
|
|
1145
1164
|
FoirRequestError,
|
|
1146
1165
|
MAX_APP_MANIFEST_BYTES,
|
|
1147
1166
|
RECORD_KEY_RULE,
|
|
1167
|
+
appCustomerEmailUnavailableOf,
|
|
1148
1168
|
appCustomerUnlinkedOf,
|
|
1149
1169
|
appLookupConflictOf,
|
|
1150
1170
|
appModelFieldName,
|