@foir/sdk 0.17.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 CHANGED
@@ -108,6 +108,35 @@ 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
+
111
140
  ## [0.17.0] — 2026-10-02
112
141
 
113
142
  Published under npm's `next` tag from `dev`, because it reads a field the
@@ -103,6 +103,14 @@ export interface AppInstallConfig {
103
103
  * (`appCustomerEmailUnavailableOf`), so say so before one is.
104
104
  */
105
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;
106
114
  }
107
115
  /**
108
116
  * The status an install reports. Leaving out `subscriptionHealth`,
@@ -378,12 +386,6 @@ export interface AppClient {
378
386
  * else is attached to them. Needs `customers:write` as well.
379
387
  */
380
388
  erase(model: string, identity: string): Promise<AppCustomerEraseResult>;
381
- /**
382
- * The other direction: the identities a customer the app names by id
383
- * signs in with there, most recently seen first. Empty when they sign in
384
- * with none. For an app acting on an event that names the Foir customer.
385
- */
386
- identities(model: string, customerId: string): Promise<string[]>;
387
389
  };
388
390
  };
389
391
  customers: {
@@ -415,6 +417,23 @@ export interface AppClient {
415
417
  * `customers:read`.
416
418
  */
417
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[]>;
418
437
  /**
419
438
  * The customers at the install's level, a page at a time, newest first.
420
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 source (SourceMapping.identity_provider), at the install's level:
590
- * the customer who signs in with that identity, or one made for it. Each
591
- * customer holds one row of the source, their profile, so the source has no
592
- * natural key; the customer is the key. Never matched by email.
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
  *
@@ -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
  /**
@@ -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("ChJhcHBzL3YxL2FwcHMucHJvdG8SB2FwcHMudjEilgUKCUFwcENvbmZpZxI0CgRuYW1lGAEgASgJQia6SCNyIRhAMh1eW2Etel1bYS16MC05XSooLVthLXowLTldKykqJBIYCgd2ZXJzaW9uGAIgASgJQge6SARyAhABEiMKCG1ldGFkYXRhGAMgASgLMhEuYXBwcy52MS5NZXRhZGF0YRInCgptaWRkbGV3YXJlGAQgASgLMhMuYXBwcy52MS5NaWRkbGV3YXJlEikKC2NyZWRlbnRpYWxzGAUgASgLMhQuYXBwcy52MS5DcmVkZW50aWFscxIwCg9zZXR0aW5nc19zY2hlbWEYBiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKB3NvdXJjZXMYByADKAsyHy5hcHBzLnYxLkFwcENvbmZpZy5Tb3VyY2VzRW50cnkSLAoFc2lua3MYCCADKAsyHS5hcHBzLnYxLkFwcENvbmZpZy5TaW5rc0VudHJ5EiYKCm9wZXJhdGlvbnMYCSADKAsyEi5hcHBzLnYxLk9wZXJhdGlvbhIcCgVob29rcxgKIAMoCzINLmFwcHMudjEuSG9vaxIXCgJ1aRgLIAEoCzILLmFwcHMudjEuVUkSIQoHaW5ib3VuZBgMIAEoCzIQLmFwcHMudjEuSW5ib3VuZBIiCghmZWF0dXJlcxgNIAMoCzIQLmFwcHMudjEuRmVhdHVyZRpDCgxTb3VyY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMuYXBwcy52MS5Tb3VyY2VUeXBlOgI4ARpDCgpTaW5rc0VudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLmFwcHMudjEuU2lua0NvbnRyYWN0OgI4ASKNAQoHRmVhdHVyZRIzCgNrZXkYASABKAlCJrpII3IhGEAyHV5bYS16XVthLXowLTldKigtW2EtejAtOV0rKSokEhYKBXRpdGxlGAIgASgJQge6SARyAhABEhMKC2Rlc2NyaXB0aW9uGAMgASgJEg8KB3NldHRpbmcYBCABKAkSDwoHc291cmNlcxgFIAMoCSJlCghNZXRhZGF0YRIUCgxkaXNwbGF5X25hbWUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSDAoEaWNvbhgDIAEoCRIOCgZhdXRob3IYBCABKAkSEAoIaG9tZXBhZ2UYBSABKAkiLQoKTWlkZGxld2FyZRIfCgN1cmwYASABKAlCErpID3INMgteaHR0cHM6Ly8uKyLXAgoLQ3JlZGVudGlhbHMSLwoIc3RyYXRlZ3kYASABKA4yHS5hcHBzLnYxLkNyZWRlbnRpYWxzLlN0cmF0ZWd5EiwKBnNjaGVtYRgCIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIAIgBARIoCgVvYXV0aBgDIAEoCzIULmFwcHMudjEuT0F1dGhDb25maWdIAYgBASKpAQoIU3RyYXRlZ3kSGAoUU1RSQVRFR1lfVU5TUEVDSUZJRUQQABISCg5TVFJBVEVHWV9PQVVUSBABEhQKEFNUUkFURUdZX0FQSV9LRVkQAhIaChZTVFJBVEVHWV9TSEFSRURfU0VDUkVUEAMSFAoQU1RSQVRFR1lfU1NIX0tFWRAEEhEKDVNUUkFURUdZX05PTkUQBRIUChBTVFJBVEVHWV9NQU5BR0VEEAZCCQoHX3NjaGVtYUIICgZfb2F1dGgiTAoLT0F1dGhDb25maWcSHAoUYXV0aG9yaXplX3N0YXJ0X3BhdGgYASABKAkSHwoXYXV0aG9yaXplX2NhbGxiYWNrX3BhdGgYAiABKAkiVgoHSW5ib3VuZBIhCgd3ZWJob29rGAEgASgLMhAuYXBwcy52MS5XZWJob29rEigKB2FjY291bnQYAiABKAsyFy5hcHBzLnYxLkFjY291bnRXZWJob29rIhcKB1dlYmhvb2sSDAoEcGF0aBgBIAEoCSI/Cg5BY2NvdW50V2ViaG9vaxIMCgRwYXRoGAEgASgJEg8KB3NldHRpbmcYAiABKAkSDgoGc291cmNlGAMgASgJIt0CCgpTb3VyY2VUeXBlEg0KBWxhYmVsGAEgASgJEi8KBmZpZWxkcxgCIAMoCzIfLmFwcHMudjEuU291cmNlVHlwZS5GaWVsZHNFbnRyeRITCgtuYXR1cmFsX2tleRgDIAEoCRIQCghvcHRpb25hbBgEIAEoCBIWCg5wcm92aXNpb25fb25seRgFIAEoCBIrCglyZWZlcmVuY2UYBiABKAsyGC5hcHBzLnYxLlNvdXJjZVJlZmVyZW5jZRIkCgVvd25lchgHIAEoDjIVLmFwcHMudjEuU3RvcmFnZU93bmVyEhMKC3JlY29tbWVuZGVkGAggASgIEg4KBmxvb2t1cBgJIAMoCRIQCghpZGVudGl0eRgKIAEoCRpGCgtGaWVsZHNFbnRyeRILCgNrZXkYASABKAkSJgoFdmFsdWUYAiABKAsyFy5hcHBzLnYxLlN1Z2dlc3RlZEZpZWxkOgI4ASKqAgoPU291cmNlUmVmZXJlbmNlEhEKCWtleV9maWVsZBgBIAEoCRI0CgZmaWVsZHMYAiADKAsyJC5hcHBzLnYxLlNvdXJjZVJlZmVyZW5jZS5GaWVsZHNFbnRyeRIQCghlbmRwb2ludBgDIAEoCRINCgVob3N0cxgEIAMoCRIqCgdyZXF1ZXN0GAUgASgLMhkuYXBwcy52MS5SZWZlcmVuY2VSZXF1ZXN0EhoKEnJlc3BvbnNlX3RyYW5zZm9ybRgGIAEoCRIdChVjYWNoZV9tYXhfYWdlX3NlY29uZHMYByABKAUaRgoLRmllbGRzRW50cnkSCwoDa2V5GAEgASgJEiYKBXZhbHVlGAIgASgLMhcuYXBwcy52MS5TdWdnZXN0ZWRGaWVsZDoCOAEiswIKEFJlZmVyZW5jZVJlcXVlc3QSDgoGbWV0aG9kGAEgASgJEhUKDXBhdGhfdGVtcGxhdGUYAiABKAkSMwoFcXVlcnkYAyADKAsyJC5hcHBzLnYxLlJlZmVyZW5jZVJlcXVlc3QuUXVlcnlFbnRyeRI3CgdoZWFkZXJzGAQgAygLMiYuYXBwcy52MS5SZWZlcmVuY2VSZXF1ZXN0LkhlYWRlcnNFbnRyeRIVCg1ib2R5X3RlbXBsYXRlGAUgASgJEhUKDWJhdGNoX2NhcGFibGUYBiABKAgaLAoKUXVlcnlFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGi4KDEhlYWRlcnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIroBCgxTaW5rQ29udHJhY3QSDQoFbGFiZWwYASABKAkSMQoGZmllbGRzGAIgAygLMiEuYXBwcy52MS5TaW5rQ29udHJhY3QuRmllbGRzRW50cnkSEwoLbmF0dXJhbF9rZXkYAyABKAkSEAoIb3B0aW9uYWwYBCABKAgaQQoLRmllbGRzRW50cnkSCwoDa2V5GAEgASgJEiEKBXZhbHVlGAIgASgLMhIuYXBwcy52MS5TaW5rRmllbGQ6AjgBIpYCCg5TdWdnZXN0ZWRGaWVsZBIMCgR0eXBlGAEgASgJEhIKBWxhYmVsGAIgASgJSACIAQESFQoIcmVxdWlyZWQYAyABKAhIAYgBARIsCgZjb25maWcYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0SAKIAQESPQoTc3VwcG9ydGVkX2RpcmVjdGlvbhgFIAEoDjIbLmFwcHMudjEuRmllbGRTeW5jRGlyZWN0aW9uSAOIAQESFgoJcXVlcnlhYmxlGAYgASgISASIAQFCCAoGX2xhYmVsQgsKCV9yZXF1aXJlZEIJCgdfY29uZmlnQhYKFF9zdXBwb3J0ZWRfZGlyZWN0aW9uQgwKCl9xdWVyeWFibGUiWwoJU2lua0ZpZWxkEgwKBHR5cGUYASABKAkSEAoIc2VtYW50aWMYAiABKAkSEAoIcmVxdWlyZWQYAyABKAgSEgoFbGFiZWwYBCABKAlIAIgBAUIICgZfbGFiZWwimAQKCU9wZXJhdGlvbhI6CgNrZXkYASABKAlCLbpIKnIoGEAyJF4oX18pP1thLXpdW2EtejAtOV9dKigtW2EtejAtOV9dKykqJBIMCgRuYW1lGAIgASgJEhgKC2Rlc2NyaXB0aW9uGAMgASgJSACIAQESHQoIZW5kcG9pbnQYBCABKAlCC7pICHIGMgReLy4qEhQKDGNhcGFiaWxpdGllcxgFIAMoCRIXCgp0aW1lb3V0X21zGAYgASgFSAGIAQESMgoMcmV0cnlfcG9saWN5GAcgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgCiAEBEjIKDGlucHV0X3NjaGVtYRgIIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIA4gBARIzCg1vdXRwdXRfc2NoZW1hGAkgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgEiAEBEhsKDnN1cHBvcnRzX2FzeW5jGAogASgISAWIAQESGQoRcnVuX2FmdGVyX2luc3RhbGwYCyABKAgSHgoWcnVuc19vbl9tYXBwZWRfc291cmNlcxgMIAEoCEIOCgxfZGVzY3JpcHRpb25CDQoLX3RpbWVvdXRfbXNCDwoNX3JldHJ5X3BvbGljeUIPCg1faW5wdXRfc2NoZW1hQhAKDl9vdXRwdXRfc2NoZW1hQhEKD19zdXBwb3J0c19hc3luYyI9ChZNYW5pZmVzdENhcGFiaWxpdHlTcGVjEhAKCGRlY2xhcmVzGAEgASgJEhEKCXBlcl9tb2RlbBgCIAEoCCKmAQoESG9vaxIzCgNrZXkYASABKAlCJrpII3IhGEAyHV5bYS16XVthLXowLTldKigtW2EtejAtOV0rKSokEgwKBG5hbWUYAiABKAkSFgoFZXZlbnQYAyABKAlCB7pIBHICEAESJwoGZmlsdGVyGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIaCglvcGVyYXRpb24YBSABKAlCB7pIBHICEAEiNwoCVUkSMQoKcGxhY2VtZW50cxgBIAMoCzIdLmFwcHMudjEuUGxhY2VtZW50RGVjbGFyYXRpb24itgQKFFBsYWNlbWVudERlY2xhcmF0aW9uEjMKA2tleRgBIAEoCUImukgjciEYQDIdXlthLXpdW2EtejAtOV0qKC1bYS16MC05XSspKiQSNAoGdGFyZ2V0GAIgASgOMiQuYXBwcy52MS5QbGFjZW1lbnREZWNsYXJhdGlvbi5UYXJnZXQSEgoFbW9kZWwYAyABKAlIAIgBARISCgVmaWVsZBgEIAEoCUgBiAEBEiEKGWZpZWxkX3NlbGVjdGVkX2F0X2luc3RhbGwYBSABKAgSEAoDdGFiGAYgASgJSAKIAQESFgoFdGl0bGUYByABKAlCB7pIBHICEAESHwoDdXJsGAggASgJQhK6SA9yDTILXmh0dHBzOi8vLisSHQoQcmVwbGFjZXNfZGVmYXVsdBgJIAEoCEgDiAEBEisKBWhpbnRzGAogASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgEiAEBEg4KBnNjb3BlcxgLIAMoCRIQCghzZXR0aW5ncxgMIAMoCSJ0CgZUYXJnZXQSFgoSVEFSR0VUX1VOU1BFQ0lGSUVEEAASFAoQVEFSR0VUX0ZVTExfUEFHRRABEhYKElRBUkdFVF9NQUlOX0VESVRPUhACEhIKDlRBUkdFVF9TSURFQkFSEAMSEAoMVEFSR0VUX0ZJRUxEEARCCAoGX21vZGVsQggKBl9maWVsZEIGCgRfdGFiQhMKEV9yZXBsYWNlc19kZWZhdWx0QggKBl9oaW50cyqsAQoSRmllbGRTeW5jRGlyZWN0aW9uEiQKIEZJRUxEX1NZTkNfRElSRUNUSU9OX1VOU1BFQ0lGSUVEEAASJAogRklFTERfU1lOQ19ESVJFQ1RJT05fU09VUkNFX09OTFkQARIiCh5GSUVMRF9TWU5DX0RJUkVDVElPTl9TSU5LX09OTFkQAhImCiJGSUVMRF9TWU5DX0RJUkVDVElPTl9CSURJUkVDVElPTkFMEAMqhAEKDFN0b3JhZ2VPd25lchIdChlTVE9SQUdFX09XTkVSX1VOU1BFQ0lGSUVEEAASGQoVU1RPUkFHRV9PV05FUl9QUk9KRUNUEAESHgoaU1RPUkFHRV9PV05FUl9PUkdBTklaQVRJT04QAhIaChZTVE9SQUdFX09XTkVSX0NVU1RPTUVSEAMqxAoKEk1hbmlmZXN0Q2FwYWJpbGl0eRIjCh9NQU5JRkVTVF9DQVBBQklMSVRZX1VOU1BFQ0lGSUVEEAASNgofTUFOSUZFU1RfQ0FQQUJJTElUWV9DT05GSUdfUkVBRBABGhGaph0NCgtjb25maWc6cmVhZBJACiRNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfUkVBRF9BUFAQAhoWmqYdEgoQc2VjcmV0czpyZWFkLmFwcBI+CiNNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfUFVUX0FQUBADGhWaph0RCg9zZWNyZXRzOnB1dC5hcHASQAokTUFOSUZFU1RfQ0FQQUJJTElUWV9TRUNSRVRTX0xJU1RfQVBQEAQaFpqmHRIKEHNlY3JldHM6bGlzdC5hcHASRAomTUFOSUZFU1RfQ0FQQUJJTElUWV9TRUNSRVRTX0RFTEVURV9BUFAQBRoYmqYdFAoSc2VjcmV0czpkZWxldGUuYXBwEjgKIE1BTklGRVNUX0NBUEFCSUxJVFlfU1RBVFVTX1dSSVRFEAYaEpqmHQ4KDHN0YXR1czp3cml0ZRI0Ch5NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX1JFQUQQBxoQmqYdDAoKZmlsZXM6cmVhZBI0Ch5NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX0xJU1QQCBoQmqYdDAoKZmlsZXM6bGlzdBI2Ch9NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX1dSSVRFEAkaEZqmHQ0KC2ZpbGVzOndyaXRlEj4KI01BTklGRVNUX0NBUEFCSUxJVFlfQ1VTVE9NRVJTX1dSSVRFEAoaFZqmHREKD2N1c3RvbWVyczp3cml0ZRJGCidNQU5JRkVTVF9DQVBBQklMSVRZX05PVElGSUNBVElPTlNfV1JJVEUQCxoZmqYdFQoTbm90aWZpY2F0aW9uczp3cml0ZRJKCilNQU5JRkVTVF9DQVBBQklMSVRZX05PVElGSUNBVElPTlNfQ09OU0VOVBAMGhuaph0XChVub3RpZmljYXRpb25zOmNvbnNlbnQSPAoiTUFOSUZFU1RfQ0FQQUJJTElUWV9DVVNUT01FUlNfUkVBRBAOGhSaph0QCg5jdXN0b21lcnM6cmVhZBJICihNQU5JRkVTVF9DQVBBQklMSVRZX0NVU1RPTUVSU19SRUFEX05BTUVEEA8aGpqmHRYKFGN1c3RvbWVyczpyZWFkOm5hbWVkEkYKJ01BTklGRVNUX0NBUEFCSUxJVFlfT1BFUkFUSU9OU19DT01QTEVURRANGhmaph0VChNvcGVyYXRpb25zOmNvbXBsZXRlEjsKIE1BTklGRVNUX0NBUEFCSUxJVFlfUkVDT1JEU19SRUFEEBQaFZqmHREKDXJlY29yZHM6cmVhZDoQARI9CiFNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfV1JJVEUQFRoWmqYdEgoOcmVjb3Jkczp3cml0ZToQARI/CiJNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfREVMRVRFEBYaF5qmHRMKD3JlY29yZHM6ZGVsZXRlOhABEkEKI01BTklGRVNUX0NBUEFCSUxJVFlfUkVDT1JEU19QVUJMSVNIEBcaGJqmHRQKEHJlY29yZHM6cHVibGlzaDoQARJFCiVNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfQVRUUklCVVRFEBgaGpqmHRYKEnJlY29yZHM6YXR0cmlidXRlOhABOnUKE21hbmlmZXN0X2NhcGFiaWxpdHkSIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucxjj1AMgASgLMh8uYXBwcy52MS5NYW5pZmVzdENhcGFiaWxpdHlTcGVjUhJtYW5pZmVzdENhcGFiaWxpdHlCNVozZ2l0aHViLmNvbS9laWRlc3R1ZGlvL2ZvaXIvZ2VuL3Byb3RvL2FwcHMvdjE7YXBwc3YxYgZwcm90bzM", [file_buf_validate_validate, file_google_protobuf_descriptor2, file_google_protobuf_struct]);
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 FeatureSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 1);
14
- var MetadataSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 2);
15
- var MiddlewareSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 3);
16
- var CredentialsSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 4);
17
- var Credentials_StrategySchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps, 4, 0);
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, 5);
20
- var InboundSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 6);
21
- var WebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 7);
22
- var AccountWebhookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 8);
23
- var SourceTypeSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 9);
24
- var SourceReferenceSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 10);
25
- var ReferenceRequestSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 11);
26
- var SinkContractSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 12);
27
- var SuggestedFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 13);
28
- var SinkFieldSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 14);
29
- var OperationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 15);
30
- var ManifestCapabilitySpecSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 16);
31
- var HookSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 17);
32
- var UISchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 18);
33
- var PlacementDeclarationSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 19);
34
- var PlacementDeclaration_TargetSchema = /* @__PURE__ */ enumDesc2(file_apps_v1_apps, 19, 0);
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
@@ -497,7 +497,7 @@ function createAppClient(config) {
497
497
  "integrationConfig",
498
498
  `query AppInstallConfig {
499
499
  integrationConfig {
500
- name enabled middlewareUrl targetModels webhookUrl config customerEmailUnavailable
500
+ name enabled middlewareUrl targetModels webhookUrl config customerEmailUnavailable customerSignIn
501
501
  sources { key model naturalKey mode fields { appField modelField direction } }
502
502
  sinks { key model naturalKey fields { appField modelField direction } }
503
503
  }
@@ -514,7 +514,8 @@ function createAppClient(config) {
514
514
  settings: got.config ?? {},
515
515
  sources: bindingsOf(got.sources),
516
516
  sinks: bindingsOf(got.sinks),
517
- customerEmailUnavailable: customerEmailUnavailableReasonOf(got.customerEmailUnavailable)
517
+ customerEmailUnavailable: customerEmailUnavailableReasonOf(got.customerEmailUnavailable),
518
+ customerSignIn: typeof got.customerSignIn === "string" && got.customerSignIn !== "" ? got.customerSignIn : null
518
519
  };
519
520
  },
520
521
  async credentials() {
@@ -732,16 +733,6 @@ function createAppClient(config) {
732
733
  customerDeleted: answer.customerDeleted === true,
733
734
  customerKeptBecause: answer.customerKeptBecause ?? null
734
735
  };
735
- },
736
- async identities(model, customerId) {
737
- if (customerId === "") refuse(`a customer's identities on ${model} were asked for with no customer`);
738
- const answer = await field(
739
- "customerIdentitiesById",
740
- `query AppCustomerIdentities($modelKey: String!, $customerId: ID!) { customerIdentitiesById(modelKey: $modelKey, customerId: $customerId) }`,
741
- { modelKey: model, customerId }
742
- );
743
- if (!Array.isArray(answer)) return refuse(`customerIdentitiesById reported no error and returned no list on ${model}`);
744
- return answer.filter((identity) => typeof identity === "string");
745
736
  }
746
737
  }
747
738
  },
@@ -776,6 +767,25 @@ function createAppClient(config) {
776
767
  );
777
768
  return customerOf(customer);
778
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
+ },
779
789
  async list(query = {}) {
780
790
  const search = query.search?.trim() ?? "";
781
791
  const page = await field(
@@ -1137,6 +1147,7 @@ var APP_CAPABILITIES = [
1137
1147
  "notifications:consent",
1138
1148
  "customers:read",
1139
1149
  "customers:read:named",
1150
+ "customers:read:identity",
1140
1151
  "operations:complete"
1141
1152
  ];
1142
1153
  var APP_RECORD_CAPABILITY_PREFIXES = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foir/sdk",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Official Foir SDK — editor iframe client + server-side platform helpers",
5
5
  "type": "module",
6
6
  "publishConfig": {