@foir/sdk 0.13.0 → 0.14.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 +21 -0
- package/dist/app/client.d.ts +47 -0
- package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +15 -0
- package/dist/app/index.d.ts +1 -1
- package/dist/app/vocabulary.generated.d.ts +1 -1
- package/dist/app-contract.js +1 -1
- package/dist/app.js +54 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -108,6 +108,27 @@ 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.14.0] — 2026-10-01
|
|
112
|
+
|
|
113
|
+
Published under npm's `next` tag from `dev`, because it calls parts of the
|
|
114
|
+
platform that production serves from the next promotion; `latest` moves to it
|
|
115
|
+
then.
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
|
|
119
|
+
- **`customers.get`, `customers.byEmail` and `customers.list`** on the app
|
|
120
|
+
client (`@foir/sdk/app`): an operation reads the customers its work is about.
|
|
121
|
+
`get(id)` and `byEmail(email)` answer one customer or null, and need
|
|
122
|
+
`customers:read:named`: the customer the operation names, by id or by their
|
|
123
|
+
exact email address at the install's level, and nothing wider. `list` pages
|
|
124
|
+
through the customers at the install's level and needs `customers:read`,
|
|
125
|
+
which covers the two lookups as well. An operation declaring only the named
|
|
126
|
+
read is refused the list. `AppCustomer` and `AppCustomerList` are their types.
|
|
127
|
+
- **`customers.ensure` answers `verified`**: whether the customer it found or
|
|
128
|
+
made has proved the address is theirs. It finds the customer holding the
|
|
129
|
+
email either way, so one shopper asking twice is one customer; a caller with
|
|
130
|
+
something that should wait for proof asks the flag first.
|
|
131
|
+
|
|
111
132
|
## [0.13.0] — 2026-10-01
|
|
112
133
|
|
|
113
134
|
Published under npm's `next` tag from `dev`, because it calls parts of the
|
package/dist/app/client.d.ts
CHANGED
|
@@ -367,10 +367,40 @@ export interface AppClient {
|
|
|
367
367
|
* The customer who has this email at the install's level, made when there
|
|
368
368
|
* is none. The same customer every time for one email. Needs
|
|
369
369
|
* `customers:write`.
|
|
370
|
+
*
|
|
371
|
+
* `verified` says whether that address is one the customer has proved is
|
|
372
|
+
* theirs. A customer this call makes has not, and neither has one an
|
|
373
|
+
* earlier call made: anybody can type an address. So what is written for
|
|
374
|
+
* an unverified customer is written for whoever holds the address, and
|
|
375
|
+
* anything that should wait for proof asks `verified` first.
|
|
370
376
|
*/
|
|
371
377
|
ensure(email: string): Promise<{
|
|
372
378
|
id: string;
|
|
373
379
|
email: string;
|
|
380
|
+
verified: boolean;
|
|
381
|
+
}>;
|
|
382
|
+
/**
|
|
383
|
+
* One customer by id, or null when there is none at the install's level.
|
|
384
|
+
* Needs `customers:read:named`, or `customers:read`.
|
|
385
|
+
*/
|
|
386
|
+
get(id: string): Promise<AppCustomer | null>;
|
|
387
|
+
/**
|
|
388
|
+
* The customer who has this email at the install's level, or null. The
|
|
389
|
+
* exact address, as `ensure` matches it, and nothing wider: it finds one
|
|
390
|
+
* customer and never searches. Needs `customers:read:named`, or
|
|
391
|
+
* `customers:read`.
|
|
392
|
+
*/
|
|
393
|
+
byEmail(email: string): Promise<AppCustomer | null>;
|
|
394
|
+
/**
|
|
395
|
+
* The customers at the install's level, a page at a time, newest first.
|
|
396
|
+
* Needs `customers:read`: an operation declaring only
|
|
397
|
+
* `customers:read:named` reads the customers it names and is refused the
|
|
398
|
+
* list.
|
|
399
|
+
*/
|
|
400
|
+
list(query?: AppCustomerList): Promise<{
|
|
401
|
+
customers: AppCustomer[];
|
|
402
|
+
hasMore: boolean;
|
|
403
|
+
endCursor: string | null;
|
|
374
404
|
}>;
|
|
375
405
|
};
|
|
376
406
|
notifications: {
|
|
@@ -402,6 +432,23 @@ export interface AppClient {
|
|
|
402
432
|
start(operationKey: string, options?: AppOperationStart): Promise<AppStartedOperation>;
|
|
403
433
|
};
|
|
404
434
|
}
|
|
435
|
+
/** A customer, as an operation that declared a customer read sees them. */
|
|
436
|
+
export interface AppCustomer {
|
|
437
|
+
id: string;
|
|
438
|
+
email: string;
|
|
439
|
+
/** Whether the customer has proved the address is theirs. */
|
|
440
|
+
verified: boolean;
|
|
441
|
+
/** `ACTIVE`, `SUSPENDED` or `PENDING`, as the platform holds it. */
|
|
442
|
+
status: string;
|
|
443
|
+
}
|
|
444
|
+
export interface AppCustomerList {
|
|
445
|
+
/** Part of an email address to look for. Absent lists everyone. */
|
|
446
|
+
search?: string;
|
|
447
|
+
/** How many to answer, at most. The platform's own page size when absent. */
|
|
448
|
+
first?: number;
|
|
449
|
+
/** The `endCursor` of the page before, to read the next one. */
|
|
450
|
+
after?: string;
|
|
451
|
+
}
|
|
405
452
|
export interface AppRecordList {
|
|
406
453
|
/** The model's typed filter, by model field key. Absent matches every record. */
|
|
407
454
|
where?: JsonObject;
|
|
@@ -1414,6 +1414,21 @@ export enum ManifestCapability {
|
|
|
1414
1414
|
*/
|
|
1415
1415
|
NOTIFICATIONS_CONSENT = 12,
|
|
1416
1416
|
|
|
1417
|
+
/**
|
|
1418
|
+
* Reading customers at the install's level. customers:read:named is one
|
|
1419
|
+
* customer the operation names, by id or by their exact email address, and
|
|
1420
|
+
* never the list. customers:read is that and the list. An operation that
|
|
1421
|
+
* declares the whole read holds the named one too.
|
|
1422
|
+
*
|
|
1423
|
+
* @generated from enum value: MANIFEST_CAPABILITY_CUSTOMERS_READ = 14;
|
|
1424
|
+
*/
|
|
1425
|
+
CUSTOMERS_READ = 14,
|
|
1426
|
+
|
|
1427
|
+
/**
|
|
1428
|
+
* @generated from enum value: MANIFEST_CAPABILITY_CUSTOMERS_READ_NAMED = 15;
|
|
1429
|
+
*/
|
|
1430
|
+
CUSTOMERS_READ_NAMED = 15,
|
|
1431
|
+
|
|
1417
1432
|
/**
|
|
1418
1433
|
* Reporting an ASYNC run's outcome.
|
|
1419
1434
|
*
|
package/dist/app/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* The manifest's own messages are on `@foir/sdk/app/contract`.
|
|
22
22
|
*/
|
|
23
23
|
export { createAppClient } from './client';
|
|
24
|
-
export type { AppBinding, AppClient, AppClientConfig, AppConsentChange, AppCustomerEraseResult, AppCustomerSaveResult, AppFieldMapping, AppInstallConfig, AppNotification, AppOperationStart, AppRecord, AppRecordList, AppStartedOperation, AppStatusReport, AppSyncDirection, AppUpsertResult, AppWhoami, } from './client';
|
|
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
25
|
export { appCustomerUnlinkedOf, appLookupConflictOf, isAppFieldWithheld } from './errors';
|
|
26
26
|
export type { AppLookupConflict } from './errors';
|
|
27
27
|
export { appModelFieldName, appModelTypeName, appSelectorEnumValue } from './naming';
|
|
@@ -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", "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", "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,7 +8,7 @@ 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/
|
|
11
|
+
var file_apps_v1_apps = /* @__PURE__ */ fileDesc2("ChJhcHBzL3YxL2FwcHMucHJvdG8SB2FwcHMudjEilgUKCUFwcENvbmZpZxI0CgRuYW1lGAEgASgJQia6SCNyIRhAMh1eW2Etel1bYS16MC05XSooLVthLXowLTldKykqJBIYCgd2ZXJzaW9uGAIgASgJQge6SARyAhABEiMKCG1ldGFkYXRhGAMgASgLMhEuYXBwcy52MS5NZXRhZGF0YRInCgptaWRkbGV3YXJlGAQgASgLMhMuYXBwcy52MS5NaWRkbGV3YXJlEikKC2NyZWRlbnRpYWxzGAUgASgLMhQuYXBwcy52MS5DcmVkZW50aWFscxIwCg9zZXR0aW5nc19zY2hlbWEYBiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKB3NvdXJjZXMYByADKAsyHy5hcHBzLnYxLkFwcENvbmZpZy5Tb3VyY2VzRW50cnkSLAoFc2lua3MYCCADKAsyHS5hcHBzLnYxLkFwcENvbmZpZy5TaW5rc0VudHJ5EiYKCm9wZXJhdGlvbnMYCSADKAsyEi5hcHBzLnYxLk9wZXJhdGlvbhIcCgVob29rcxgKIAMoCzINLmFwcHMudjEuSG9vaxIXCgJ1aRgLIAEoCzILLmFwcHMudjEuVUkSIQoHaW5ib3VuZBgMIAEoCzIQLmFwcHMudjEuSW5ib3VuZBIiCghmZWF0dXJlcxgNIAMoCzIQLmFwcHMudjEuRmVhdHVyZRpDCgxTb3VyY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMuYXBwcy52MS5Tb3VyY2VUeXBlOgI4ARpDCgpTaW5rc0VudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLmFwcHMudjEuU2lua0NvbnRyYWN0OgI4ASKNAQoHRmVhdHVyZRIzCgNrZXkYASABKAlCJrpII3IhGEAyHV5bYS16XVthLXowLTldKigtW2EtejAtOV0rKSokEhYKBXRpdGxlGAIgASgJQge6SARyAhABEhMKC2Rlc2NyaXB0aW9uGAMgASgJEg8KB3NldHRpbmcYBCABKAkSDwoHc291cmNlcxgFIAMoCSJlCghNZXRhZGF0YRIUCgxkaXNwbGF5X25hbWUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSDAoEaWNvbhgDIAEoCRIOCgZhdXRob3IYBCABKAkSEAoIaG9tZXBhZ2UYBSABKAkiLQoKTWlkZGxld2FyZRIfCgN1cmwYASABKAlCErpID3INMgteaHR0cHM6Ly8uKyLXAgoLQ3JlZGVudGlhbHMSLwoIc3RyYXRlZ3kYASABKA4yHS5hcHBzLnYxLkNyZWRlbnRpYWxzLlN0cmF0ZWd5EiwKBnNjaGVtYRgCIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIAIgBARIoCgVvYXV0aBgDIAEoCzIULmFwcHMudjEuT0F1dGhDb25maWdIAYgBASKpAQoIU3RyYXRlZ3kSGAoUU1RSQVRFR1lfVU5TUEVDSUZJRUQQABISCg5TVFJBVEVHWV9PQVVUSBABEhQKEFNUUkFURUdZX0FQSV9LRVkQAhIaChZTVFJBVEVHWV9TSEFSRURfU0VDUkVUEAMSFAoQU1RSQVRFR1lfU1NIX0tFWRAEEhEKDVNUUkFURUdZX05PTkUQBRIUChBTVFJBVEVHWV9NQU5BR0VEEAZCCQoHX3NjaGVtYUIICgZfb2F1dGgiTAoLT0F1dGhDb25maWcSHAoUYXV0aG9yaXplX3N0YXJ0X3BhdGgYASABKAkSHwoXYXV0aG9yaXplX2NhbGxiYWNrX3BhdGgYAiABKAkiVgoHSW5ib3VuZBIhCgd3ZWJob29rGAEgASgLMhAuYXBwcy52MS5XZWJob29rEigKB2FjY291bnQYAiABKAsyFy5hcHBzLnYxLkFjY291bnRXZWJob29rIhcKB1dlYmhvb2sSDAoEcGF0aBgBIAEoCSI/Cg5BY2NvdW50V2ViaG9vaxIMCgRwYXRoGAEgASgJEg8KB3NldHRpbmcYAiABKAkSDgoGc291cmNlGAMgASgJIt0CCgpTb3VyY2VUeXBlEg0KBWxhYmVsGAEgASgJEi8KBmZpZWxkcxgCIAMoCzIfLmFwcHMudjEuU291cmNlVHlwZS5GaWVsZHNFbnRyeRITCgtuYXR1cmFsX2tleRgDIAEoCRIQCghvcHRpb25hbBgEIAEoCBIWCg5wcm92aXNpb25fb25seRgFIAEoCBIrCglyZWZlcmVuY2UYBiABKAsyGC5hcHBzLnYxLlNvdXJjZVJlZmVyZW5jZRIkCgVvd25lchgHIAEoDjIVLmFwcHMudjEuU3RvcmFnZU93bmVyEhMKC3JlY29tbWVuZGVkGAggASgIEg4KBmxvb2t1cBgJIAMoCRIQCghpZGVudGl0eRgKIAEoCRpGCgtGaWVsZHNFbnRyeRILCgNrZXkYASABKAkSJgoFdmFsdWUYAiABKAsyFy5hcHBzLnYxLlN1Z2dlc3RlZEZpZWxkOgI4ASKqAgoPU291cmNlUmVmZXJlbmNlEhEKCWtleV9maWVsZBgBIAEoCRI0CgZmaWVsZHMYAiADKAsyJC5hcHBzLnYxLlNvdXJjZVJlZmVyZW5jZS5GaWVsZHNFbnRyeRIQCghlbmRwb2ludBgDIAEoCRINCgVob3N0cxgEIAMoCRIqCgdyZXF1ZXN0GAUgASgLMhkuYXBwcy52MS5SZWZlcmVuY2VSZXF1ZXN0EhoKEnJlc3BvbnNlX3RyYW5zZm9ybRgGIAEoCRIdChVjYWNoZV9tYXhfYWdlX3NlY29uZHMYByABKAUaRgoLRmllbGRzRW50cnkSCwoDa2V5GAEgASgJEiYKBXZhbHVlGAIgASgLMhcuYXBwcy52MS5TdWdnZXN0ZWRGaWVsZDoCOAEiswIKEFJlZmVyZW5jZVJlcXVlc3QSDgoGbWV0aG9kGAEgASgJEhUKDXBhdGhfdGVtcGxhdGUYAiABKAkSMwoFcXVlcnkYAyADKAsyJC5hcHBzLnYxLlJlZmVyZW5jZVJlcXVlc3QuUXVlcnlFbnRyeRI3CgdoZWFkZXJzGAQgAygLMiYuYXBwcy52MS5SZWZlcmVuY2VSZXF1ZXN0LkhlYWRlcnNFbnRyeRIVCg1ib2R5X3RlbXBsYXRlGAUgASgJEhUKDWJhdGNoX2NhcGFibGUYBiABKAgaLAoKUXVlcnlFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGi4KDEhlYWRlcnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIroBCgxTaW5rQ29udHJhY3QSDQoFbGFiZWwYASABKAkSMQoGZmllbGRzGAIgAygLMiEuYXBwcy52MS5TaW5rQ29udHJhY3QuRmllbGRzRW50cnkSEwoLbmF0dXJhbF9rZXkYAyABKAkSEAoIb3B0aW9uYWwYBCABKAgaQQoLRmllbGRzRW50cnkSCwoDa2V5GAEgASgJEiEKBXZhbHVlGAIgASgLMhIuYXBwcy52MS5TaW5rRmllbGQ6AjgBIpYCCg5TdWdnZXN0ZWRGaWVsZBIMCgR0eXBlGAEgASgJEhIKBWxhYmVsGAIgASgJSACIAQESFQoIcmVxdWlyZWQYAyABKAhIAYgBARIsCgZjb25maWcYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0SAKIAQESPQoTc3VwcG9ydGVkX2RpcmVjdGlvbhgFIAEoDjIbLmFwcHMudjEuRmllbGRTeW5jRGlyZWN0aW9uSAOIAQESFgoJcXVlcnlhYmxlGAYgASgISASIAQFCCAoGX2xhYmVsQgsKCV9yZXF1aXJlZEIJCgdfY29uZmlnQhYKFF9zdXBwb3J0ZWRfZGlyZWN0aW9uQgwKCl9xdWVyeWFibGUiWwoJU2lua0ZpZWxkEgwKBHR5cGUYASABKAkSEAoIc2VtYW50aWMYAiABKAkSEAoIcmVxdWlyZWQYAyABKAgSEgoFbGFiZWwYBCABKAlIAIgBAUIICgZfbGFiZWwimAQKCU9wZXJhdGlvbhI6CgNrZXkYASABKAlCLbpIKnIoGEAyJF4oX18pP1thLXpdW2EtejAtOV9dKigtW2EtejAtOV9dKykqJBIMCgRuYW1lGAIgASgJEhgKC2Rlc2NyaXB0aW9uGAMgASgJSACIAQESHQoIZW5kcG9pbnQYBCABKAlCC7pICHIGMgReLy4qEhQKDGNhcGFiaWxpdGllcxgFIAMoCRIXCgp0aW1lb3V0X21zGAYgASgFSAGIAQESMgoMcmV0cnlfcG9saWN5GAcgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgCiAEBEjIKDGlucHV0X3NjaGVtYRgIIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIA4gBARIzCg1vdXRwdXRfc2NoZW1hGAkgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgEiAEBEhsKDnN1cHBvcnRzX2FzeW5jGAogASgISAWIAQESGQoRcnVuX2FmdGVyX2luc3RhbGwYCyABKAgSHgoWcnVuc19vbl9tYXBwZWRfc291cmNlcxgMIAEoCEIOCgxfZGVzY3JpcHRpb25CDQoLX3RpbWVvdXRfbXNCDwoNX3JldHJ5X3BvbGljeUIPCg1faW5wdXRfc2NoZW1hQhAKDl9vdXRwdXRfc2NoZW1hQhEKD19zdXBwb3J0c19hc3luYyI9ChZNYW5pZmVzdENhcGFiaWxpdHlTcGVjEhAKCGRlY2xhcmVzGAEgASgJEhEKCXBlcl9tb2RlbBgCIAEoCCKmAQoESG9vaxIzCgNrZXkYASABKAlCJrpII3IhGEAyHV5bYS16XVthLXowLTldKigtW2EtejAtOV0rKSokEgwKBG5hbWUYAiABKAkSFgoFZXZlbnQYAyABKAlCB7pIBHICEAESJwoGZmlsdGVyGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIaCglvcGVyYXRpb24YBSABKAlCB7pIBHICEAEiNwoCVUkSMQoKcGxhY2VtZW50cxgBIAMoCzIdLmFwcHMudjEuUGxhY2VtZW50RGVjbGFyYXRpb24itgQKFFBsYWNlbWVudERlY2xhcmF0aW9uEjMKA2tleRgBIAEoCUImukgjciEYQDIdXlthLXpdW2EtejAtOV0qKC1bYS16MC05XSspKiQSNAoGdGFyZ2V0GAIgASgOMiQuYXBwcy52MS5QbGFjZW1lbnREZWNsYXJhdGlvbi5UYXJnZXQSEgoFbW9kZWwYAyABKAlIAIgBARISCgVmaWVsZBgEIAEoCUgBiAEBEiEKGWZpZWxkX3NlbGVjdGVkX2F0X2luc3RhbGwYBSABKAgSEAoDdGFiGAYgASgJSAKIAQESFgoFdGl0bGUYByABKAlCB7pIBHICEAESHwoDdXJsGAggASgJQhK6SA9yDTILXmh0dHBzOi8vLisSHQoQcmVwbGFjZXNfZGVmYXVsdBgJIAEoCEgDiAEBEisKBWhpbnRzGAogASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgEiAEBEg4KBnNjb3BlcxgLIAMoCRIQCghzZXR0aW5ncxgMIAMoCSJ0CgZUYXJnZXQSFgoSVEFSR0VUX1VOU1BFQ0lGSUVEEAASFAoQVEFSR0VUX0ZVTExfUEFHRRABEhYKElRBUkdFVF9NQUlOX0VESVRPUhACEhIKDlRBUkdFVF9TSURFQkFSEAMSEAoMVEFSR0VUX0ZJRUxEEARCCAoGX21vZGVsQggKBl9maWVsZEIGCgRfdGFiQhMKEV9yZXBsYWNlc19kZWZhdWx0QggKBl9oaW50cyqsAQoSRmllbGRTeW5jRGlyZWN0aW9uEiQKIEZJRUxEX1NZTkNfRElSRUNUSU9OX1VOU1BFQ0lGSUVEEAASJAogRklFTERfU1lOQ19ESVJFQ1RJT05fU09VUkNFX09OTFkQARIiCh5GSUVMRF9TWU5DX0RJUkVDVElPTl9TSU5LX09OTFkQAhImCiJGSUVMRF9TWU5DX0RJUkVDVElPTl9CSURJUkVDVElPTkFMEAMqhAEKDFN0b3JhZ2VPd25lchIdChlTVE9SQUdFX09XTkVSX1VOU1BFQ0lGSUVEEAASGQoVU1RPUkFHRV9PV05FUl9QUk9KRUNUEAESHgoaU1RPUkFHRV9PV05FUl9PUkdBTklaQVRJT04QAhIaChZTVE9SQUdFX09XTkVSX0NVU1RPTUVSEAMqxAoKEk1hbmlmZXN0Q2FwYWJpbGl0eRIjCh9NQU5JRkVTVF9DQVBBQklMSVRZX1VOU1BFQ0lGSUVEEAASNgofTUFOSUZFU1RfQ0FQQUJJTElUWV9DT05GSUdfUkVBRBABGhGaph0NCgtjb25maWc6cmVhZBJACiRNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfUkVBRF9BUFAQAhoWmqYdEgoQc2VjcmV0czpyZWFkLmFwcBI+CiNNQU5JRkVTVF9DQVBBQklMSVRZX1NFQ1JFVFNfUFVUX0FQUBADGhWaph0RCg9zZWNyZXRzOnB1dC5hcHASQAokTUFOSUZFU1RfQ0FQQUJJTElUWV9TRUNSRVRTX0xJU1RfQVBQEAQaFpqmHRIKEHNlY3JldHM6bGlzdC5hcHASRAomTUFOSUZFU1RfQ0FQQUJJTElUWV9TRUNSRVRTX0RFTEVURV9BUFAQBRoYmqYdFAoSc2VjcmV0czpkZWxldGUuYXBwEjgKIE1BTklGRVNUX0NBUEFCSUxJVFlfU1RBVFVTX1dSSVRFEAYaEpqmHQ4KDHN0YXR1czp3cml0ZRI0Ch5NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX1JFQUQQBxoQmqYdDAoKZmlsZXM6cmVhZBI0Ch5NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX0xJU1QQCBoQmqYdDAoKZmlsZXM6bGlzdBI2Ch9NQU5JRkVTVF9DQVBBQklMSVRZX0ZJTEVTX1dSSVRFEAkaEZqmHQ0KC2ZpbGVzOndyaXRlEj4KI01BTklGRVNUX0NBUEFCSUxJVFlfQ1VTVE9NRVJTX1dSSVRFEAoaFZqmHREKD2N1c3RvbWVyczp3cml0ZRJGCidNQU5JRkVTVF9DQVBBQklMSVRZX05PVElGSUNBVElPTlNfV1JJVEUQCxoZmqYdFQoTbm90aWZpY2F0aW9uczp3cml0ZRJKCilNQU5JRkVTVF9DQVBBQklMSVRZX05PVElGSUNBVElPTlNfQ09OU0VOVBAMGhuaph0XChVub3RpZmljYXRpb25zOmNvbnNlbnQSPAoiTUFOSUZFU1RfQ0FQQUJJTElUWV9DVVNUT01FUlNfUkVBRBAOGhSaph0QCg5jdXN0b21lcnM6cmVhZBJICihNQU5JRkVTVF9DQVBBQklMSVRZX0NVU1RPTUVSU19SRUFEX05BTUVEEA8aGpqmHRYKFGN1c3RvbWVyczpyZWFkOm5hbWVkEkYKJ01BTklGRVNUX0NBUEFCSUxJVFlfT1BFUkFUSU9OU19DT01QTEVURRANGhmaph0VChNvcGVyYXRpb25zOmNvbXBsZXRlEjsKIE1BTklGRVNUX0NBUEFCSUxJVFlfUkVDT1JEU19SRUFEEBQaFZqmHREKDXJlY29yZHM6cmVhZDoQARI9CiFNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfV1JJVEUQFRoWmqYdEgoOcmVjb3Jkczp3cml0ZToQARI/CiJNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfREVMRVRFEBYaF5qmHRMKD3JlY29yZHM6ZGVsZXRlOhABEkEKI01BTklGRVNUX0NBUEFCSUxJVFlfUkVDT1JEU19QVUJMSVNIEBcaGJqmHRQKEHJlY29yZHM6cHVibGlzaDoQARJFCiVNQU5JRkVTVF9DQVBBQklMSVRZX1JFQ09SRFNfQVRUUklCVVRFEBgaGpqmHRYKEnJlY29yZHM6YXR0cmlidXRlOhABOnUKE21hbmlmZXN0X2NhcGFiaWxpdHkSIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucxjj1AMgASgLMh8uYXBwcy52MS5NYW5pZmVzdENhcGFiaWxpdHlTcGVjUhJtYW5pZmVzdENhcGFiaWxpdHlCNVozZ2l0aHViLmNvbS9laWRlc3R1ZGlvL2ZvaXIvZ2VuL3Byb3RvL2FwcHMvdjE7YXBwc3YxYgZwcm90bzM", [file_buf_validate_validate, file_google_protobuf_descriptor2, file_google_protobuf_struct]);
|
|
12
12
|
var AppConfigSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 0);
|
|
13
13
|
var FeatureSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 1);
|
|
14
14
|
var MetadataSchema = /* @__PURE__ */ messageDesc2(file_apps_v1_apps, 2);
|
package/dist/app.js
CHANGED
|
@@ -279,6 +279,14 @@ function isSelectableFieldKey(fieldKey) {
|
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
// src/app/client.ts
|
|
282
|
+
var CUSTOMER_FIELDS = "id email status emailVerifiedAt";
|
|
283
|
+
function isVerified(customer) {
|
|
284
|
+
return typeof customer.emailVerifiedAt === "string" && customer.emailVerifiedAt !== "";
|
|
285
|
+
}
|
|
286
|
+
function customerOf(customer) {
|
|
287
|
+
if (!customer?.id) return null;
|
|
288
|
+
return { id: customer.id, email: customer.email ?? "", verified: isVerified(customer), status: customer.status ?? "" };
|
|
289
|
+
}
|
|
282
290
|
var RECORD_ID_FIELD = "_id";
|
|
283
291
|
var RECORD_NATURAL_KEY_FIELD = "_naturalKey";
|
|
284
292
|
var RECORD_OWNER_FIELD = "_ownerId";
|
|
@@ -735,11 +743,53 @@ function createAppClient(config) {
|
|
|
735
743
|
if (address === "") refuse("a customer was asked for with an empty email");
|
|
736
744
|
const customer = await field(
|
|
737
745
|
"createCustomer",
|
|
738
|
-
`mutation AppEnsureCustomer($input: CreateCustomerInput!) { createCustomer(input: $input) { id email } }`,
|
|
746
|
+
`mutation AppEnsureCustomer($input: CreateCustomerInput!) { createCustomer(input: $input) { id email emailVerifiedAt } }`,
|
|
739
747
|
{ input: { email: address, returnExisting: true } }
|
|
740
748
|
);
|
|
741
749
|
if (!customer?.id) return refuse("createCustomer reported no error and returned no customer");
|
|
742
|
-
return { id: customer.id, email: customer.email ?? address };
|
|
750
|
+
return { id: customer.id, email: customer.email ?? address, verified: isVerified(customer) };
|
|
751
|
+
},
|
|
752
|
+
async get(id) {
|
|
753
|
+
if (id.trim() === "") refuse("a customer was asked for with an empty id");
|
|
754
|
+
const customer = await field(
|
|
755
|
+
"customer",
|
|
756
|
+
`query AppCustomer($id: String) { customer(id: $id) { ${CUSTOMER_FIELDS} } }`,
|
|
757
|
+
{ id }
|
|
758
|
+
);
|
|
759
|
+
return customerOf(customer);
|
|
760
|
+
},
|
|
761
|
+
async byEmail(email) {
|
|
762
|
+
const address = email.trim();
|
|
763
|
+
if (address === "") refuse("a customer was asked for with an empty email");
|
|
764
|
+
const customer = await field(
|
|
765
|
+
"customer",
|
|
766
|
+
`query AppCustomerByEmail($email: String) { customer(email: $email) { ${CUSTOMER_FIELDS} } }`,
|
|
767
|
+
{ email: address }
|
|
768
|
+
);
|
|
769
|
+
return customerOf(customer);
|
|
770
|
+
},
|
|
771
|
+
async list(query = {}) {
|
|
772
|
+
const search = query.search?.trim() ?? "";
|
|
773
|
+
const page = await field(
|
|
774
|
+
"customers",
|
|
775
|
+
`query AppCustomers($first: Int, $after: String, $filter: CustomersFilterInput) {
|
|
776
|
+
customers(first: $first, after: $after, filter: $filter) {
|
|
777
|
+
edges { node { ${CUSTOMER_FIELDS} } }
|
|
778
|
+
pageInfo { hasNextPage endCursor }
|
|
779
|
+
}
|
|
780
|
+
}`,
|
|
781
|
+
{
|
|
782
|
+
...query.first !== void 0 ? { first: query.first } : {},
|
|
783
|
+
...query.after !== void 0 ? { after: query.after } : {},
|
|
784
|
+
...search !== "" ? { filter: { search } } : {}
|
|
785
|
+
}
|
|
786
|
+
);
|
|
787
|
+
const customers = [];
|
|
788
|
+
for (const edge of page?.edges ?? []) {
|
|
789
|
+
const customer = customerOf(edge?.node ?? null);
|
|
790
|
+
if (customer) customers.push(customer);
|
|
791
|
+
}
|
|
792
|
+
return { customers, hasMore: page?.pageInfo?.hasNextPage === true, endCursor: page?.pageInfo?.endCursor ?? null };
|
|
743
793
|
}
|
|
744
794
|
},
|
|
745
795
|
notifications: {
|
|
@@ -1075,6 +1125,8 @@ var APP_CAPABILITIES = [
|
|
|
1075
1125
|
"customers:write",
|
|
1076
1126
|
"notifications:write",
|
|
1077
1127
|
"notifications:consent",
|
|
1128
|
+
"customers:read",
|
|
1129
|
+
"customers:read:named",
|
|
1078
1130
|
"operations:complete"
|
|
1079
1131
|
];
|
|
1080
1132
|
var APP_RECORD_CAPABILITY_PREFIXES = [
|