palbase 0.2.0 → 0.3.1
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/LICENSE +3 -0
- package/dist/ai/index.js +2 -2
- package/dist/backend/engine.js +2 -2
- package/dist/backend/env.js +1 -1
- package/dist/backend/index.js +3 -3
- package/dist/backend/stack.js +1 -1
- package/dist/backend/test.js +2 -2
- package/dist/chunks/2YUVLZLK.js +87 -0
- package/dist/chunks/{K3C2IEDS.js → 4K4MKD2J.js} +2 -2
- package/dist/chunks/{HDX6YUAB.js → 4MOCDBZP.js} +1 -1
- package/dist/chunks/{I3JNX6MZ.js → 4UPL27ED.js} +1 -1
- package/dist/chunks/6FQGUDBD.js +2 -0
- package/dist/chunks/{ZFPDYRRY.js → FVIHTHHV.js} +2 -2
- package/dist/chunks/{6OPBXB7Z.js → INXQWVHU.js} +2 -2
- package/dist/chunks/{UTRQWCMD.js → JF7KZUPL.js} +2 -2
- package/dist/chunks/{5W6XJM46.js → L6GKX3XI.js} +2 -2
- package/dist/chunks/{ECUYQ73P.js → MJPUCGXY.js} +2 -2
- package/dist/chunks/{NIJHTHNF.js → NTMO2LFH.js} +2 -2
- package/dist/chunks/{JEJ5CFTK.js → TV7W53F2.js} +2 -2
- package/dist/chunks/{TL4H6V3P.js → VTNEPJRV.js} +1 -1
- package/dist/chunks/{KRBVYYME.js → XNRYSI7A.js} +1 -1
- package/dist/chunks/{7LOMYBLN.js → XOGEEZNP.js} +2 -2
- package/dist/cli.js +84 -81
- package/dist/refuse/ai.js +1 -1
- package/dist/refuse/backend.js +1 -1
- package/dist/refuse/server.js +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/testing.js +2 -2
- package/dist/web/index.js +2 -2
- package/dist/web/palbe.js +2 -2
- package/dist/web/paywall.js +2 -2
- package/dist/web/vite.js +2 -2
- package/package.json +3 -3
- package/types/internal/src/modules/ai.d.ts +811 -0
- package/types/internal/src/modules/purchases.d.ts +1601 -294
- package/types/internal/src/modules/storage.d.ts +1 -1
- package/types/web/src/client.d.ts +6 -0
- package/types/web/src/index.d.ts +1 -0
- package/types/web/src/paywall/assets.d.ts +51 -0
- package/types/web/src/paywall/attributes.d.ts +13 -0
- package/types/web/src/paywall/index.d.ts +4 -2
- package/types/web/src/paywall/placement.d.ts +21 -7
- package/types/web/src/paywall/render.d.ts +56 -17
- package/types/web/src/paywall/resolve.d.ts +150 -115
- package/types/web/src/purchases.d.ts +23 -4
- package/dist/chunks/AN5LCF5K.js +0 -55
- package/dist/chunks/HVC2C35F.js +0 -2
|
@@ -262,7 +262,7 @@ export type StorageObject = {
|
|
|
262
262
|
*/
|
|
263
263
|
export type StorageStats = {
|
|
264
264
|
/**
|
|
265
|
-
* Every bucket of the project, by name; an empty one with zeros.
|
|
265
|
+
* Every bucket of the project, by name; an empty one with zeros. A platform module's own bucket is listed with its share too, though the project does not reach it otherwise: _ai holds the pictures its agents' tools returned, deleted with their chat (or once a one-shot answer is answered) — counted in the project's storage as its other files are.
|
|
266
266
|
*/
|
|
267
267
|
buckets: StorageStatsBucket[];
|
|
268
268
|
/**
|
|
@@ -30,6 +30,12 @@ export interface ClientOptions {
|
|
|
30
30
|
* Off unless given; events the app captures (`analytics.capture`) go either way.
|
|
31
31
|
*/
|
|
32
32
|
analytics?: boolean | AnalyticsOptions;
|
|
33
|
+
/**
|
|
34
|
+
* The app's version, as its users see it ("2.4.1"): said with a paywall's
|
|
35
|
+
* request, for a placement's targeting rules that read it. Nothing is said
|
|
36
|
+
* without one.
|
|
37
|
+
*/
|
|
38
|
+
appVersion?: string;
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
35
41
|
* The app's client. A backend's generated Palbe module (palbase apps:sync)
|
package/types/web/src/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { Channel, RealtimeSocket, type PushReply } from './socket.js';
|
|
|
5
5
|
export { Analytics, type AnalyticsOptions } from './analytics.js';
|
|
6
6
|
export { Purchases, type CustomerInfo, type CustomerInfoListener, type MergeGrant, type Offerings } from './purchases.js';
|
|
7
7
|
export type { Paywall, PaywallRenderOptions } from './paywall/placement.js';
|
|
8
|
+
export type { PaywallAttribute } from './paywall/attributes.js';
|
|
8
9
|
export type { PaywallPackage, PaywallView } from './paywall/render.js';
|
|
9
10
|
export { PalbaseError } from '../../internal/src/transport.js';
|
|
10
11
|
export { BackendError, isBackendError, type BackendErrorKind, type FieldError } from './backend-error.js';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** An asset as the answer lists it (PaywallAssetRef). */
|
|
2
|
+
export interface PaywallAssetRef {
|
|
3
|
+
id: string;
|
|
4
|
+
kind: 'image' | 'video' | 'font' | 'html';
|
|
5
|
+
url: string;
|
|
6
|
+
sha256: string;
|
|
7
|
+
bytes: number;
|
|
8
|
+
}
|
|
9
|
+
/** An asset ready to draw. */
|
|
10
|
+
export interface PreparedAsset {
|
|
11
|
+
kind: PaywallAssetRef['kind'];
|
|
12
|
+
/** Where its checked bytes are: an object URL (or, unchecked, the https address Studio's preview draws from). */
|
|
13
|
+
url: string;
|
|
14
|
+
/** A font's family, registered with the page's fonts. */
|
|
15
|
+
family?: string;
|
|
16
|
+
/** An HTML block's document, every file of its zip inside it. */
|
|
17
|
+
html?: string;
|
|
18
|
+
}
|
|
19
|
+
/** The family a font asset is registered under. */
|
|
20
|
+
export declare const fontFamily: (id: string) => string;
|
|
21
|
+
/** The id an `asset:<id>` names; undefined for anything else. */
|
|
22
|
+
export declare function assetId(src: unknown): string | undefined;
|
|
23
|
+
export interface PrepareOptions {
|
|
24
|
+
fetch?: (input: string, init?: RequestInit) => Promise<Response>;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
/** Where a font is registered: the page's fonts unless given. */
|
|
27
|
+
fonts?: FontFaceSet;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Downloads and checks every asset; those that pass are ready to draw, by
|
|
31
|
+
* id. Done when the paywall is fetched, before it is shown: what is shown
|
|
32
|
+
* then draws from memory.
|
|
33
|
+
*/
|
|
34
|
+
export declare function prepareAssets(refs: readonly PaywallAssetRef[], opts?: PrepareOptions): Promise<Record<string, PreparedAsset>>;
|
|
35
|
+
/**
|
|
36
|
+
* What an asset's bytes are, among the formats its kind takes — the type its
|
|
37
|
+
* object URL is given: an image is PNG, JPEG or WebP; a video MP4, QuickTime
|
|
38
|
+
* or WebM; a font WOFF2, WOFF, TrueType or OpenType; an HTML block a zip.
|
|
39
|
+
* Undefined for anything else: the asset is not drawn.
|
|
40
|
+
*/
|
|
41
|
+
export declare function formatOf(kind: PaywallAssetRef['kind'], b: Uint8Array): string | undefined;
|
|
42
|
+
/** The files of a zip, by path: stored and deflated entries (what the server takes). */
|
|
43
|
+
export declare function unzip(bytes: Uint8Array): Promise<Map<string, Uint8Array>>;
|
|
44
|
+
/** The content security of an HTML block: it loads what is inside its document, and nothing from anywhere else. */
|
|
45
|
+
export declare const HTML_BLOCK_CSP = "default-src 'none'; img-src data:; media-src data:; font-src data:; style-src 'unsafe-inline' data:; script-src 'unsafe-inline' data:";
|
|
46
|
+
/**
|
|
47
|
+
* An HTML block's document: its index.html with every file it names — a
|
|
48
|
+
* src, an href, a url() in its styles — written into it, and a policy that
|
|
49
|
+
* lets it load nothing else. Undefined without an index.html.
|
|
50
|
+
*/
|
|
51
|
+
export declare function htmlDocument(files: Map<string, Uint8Array>): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** An attribute's value: a text, a number or a yes/no. */
|
|
2
|
+
export type PaywallAttribute = string | number | boolean;
|
|
3
|
+
export declare const MAX_ATTRIBUTES = 20;
|
|
4
|
+
export declare const MAX_ATTRIBUTES_BYTES = 2048;
|
|
5
|
+
export declare const MAX_ATTRIBUTE_TEXT_BYTES = 256;
|
|
6
|
+
/**
|
|
7
|
+
* The attributes as the header carries them; undefined for none. Throws
|
|
8
|
+
* `invalid_attributes` for what the module would refuse: more than 20, a key
|
|
9
|
+
* that is not a letter then letters, digits and `_ . -` (40 at most), a text
|
|
10
|
+
* over 256 bytes, a number that is not finite, a value of another kind, or
|
|
11
|
+
* more than 2 KiB of them together.
|
|
12
|
+
*/
|
|
13
|
+
export declare function attributesHeader(attributes: Readonly<Record<string, PaywallAttribute>> | undefined): string | undefined;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { PAYWALL_COMPONENTS, PAYWALL_SCHEMA,
|
|
2
|
-
export { renderPaywall, type PaywallHandlers, type PaywallInput, type PaywallPackage, type PaywallView } from './render.js';
|
|
1
|
+
export { PAYWALL_COMPONENTS, PAYWALL_SCHEMA, countdownValues, packagesOf, resolution as resolvePaywallWithPaths, resolve as resolvePaywall, type Appearance, type PackageValues, type PaywallDefinition, type Platform, type ResolvedNode, type ResolvedPaywall, type ResolvedStyle, type Resolution, type ResolveOptions, } from './resolve.js';
|
|
2
|
+
export { renderPaywall, type PaywallHandlers, type PaywallInput, type PaywallPackage, type PaywallState, type PaywallView } from './render.js';
|
|
3
|
+
export { assetId, fontFamily, htmlDocument, prepareAssets, unzip, type PaywallAssetRef, type PreparedAsset } from './assets.js';
|
|
4
|
+
export { attributesHeader, type PaywallAttribute } from './attributes.js';
|
|
3
5
|
export { formatPeriod, formatPrice, packageValues, parseDuration, type PricedPackage } from './prices.js';
|
|
4
6
|
export { ICONS as PAYWALL_ICONS } from './icons.js';
|
|
5
7
|
export { Paywall, defaultPaywall, type PaywallRenderOptions } from './placement.js';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { purchases as purchasesModule } from '../../../internal/src/modules/index.js';
|
|
2
|
+
import { type PreparedAsset } from './assets.js';
|
|
3
|
+
import { type PaywallAttribute } from './attributes.js';
|
|
2
4
|
import { type PricedPackage } from './prices.js';
|
|
3
5
|
import { type PaywallHandlers, type PaywallPackage, type PaywallView } from './render.js';
|
|
4
6
|
import { type Appearance, type PackageValues, type PaywallDefinition } from './resolve.js';
|
|
@@ -13,7 +15,7 @@ export interface PaywallRenderOptions {
|
|
|
13
15
|
appearance?: Appearance;
|
|
14
16
|
/** The browser's language unless given. */
|
|
15
17
|
locale?: string;
|
|
16
|
-
/** The app's terms and privacy policy (https), for the definition's `terms` and `privacy`
|
|
18
|
+
/** The app's terms and privacy policy (https), for the definition's `terms` and `privacy` buttons. */
|
|
17
19
|
links?: {
|
|
18
20
|
terms?: string;
|
|
19
21
|
privacy?: string;
|
|
@@ -43,17 +45,20 @@ export declare class Paywall {
|
|
|
43
45
|
/** The server's answer now, the copy kept from before when it could not be asked, or the SDK's own from the catalog (nothing published there). */
|
|
44
46
|
readonly source: 'server' | 'cache' | 'default';
|
|
45
47
|
readonly definition: PaywallDefinition;
|
|
48
|
+
/** The paywall's assets, downloaded and checked: those that passed, by id. */
|
|
49
|
+
readonly assets: Record<string, PreparedAsset>;
|
|
46
50
|
/** What the paywall sells on the web, priced as the catalog prices it. */
|
|
47
51
|
readonly offerings: Offerings;
|
|
48
|
-
/** The paywall and the version shown,
|
|
52
|
+
/** The paywall and the version shown, the experiment's variant or the placement's rule that chose it; absent for the SDK's own. */
|
|
49
53
|
readonly shown: {
|
|
50
54
|
paywallId: string;
|
|
51
55
|
version: number;
|
|
52
56
|
variant?: string;
|
|
57
|
+
ruleId?: string;
|
|
53
58
|
} | undefined;
|
|
54
59
|
private deps;
|
|
55
60
|
private exposed;
|
|
56
|
-
constructor(placement: string, source: Paywall['source'], definition: PaywallDefinition, offerings: Offerings, shown: Paywall['shown'], deps: PaywallDeps);
|
|
61
|
+
constructor(placement: string, source: Paywall['source'], definition: PaywallDefinition, offerings: Offerings, shown: Paywall['shown'], deps: PaywallDeps, assets?: Record<string, PreparedAsset>);
|
|
57
62
|
/** The store's values of each package the paywall sells, in a language: what its texts' variables read. */
|
|
58
63
|
packages(locale: string): Record<string, PackageValues>;
|
|
59
64
|
/**
|
|
@@ -68,9 +73,9 @@ export declare class Paywall {
|
|
|
68
73
|
export declare function webPackages(offerings: Offerings, keys: readonly string[], locale: string): PricedPackage[];
|
|
69
74
|
/**
|
|
70
75
|
* The SDK's own paywall, where nothing is published: every plan the web
|
|
71
|
-
* sells (the first six)
|
|
72
|
-
* and the legal links
|
|
73
|
-
* sells nothing.
|
|
76
|
+
* sells (the first six) as a card — its product, period and price —, the
|
|
77
|
+
* purchase button and the legal links; plain, in the system's colors. Null
|
|
78
|
+
* when the web sells nothing.
|
|
74
79
|
*/
|
|
75
80
|
export declare function defaultPaywall(offerings: Offerings): PaywallDefinition | null;
|
|
76
81
|
/** This browser's installation id: who a paywall is shown to before anyone signs in — the same experiment variant every time. */
|
|
@@ -81,5 +86,14 @@ export declare function loadPaywall(api: Api, ref: string, placement: string, ch
|
|
|
81
86
|
plan: string;
|
|
82
87
|
successUrl: string;
|
|
83
88
|
cancelUrl: string;
|
|
84
|
-
}) => Promise<string>,
|
|
89
|
+
}) => Promise<string>, ask?: {
|
|
90
|
+
signal?: AbortSignal;
|
|
91
|
+
fetch?: (input: string, init?: RequestInit) => Promise<Response>;
|
|
92
|
+
/** What the app says of the person, for the placement's targeting rules. */
|
|
93
|
+
attributes?: Readonly<Record<string, PaywallAttribute>>;
|
|
94
|
+
/** The language the app shows, when it is not the browser's. */
|
|
95
|
+
locale?: string;
|
|
96
|
+
/** The app's version, when the client was given one. */
|
|
97
|
+
appVersion?: string;
|
|
98
|
+
}): Promise<Paywall | null>;
|
|
85
99
|
export {};
|
|
@@ -1,31 +1,58 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
1
|
+
import { type PreparedAsset } from './assets.js';
|
|
2
|
+
import { type PaywallDefinition, type Platform, type Appearance, type PackageValues } from './resolve.js';
|
|
3
|
+
/** A package of the catalog: what the purchase button buys. */
|
|
4
|
+
export interface PaywallPackage {
|
|
5
|
+
product: string;
|
|
6
|
+
plan: string;
|
|
7
|
+
}
|
|
8
|
+
/** What a paywall is drawn from. */
|
|
3
9
|
export interface PaywallInput {
|
|
4
10
|
definition: PaywallDefinition;
|
|
5
11
|
/** The reader's language (`tr-TR`). */
|
|
6
12
|
locale: string;
|
|
7
13
|
appearance: Appearance;
|
|
14
|
+
/** Where it is drawn: the web, unless a preview draws another platform's. */
|
|
15
|
+
platform?: Platform;
|
|
8
16
|
/** The store's values of each package, by `<product>.<plan>`; a package without any is drawn, not sold. */
|
|
9
17
|
packages: Record<string, PackageValues>;
|
|
10
|
-
/** The
|
|
18
|
+
/** The packages whose introductory offer the customer can still take. */
|
|
19
|
+
eligible?: readonly string[];
|
|
20
|
+
/** The app's own addresses of `terms` and `privacy` (https); a button or link to one is not drawn without it. */
|
|
11
21
|
links?: {
|
|
12
22
|
terms?: string;
|
|
13
23
|
privacy?: string;
|
|
14
24
|
};
|
|
25
|
+
/** The definition's assets ready to draw, by id (prepareAssets): one missing is drawn without. */
|
|
26
|
+
assets?: Record<string, PreparedAsset>;
|
|
27
|
+
/** The state to draw: a preview sets it; an app leaves it to the person. */
|
|
28
|
+
state?: PaywallState;
|
|
29
|
+
/** Entrances as components appear (true); never when the system asks for less motion. */
|
|
30
|
+
animate?: boolean;
|
|
31
|
+
/** Draws as if the system asked for less motion (a preview's choice); the system's own otherwise. */
|
|
32
|
+
reduceMotion?: boolean;
|
|
15
33
|
}
|
|
16
|
-
/**
|
|
17
|
-
export interface
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
/** What the person has done to the paywall, and its clock. */
|
|
35
|
+
export interface PaywallState {
|
|
36
|
+
/** The package the person selected. */
|
|
37
|
+
selected?: string;
|
|
38
|
+
/** Each tabs component's tab, and each switch's side, by the component's path. */
|
|
39
|
+
tabs?: Record<string, string>;
|
|
40
|
+
switches?: Record<string, boolean>;
|
|
41
|
+
/** The sheet open, by its id. */
|
|
42
|
+
sheet?: string | null;
|
|
43
|
+
/** When the paywall opened (ms since the epoch): a countdown from its opening counts from here. */
|
|
44
|
+
openedAt?: number;
|
|
45
|
+
/** A moment to draw, held still (ms since the epoch); the clock runs when absent. */
|
|
46
|
+
now?: number;
|
|
20
47
|
}
|
|
21
48
|
export interface PaywallHandlers {
|
|
22
|
-
/** The purchase button, for
|
|
49
|
+
/** The purchase button, for its package (the one selected, unless it names one); the button waits while a promise it returns runs. */
|
|
23
50
|
onPurchase(pkg: PaywallPackage): void | Promise<void>;
|
|
24
|
-
/**
|
|
51
|
+
/** A restore button; without this one is not drawn (the web restores nothing: Stripe's purchases are the account's). */
|
|
25
52
|
onRestore?(): void | Promise<void>;
|
|
26
|
-
/**
|
|
53
|
+
/** A close button; without this one is not drawn (a close inside a sheet closes the sheet). */
|
|
27
54
|
onClose?(): void;
|
|
28
|
-
/** A link the person opened; without
|
|
55
|
+
/** A link the person opened; without this the browser opens it in a new tab. */
|
|
29
56
|
onLink?(url: string): void;
|
|
30
57
|
/** Told when the person picks another package. */
|
|
31
58
|
onSelect?(pkg: PaywallPackage): void;
|
|
@@ -35,20 +62,32 @@ export interface PaywallHandlers {
|
|
|
35
62
|
close?: string;
|
|
36
63
|
restore?: string;
|
|
37
64
|
};
|
|
65
|
+
/** An offer code button: the web has none to redeem, so without this one is not drawn. */
|
|
66
|
+
onOfferCode?(): void | Promise<void>;
|
|
67
|
+
/** Told whenever the state changes: a preview keeps its controls with it. */
|
|
68
|
+
onState?(state: PaywallState): void;
|
|
69
|
+
/** A designer's canvas: a click picks the component under it (its definition path) instead of acting. */
|
|
70
|
+
editor?: {
|
|
71
|
+
onPick(path: string): void;
|
|
72
|
+
};
|
|
38
73
|
}
|
|
39
74
|
export interface PaywallView {
|
|
40
75
|
/** The package selected now. */
|
|
41
76
|
readonly selected: PaywallPackage | null;
|
|
42
77
|
/** Selects a package (`<product>.<plan>`) as the person would. */
|
|
43
78
|
select(key: string): void;
|
|
44
|
-
/** Draws it again from what changed: a new definition, the other appearance, another language, new prices. */
|
|
45
|
-
update(input: Partial<PaywallInput>): void;
|
|
46
79
|
/** Removes it from the page. */
|
|
47
80
|
destroy(): void;
|
|
81
|
+
/** Draws it again from what changed: a new definition, the other appearance, another language, new prices or assets, a state to show. */
|
|
82
|
+
update(input: Partial<PaywallInput>): void;
|
|
83
|
+
/** The state drawn now. */
|
|
84
|
+
readonly state: PaywallState;
|
|
85
|
+
/** Marks a component (by path) as a designer's canvas does; null clears it. */
|
|
86
|
+
highlight(path: string | null): void;
|
|
87
|
+
/** Plays every entrance again. */
|
|
88
|
+
replay(): void;
|
|
48
89
|
}
|
|
49
|
-
/** An https address, with a host and no credentials: the only images and links a paywall shows. */
|
|
50
|
-
export declare function isHttps(s: unknown): s is string;
|
|
51
|
-
/** Black or white, whichever reads on a color: a badge's text. */
|
|
52
|
-
export declare function readableOn(hex: string): string;
|
|
53
90
|
/** Draws a paywall into a container (its content is replaced). */
|
|
54
91
|
export declare function renderPaywall(container: HTMLElement, input: PaywallInput, handlers: PaywallHandlers): PaywallView;
|
|
92
|
+
/** The paywall's styles in its shadow root: a constructed sheet where the browser has them, a style element elsewhere. */
|
|
93
|
+
export declare function adoptStyle(doc: Document, shadow: ShadowRoot, css: string): void;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { purchases } from '../../../internal/src/modules/index.js';
|
|
2
2
|
export type PaywallDefinition = purchases.PaywallDefinition;
|
|
3
|
-
|
|
4
|
-
export declare const PAYWALL_SCHEMA = 1;
|
|
3
|
+
export type Platform = 'ios' | 'android' | 'web';
|
|
5
4
|
export type Appearance = 'light' | 'dark';
|
|
6
5
|
/** What the store gave a package, as the variables of its texts: `{{price}}` … */
|
|
7
6
|
export interface PackageValues {
|
|
@@ -12,138 +11,174 @@ export interface PackageValues {
|
|
|
12
11
|
savings?: string;
|
|
13
12
|
product_name?: string;
|
|
14
13
|
}
|
|
14
|
+
/** The schema this renderer draws: what the SDK asks the server for (X-Palbase-Paywall-Schema). */
|
|
15
|
+
export declare const PAYWALL_SCHEMA = 2;
|
|
15
16
|
export interface ResolveOptions {
|
|
16
|
-
/** The app's language (`tr-TR`)
|
|
17
|
+
/** The app's language (`tr-TR`). */
|
|
17
18
|
locale: string;
|
|
18
19
|
appearance: Appearance;
|
|
20
|
+
platform: Platform;
|
|
19
21
|
/** The store's values of each package, by `<product>.<plan>`. */
|
|
20
22
|
packages: Record<string, PackageValues>;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* one of its packages.
|
|
25
|
-
*/
|
|
23
|
+
/** The packages whose introductory offer (a trial) the customer can still take. */
|
|
24
|
+
eligible?: readonly string[];
|
|
25
|
+
/** The package the customer selected; absent, the paywall's own selection. */
|
|
26
26
|
selected?: string;
|
|
27
|
+
/** The tab shown in every tabs component, and each switch's side — the paywall's defaults when absent. */
|
|
28
|
+
tab?: string;
|
|
29
|
+
switch?: 'on' | 'off';
|
|
30
|
+
/** One tabs component's tab, or one switch's side, by the component's path (`root.children[3]`): what the person chose. */
|
|
31
|
+
tabs?: Record<string, string>;
|
|
32
|
+
switches?: Record<string, boolean>;
|
|
33
|
+
/** A countdown's time left: how long ago the paywall opened, and the moment it is drawn (ms since the epoch). */
|
|
34
|
+
openedSecondsAgo?: number;
|
|
35
|
+
now?: number;
|
|
27
36
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
text: string;
|
|
32
|
-
muted: string;
|
|
33
|
-
accent: string;
|
|
34
|
-
on_accent: string;
|
|
35
|
-
badge: string;
|
|
36
|
-
radius: number;
|
|
37
|
-
font: 'system' | 'rounded' | 'serif';
|
|
38
|
-
}
|
|
39
|
-
type Base = {
|
|
37
|
+
/** A component resolved: its type, its fields with every token and default resolved. */
|
|
38
|
+
export type ResolvedNode = {
|
|
39
|
+
type: string;
|
|
40
40
|
id?: string;
|
|
41
|
+
style?: ResolvedStyle;
|
|
42
|
+
animation?: ResolvedAnimation;
|
|
43
|
+
[field: string]: unknown;
|
|
41
44
|
};
|
|
42
|
-
export
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
export type
|
|
55
|
-
type: 'text';
|
|
56
|
-
text: string;
|
|
57
|
-
style: TextStyle;
|
|
45
|
+
export interface ResolvedEdges {
|
|
46
|
+
top: number;
|
|
47
|
+
bottom: number;
|
|
48
|
+
leading: number;
|
|
49
|
+
trailing: number;
|
|
50
|
+
}
|
|
51
|
+
export interface ResolvedCorners {
|
|
52
|
+
top_leading: number;
|
|
53
|
+
top_trailing: number;
|
|
54
|
+
bottom_leading: number;
|
|
55
|
+
bottom_trailing: number;
|
|
56
|
+
}
|
|
57
|
+
export type ResolvedStop = {
|
|
58
58
|
color: string;
|
|
59
|
-
|
|
60
|
-
weight?: 'regular' | 'medium' | 'semibold' | 'bold';
|
|
59
|
+
at: number;
|
|
61
60
|
};
|
|
62
|
-
export type
|
|
61
|
+
export type ResolvedFill = {
|
|
62
|
+
type: 'color';
|
|
63
|
+
color: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'linear';
|
|
66
|
+
angle: number;
|
|
67
|
+
stops: ResolvedStop[];
|
|
68
|
+
} | {
|
|
69
|
+
type: 'radial';
|
|
70
|
+
center_x: number;
|
|
71
|
+
center_y: number;
|
|
72
|
+
radius: number;
|
|
73
|
+
stops: ResolvedStop[];
|
|
74
|
+
} | {
|
|
63
75
|
type: 'image';
|
|
64
76
|
src: string;
|
|
65
77
|
fit: 'fit' | 'fill';
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
} | {
|
|
79
|
+
type: 'video';
|
|
80
|
+
src: string;
|
|
81
|
+
poster?: string;
|
|
82
|
+
loop: boolean;
|
|
70
83
|
};
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
export interface ResolvedStyle {
|
|
85
|
+
padding?: ResolvedEdges;
|
|
86
|
+
margin?: ResolvedEdges;
|
|
87
|
+
width?: number | string;
|
|
88
|
+
height?: number | string;
|
|
89
|
+
max_width?: number;
|
|
90
|
+
background?: ResolvedFill;
|
|
91
|
+
border?: {
|
|
92
|
+
width: number;
|
|
93
|
+
color: string;
|
|
94
|
+
};
|
|
95
|
+
corners?: ResolvedCorners;
|
|
96
|
+
shadow?: {
|
|
97
|
+
color: string;
|
|
98
|
+
radius: number;
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
};
|
|
102
|
+
opacity?: number;
|
|
103
|
+
}
|
|
104
|
+
export interface ResolvedAnimation {
|
|
105
|
+
type: 'fade' | 'slide_up' | 'slide_down' | 'slide_leading' | 'slide_trailing' | 'scale';
|
|
106
|
+
duration_ms: number;
|
|
107
|
+
delay_ms: number;
|
|
108
|
+
easing: 'ease_out' | 'ease_in_out' | 'spring';
|
|
109
|
+
}
|
|
110
|
+
export interface ResolvedTypeStyle {
|
|
111
|
+
font: string;
|
|
75
112
|
size: number;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
type: 'features';
|
|
83
|
-
items: ResolvedFeature[];
|
|
84
|
-
icon_color: string;
|
|
85
|
-
color: string;
|
|
86
|
-
spacing: number;
|
|
87
|
-
};
|
|
88
|
-
export type ResolvedPackage = {
|
|
89
|
-
product: string;
|
|
90
|
-
plan: string;
|
|
91
|
-
selected: boolean;
|
|
92
|
-
title?: string;
|
|
93
|
-
detail?: string;
|
|
94
|
-
badge?: string;
|
|
95
|
-
};
|
|
96
|
-
export type ResolvedPackages = Base & {
|
|
97
|
-
type: 'packages';
|
|
98
|
-
layout: 'list' | 'cards' | 'segmented';
|
|
99
|
-
items: ResolvedPackage[];
|
|
100
|
-
};
|
|
101
|
-
export type ResolvedPurchaseButton = Base & {
|
|
102
|
-
type: 'purchase_button';
|
|
103
|
-
text: string;
|
|
104
|
-
sub_text?: string;
|
|
105
|
-
};
|
|
106
|
-
export type ResolvedRestoreButton = Base & {
|
|
107
|
-
type: 'restore_button';
|
|
108
|
-
text?: string;
|
|
109
|
-
};
|
|
110
|
-
export type ResolvedLink = Base & {
|
|
111
|
-
type: 'link';
|
|
112
|
-
text: string;
|
|
113
|
-
url: string;
|
|
114
|
-
};
|
|
115
|
-
export type ResolvedCloseButton = Base & {
|
|
116
|
-
type: 'close_button';
|
|
117
|
-
color: string;
|
|
118
|
-
};
|
|
119
|
-
export type ResolvedSpacer = Base & {
|
|
120
|
-
type: 'spacer';
|
|
121
|
-
size?: number;
|
|
122
|
-
};
|
|
123
|
-
export type ResolvedDivider = Base & {
|
|
124
|
-
type: 'divider';
|
|
125
|
-
color: string;
|
|
126
|
-
};
|
|
127
|
-
export type ResolvedComponent = ResolvedStack | ResolvedText | ResolvedImage | ResolvedIcon | ResolvedFeatures | ResolvedPackages | ResolvedPurchaseButton | ResolvedRestoreButton | ResolvedLink | ResolvedCloseButton | ResolvedSpacer | ResolvedDivider;
|
|
128
|
-
/** The definition as drawn: the palette of the appearance and the tree, nothing left to look up. */
|
|
113
|
+
weight: number;
|
|
114
|
+
line_height?: number;
|
|
115
|
+
letter_spacing: number;
|
|
116
|
+
text_style: string;
|
|
117
|
+
}
|
|
118
|
+
/** The definition as drawn, the contract's resolved tree. */
|
|
129
119
|
export interface ResolvedPaywall {
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
selected: string;
|
|
121
|
+
theme: {
|
|
122
|
+
colors: Record<string, string>;
|
|
123
|
+
typography: Record<string, ResolvedTypeStyle>;
|
|
124
|
+
radii: Record<string, number>;
|
|
125
|
+
spacing: Record<string, number>;
|
|
126
|
+
};
|
|
127
|
+
header?: ResolvedNode;
|
|
128
|
+
root?: ResolvedNode;
|
|
129
|
+
footer?: ResolvedNode;
|
|
130
|
+
sheets?: Record<string, ResolvedNode>;
|
|
131
|
+
}
|
|
132
|
+
/** Beside the tree: where in the definition each node is (its path, as the server's problems name it), and what is not part of the tree. */
|
|
133
|
+
export interface Resolution {
|
|
134
|
+
tree: ResolvedPaywall;
|
|
135
|
+
/** A node's path in the definition: `root.children[2]`, `sheets.offer.root`. */
|
|
136
|
+
pathOf(node: object): string | undefined;
|
|
137
|
+
/** The tab shown in each tabs component and each switch's side, by path. */
|
|
138
|
+
tabs: Record<string, string>;
|
|
139
|
+
switches: Record<string, boolean>;
|
|
140
|
+
/** Each sheet's title, in the language drawn. */
|
|
141
|
+
sheetTitles: Record<string, string>;
|
|
142
|
+
/** The time a counting countdown has left, by path: the renderer ticks while any does. */
|
|
143
|
+
countdowns: Record<string, number>;
|
|
144
|
+
/** The language the definition is drawn in. */
|
|
145
|
+
language: string;
|
|
132
146
|
}
|
|
133
|
-
|
|
147
|
+
type Value = 'plain' | 'color' | 'textColor' | 'spacing' | 'radius';
|
|
148
|
+
type Field = {
|
|
149
|
+
kind: 'value';
|
|
150
|
+
value: Value;
|
|
151
|
+
def?: unknown;
|
|
152
|
+
required?: boolean;
|
|
153
|
+
} | {
|
|
154
|
+
kind: 'text';
|
|
155
|
+
required?: boolean;
|
|
156
|
+
} | {
|
|
157
|
+
kind: 'list';
|
|
158
|
+
item: string;
|
|
159
|
+
required?: boolean;
|
|
160
|
+
} | {
|
|
161
|
+
kind: 'object';
|
|
162
|
+
item: string;
|
|
163
|
+
required?: boolean;
|
|
164
|
+
} | {
|
|
165
|
+
kind: 'component';
|
|
166
|
+
required?: boolean;
|
|
167
|
+
} | {
|
|
168
|
+
kind: 'components';
|
|
169
|
+
} | {
|
|
170
|
+
kind: 'edges' | 'corners' | 'fill';
|
|
171
|
+
};
|
|
172
|
+
type Spec = Record<string, Field>;
|
|
173
|
+
export declare const COMPONENT_FIELDS: Record<string, Spec>;
|
|
174
|
+
/** The components a definition has, by type. */
|
|
134
175
|
export declare const PAYWALL_COMPONENTS: readonly string[];
|
|
135
|
-
/**
|
|
136
|
-
export declare function
|
|
137
|
-
/** Every package a definition sells, `<product>.<plan>`, in its
|
|
138
|
-
export declare function packagesOf(
|
|
139
|
-
/** The language a definition is drawn in for an app's: its own, else without the region, else the default. */
|
|
140
|
-
export declare function paywallLanguage(definition: PaywallDefinition, locale: string): string;
|
|
176
|
+
/** {{countdown}} and its parts for a time left, in seconds. */
|
|
177
|
+
export declare function countdownValues(left: number): Record<string, string>;
|
|
178
|
+
/** Every package a definition sells, `<product>.<plan>`, in the order it names them: the header, the root, the footer, then its sheets. */
|
|
179
|
+
export declare function packagesOf(definition: PaywallDefinition): string[];
|
|
141
180
|
/** A definition as drawn (contracts/paywall/README.md). */
|
|
142
181
|
export declare function resolve(definition: PaywallDefinition, opts: ResolveOptions): ResolvedPaywall;
|
|
143
|
-
/**
|
|
144
|
-
|
|
145
|
-
* two resolutions of one definition line up child by child, so the renderer
|
|
146
|
-
* changes only what a new selection changed.
|
|
147
|
-
*/
|
|
148
|
-
export declare function resolveAligned(definition: PaywallDefinition, opts: ResolveOptions): ResolvedPaywall;
|
|
182
|
+
/** The same, with each node's path in the definition and the state the renderer keeps. */
|
|
183
|
+
export declare function resolution(definition: PaywallDefinition, opts: ResolveOptions): Resolution;
|
|
149
184
|
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { purchases as purchasesModule } from '../../internal/src/modules/index.js';
|
|
2
|
-
import type { Transport } from '../../internal/src/transport.js';
|
|
2
|
+
import type { Fetch, Transport } from '../../internal/src/transport.js';
|
|
3
3
|
import type { SessionManager } from './session.js';
|
|
4
4
|
import type { RealtimeSocket } from './socket.js';
|
|
5
|
+
import type { PaywallAttribute } from './paywall/attributes.js';
|
|
5
6
|
import { type Paywall } from './paywall/placement.js';
|
|
6
7
|
type P = typeof purchasesModule;
|
|
7
8
|
export type CustomerInfo = purchasesModule.CustomerInfo;
|
|
@@ -15,26 +16,44 @@ export declare class Purchases {
|
|
|
15
16
|
private session;
|
|
16
17
|
private socket;
|
|
17
18
|
private ref;
|
|
19
|
+
/** What a paywall's assets are downloaded with: the app's fetch, when it gave one. */
|
|
20
|
+
private fetch;
|
|
21
|
+
/** The app's version, when it gave one: a paywall's request says it. */
|
|
22
|
+
private appVersion;
|
|
18
23
|
private listeners;
|
|
19
24
|
private watch;
|
|
20
25
|
private following;
|
|
21
26
|
/** What listeners were last told: undefined until the first read (or sign-out) is known. */
|
|
22
27
|
private last;
|
|
23
|
-
constructor(transport: Transport, session: SessionManager, socket: RealtimeSocket, ref: string);
|
|
28
|
+
constructor(transport: Transport, session: SessionManager, socket: RealtimeSocket, ref: string, fetch?: Fetch, appVersion?: string);
|
|
24
29
|
/** Everything the signed-in customer has, read now (the first read makes the user a customer). */
|
|
25
30
|
me(): Promise<CustomerInfo>;
|
|
26
31
|
/** The paywall's catalog: each product's text and price on a channel — the web's unless another is named. */
|
|
27
32
|
offerings(channel?: 'ios' | 'android' | 'web'): Promise<Offerings>;
|
|
28
33
|
/**
|
|
29
34
|
* The paywall the project shows at a placement — the place in the app it
|
|
30
|
-
* names (`onboarding`, `settings`) — to draw with render()
|
|
31
|
-
* is the newest published in a
|
|
35
|
+
* names (`onboarding`, `settings`) — to draw with render(), its assets
|
|
36
|
+
* downloaded and checked first. Its version is the newest published in a
|
|
37
|
+
* schema this SDK draws (an experiment's
|
|
32
38
|
* variant while one runs there, the same for this person every time); the
|
|
33
39
|
* browser keeps it, to ask again with its ETag and to show offline. With
|
|
34
40
|
* nothing published there it is the SDK's own, of every plan the web
|
|
35
41
|
* sells; null when the web sells nothing.
|
|
42
|
+
*
|
|
43
|
+
* Which paywall a placement shows may depend on its targeting rules: they
|
|
44
|
+
* read what the request says of the app (the web, the SDK, the version the
|
|
45
|
+
* client was made with, where it is asked from), its language — the
|
|
46
|
+
* browser's, or `locale` when the app shows another — and `attributes`,
|
|
47
|
+
* what the app says of the person
|
|
48
|
+
* (`{ plan: 'free', sessions: 12 }`: texts, numbers, yes/no). An attribute
|
|
49
|
+
* the module would refuse throws `invalid_attributes` before anything is
|
|
50
|
+
* asked. Targeting picks what to show; it is not access control: the
|
|
51
|
+
* country, the attributes and the versions are what the app says of
|
|
52
|
+
* itself, so no price or region entitlement may hang on them.
|
|
36
53
|
*/
|
|
37
54
|
paywall(placement: string, opts?: {
|
|
55
|
+
attributes?: Readonly<Record<string, PaywallAttribute>>;
|
|
56
|
+
locale?: string;
|
|
38
57
|
signal?: AbortSignal;
|
|
39
58
|
}): Promise<Paywall | null>;
|
|
40
59
|
/**
|