@foir/sdk 0.16.0 → 0.17.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 +22 -0
- package/dist/app/client.d.ts +8 -0
- package/dist/app/errors.d.ts +20 -0
- package/dist/app/index.d.ts +2 -2
- package/dist/app.js +11 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -108,6 +108,28 @@ 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.17.0] — 2026-10-02
|
|
112
|
+
|
|
113
|
+
Published under npm's `next` tag from `dev`, because it reads a field the
|
|
114
|
+
platform serves from the next promotion; `latest` moves to it then.
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
|
|
118
|
+
- **An app is told when a project cannot email its customers**
|
|
119
|
+
(`@foir/sdk/app`). A project with no App base URL used to accept a
|
|
120
|
+
notification's email and drop it. The platform now refuses a notification
|
|
121
|
+
that carries an email, and an opt-in to a category confirmed by email, with
|
|
122
|
+
the reason as data. `appCustomerEmailUnavailableOf(error)` reads it:
|
|
123
|
+
`{ reason: 'NO_APP_BASE_URL' }`, or `null` for any other failure.
|
|
124
|
+
- `install.config()` answers `customerEmailUnavailable`: the same reason ahead
|
|
125
|
+
of time, or `null` when the project can send. `AppCustomerEmailUnavailableReason`
|
|
126
|
+
is the type.
|
|
127
|
+
|
|
128
|
+
### Changed
|
|
129
|
+
|
|
130
|
+
- `install.config()` asks the platform for `customerEmailUnavailable`, a field
|
|
131
|
+
a platform older than this release does not have.
|
|
132
|
+
|
|
111
133
|
## [0.16.0] — 2026-10-02
|
|
112
134
|
|
|
113
135
|
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,13 @@ 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;
|
|
98
106
|
}
|
|
99
107
|
/**
|
|
100
108
|
* The status an install reports. Leaving out `subscriptionHealth`,
|
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';
|
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
|
|
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,8 @@ 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)
|
|
510
518
|
};
|
|
511
519
|
},
|
|
512
520
|
async credentials() {
|
|
@@ -1145,6 +1153,7 @@ export {
|
|
|
1145
1153
|
FoirRequestError,
|
|
1146
1154
|
MAX_APP_MANIFEST_BYTES,
|
|
1147
1155
|
RECORD_KEY_RULE,
|
|
1156
|
+
appCustomerEmailUnavailableOf,
|
|
1148
1157
|
appCustomerUnlinkedOf,
|
|
1149
1158
|
appLookupConflictOf,
|
|
1150
1159
|
appModelFieldName,
|