@proveanything/smartlinks 2.0.47 → 2.0.48
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/dist/api/comms.d.ts +16 -1
- package/dist/api/comms.js +26 -4
- package/dist/api/functions.js +21 -3
- package/dist/context.d.ts +5 -0
- package/dist/context.js +1 -0
- package/dist/docs/API_SUMMARY.md +81 -34
- package/dist/docs/comms.md +22 -1
- package/dist/docs/deploying-apps.md +11 -0
- package/dist/docs/widgets.md +72 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/openapi.yaml +71 -33
- package/dist/types/appManifest.d.ts +20 -0
- package/dist/types/comms.d.ts +24 -7
- package/dist/widgetStyle.d.ts +37 -0
- package/dist/widgetStyle.js +64 -0
- package/docs/API_SUMMARY.md +81 -34
- package/docs/comms.md +22 -1
- package/docs/deploying-apps.md +11 -0
- package/docs/widgets.md +72 -0
- package/openapi.yaml +71 -33
- package/package.json +1 -1
package/dist/openapi.yaml
CHANGED
|
@@ -74,8 +74,6 @@ tags:
|
|
|
74
74
|
description: Product facet querying and aggregation.
|
|
75
75
|
- name: form
|
|
76
76
|
description: Form definitions and submissions.
|
|
77
|
-
- name: functions
|
|
78
|
-
description: functions API
|
|
79
77
|
- name: integrations
|
|
80
78
|
description: Third-party integration flows and imports.
|
|
81
79
|
- name: interactions
|
|
@@ -10024,26 +10022,6 @@ paths:
|
|
|
10024
10022
|
description: Unauthorized
|
|
10025
10023
|
404:
|
|
10026
10024
|
description: Not found
|
|
10027
|
-
/functions:
|
|
10028
|
-
get:
|
|
10029
|
-
tags:
|
|
10030
|
-
- functions
|
|
10031
|
-
summary: List the public functions available for a collection (discovery).
|
|
10032
|
-
operationId: functions_list
|
|
10033
|
-
security: []
|
|
10034
|
-
responses:
|
|
10035
|
-
200:
|
|
10036
|
-
description: Success
|
|
10037
|
-
content:
|
|
10038
|
-
application/json:
|
|
10039
|
-
schema:
|
|
10040
|
-
$ref: "#/components/schemas/FunctionListResponse"
|
|
10041
|
-
400:
|
|
10042
|
-
description: Bad request
|
|
10043
|
-
401:
|
|
10044
|
-
description: Unauthorized
|
|
10045
|
-
404:
|
|
10046
|
-
description: Not found
|
|
10047
10025
|
/platform/location:
|
|
10048
10026
|
post:
|
|
10049
10027
|
tags:
|
|
@@ -11360,6 +11338,40 @@ paths:
|
|
|
11360
11338
|
description: Unauthorized
|
|
11361
11339
|
404:
|
|
11362
11340
|
description: Not found
|
|
11341
|
+
/public/collection/{collectionId}/comm/signup:
|
|
11342
|
+
post:
|
|
11343
|
+
tags:
|
|
11344
|
+
- comms
|
|
11345
|
+
summary: "Public: sign an email address up for topics (a newsletter, updates) — works signed out."
|
|
11346
|
+
operationId: comms_signup
|
|
11347
|
+
security: []
|
|
11348
|
+
parameters:
|
|
11349
|
+
- name: collectionId
|
|
11350
|
+
in: path
|
|
11351
|
+
required: true
|
|
11352
|
+
schema:
|
|
11353
|
+
type: string
|
|
11354
|
+
responses:
|
|
11355
|
+
200:
|
|
11356
|
+
description: Success
|
|
11357
|
+
content:
|
|
11358
|
+
application/json:
|
|
11359
|
+
schema:
|
|
11360
|
+
type: object
|
|
11361
|
+
additionalProperties: true
|
|
11362
|
+
400:
|
|
11363
|
+
description: Bad request
|
|
11364
|
+
401:
|
|
11365
|
+
description: Unauthorized
|
|
11366
|
+
404:
|
|
11367
|
+
description: Not found
|
|
11368
|
+
requestBody:
|
|
11369
|
+
required: true
|
|
11370
|
+
content:
|
|
11371
|
+
application/json:
|
|
11372
|
+
schema:
|
|
11373
|
+
type: object
|
|
11374
|
+
additionalProperties: true
|
|
11363
11375
|
/public/collection/{collectionId}/comm/sms/register:
|
|
11364
11376
|
post:
|
|
11365
11377
|
tags:
|
|
@@ -18888,8 +18900,24 @@ components:
|
|
|
18888
18900
|
settings:
|
|
18889
18901
|
type: object
|
|
18890
18902
|
additionalProperties: true
|
|
18903
|
+
styleSupport:
|
|
18904
|
+
$ref: "#/components/schemas/WidgetStyleSupport"
|
|
18891
18905
|
required:
|
|
18892
18906
|
- name
|
|
18907
|
+
WidgetStyleSupport:
|
|
18908
|
+
type: object
|
|
18909
|
+
properties:
|
|
18910
|
+
accent:
|
|
18911
|
+
type: boolean
|
|
18912
|
+
text:
|
|
18913
|
+
type: boolean
|
|
18914
|
+
textAlign:
|
|
18915
|
+
type: boolean
|
|
18916
|
+
background:
|
|
18917
|
+
type: string
|
|
18918
|
+
enum:
|
|
18919
|
+
- transparent
|
|
18920
|
+
- own
|
|
18893
18921
|
AppManifestWidgets:
|
|
18894
18922
|
type: object
|
|
18895
18923
|
properties:
|
|
@@ -23526,7 +23554,6 @@ components:
|
|
|
23526
23554
|
type: object
|
|
23527
23555
|
additionalProperties: true
|
|
23528
23556
|
required:
|
|
23529
|
-
- contactId
|
|
23530
23557
|
- endpoint
|
|
23531
23558
|
- keys
|
|
23532
23559
|
CommsSettings:
|
|
@@ -23618,8 +23645,6 @@ components:
|
|
|
23618
23645
|
$ref: "#/components/schemas/BroadcastChannel"
|
|
23619
23646
|
token:
|
|
23620
23647
|
type: string
|
|
23621
|
-
required:
|
|
23622
|
-
- contactId
|
|
23623
23648
|
UnsubscribeResponse:
|
|
23624
23649
|
type: object
|
|
23625
23650
|
properties:
|
|
@@ -23628,6 +23653,27 @@ components:
|
|
|
23628
23653
|
additionalProperties: true
|
|
23629
23654
|
required:
|
|
23630
23655
|
- ok
|
|
23656
|
+
CommsSignupRequest:
|
|
23657
|
+
type: object
|
|
23658
|
+
properties:
|
|
23659
|
+
email:
|
|
23660
|
+
type: string
|
|
23661
|
+
topics:
|
|
23662
|
+
type: array
|
|
23663
|
+
items:
|
|
23664
|
+
type: string
|
|
23665
|
+
firstName:
|
|
23666
|
+
type: string
|
|
23667
|
+
required:
|
|
23668
|
+
- email
|
|
23669
|
+
CommsSignupResponse:
|
|
23670
|
+
type: object
|
|
23671
|
+
properties:
|
|
23672
|
+
ok:
|
|
23673
|
+
type: object
|
|
23674
|
+
additionalProperties: true
|
|
23675
|
+
required:
|
|
23676
|
+
- ok
|
|
23631
23677
|
CommsConsentUpsertRequest:
|
|
23632
23678
|
type: object
|
|
23633
23679
|
properties:
|
|
@@ -23641,8 +23687,6 @@ components:
|
|
|
23641
23687
|
type: boolean
|
|
23642
23688
|
topicsByChannel:
|
|
23643
23689
|
$ref: "#/components/schemas/BroadcastChannel"
|
|
23644
|
-
required:
|
|
23645
|
-
- contactId
|
|
23646
23690
|
CommsPreferencesUpsertRequest:
|
|
23647
23691
|
type: object
|
|
23648
23692
|
properties:
|
|
@@ -23659,8 +23703,6 @@ components:
|
|
|
23659
23703
|
type: boolean
|
|
23660
23704
|
topicsByChannel:
|
|
23661
23705
|
$ref: "#/components/schemas/BroadcastChannel"
|
|
23662
|
-
required:
|
|
23663
|
-
- contactId
|
|
23664
23706
|
CommsSubscribeRequest:
|
|
23665
23707
|
type: object
|
|
23666
23708
|
properties:
|
|
@@ -23674,7 +23716,6 @@ components:
|
|
|
23674
23716
|
source:
|
|
23675
23717
|
type: string
|
|
23676
23718
|
required:
|
|
23677
|
-
- contactId
|
|
23678
23719
|
- subject
|
|
23679
23720
|
- subscribe
|
|
23680
23721
|
CommsSubscribeResponse:
|
|
@@ -23697,7 +23738,6 @@ components:
|
|
|
23697
23738
|
productId:
|
|
23698
23739
|
type: string
|
|
23699
23740
|
required:
|
|
23700
|
-
- contactId
|
|
23701
23741
|
- subjectType
|
|
23702
23742
|
- subjectId
|
|
23703
23743
|
CommsSubscriptionCheckResponse:
|
|
@@ -23715,8 +23755,6 @@ components:
|
|
|
23715
23755
|
type: string
|
|
23716
23756
|
type:
|
|
23717
23757
|
$ref: "#/components/schemas/BroadcastChannel"
|
|
23718
|
-
required:
|
|
23719
|
-
- contactId
|
|
23720
23758
|
CommsListMethodsResponse:
|
|
23721
23759
|
type: object
|
|
23722
23760
|
properties:
|
|
@@ -53,6 +53,26 @@ export interface AppWidgetComponent {
|
|
|
53
53
|
};
|
|
54
54
|
/** JSON-Schema-style settings the widget accepts */
|
|
55
55
|
settings?: Record<string, any>;
|
|
56
|
+
/**
|
|
57
|
+
* What styling this widget honours when a host places it (Link Page, Hub…). The host shows only
|
|
58
|
+
* these controls and sets the matching `--sl-widget-*` variables. Missing = layout controls only.
|
|
59
|
+
* See docs/widgets.md → "Style support".
|
|
60
|
+
*/
|
|
61
|
+
styleSupport?: WidgetStyleSupport;
|
|
62
|
+
}
|
|
63
|
+
/** A widget's declared styling support — see {@link AppWidgetComponent.styleSupport}. */
|
|
64
|
+
export interface WidgetStyleSupport {
|
|
65
|
+
/** Widget reads --sl-widget-accent / --sl-widget-accent-contrast for buttons, links, focus, active states. */
|
|
66
|
+
accent?: boolean;
|
|
67
|
+
/** Widget reads --sl-widget-text for its body text, titles and secondary text. */
|
|
68
|
+
text?: boolean;
|
|
69
|
+
/** Widget's titles and messages use `text-align: inherit`. */
|
|
70
|
+
textAlign?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* 'transparent' (recommended): the widget draws no background, so the host's Background shows.
|
|
73
|
+
* 'own': the widget paints its own card; the host hides Background (padding/border/radius stay).
|
|
74
|
+
*/
|
|
75
|
+
background?: 'transparent' | 'own';
|
|
56
76
|
}
|
|
57
77
|
/** Widget bundle declaration in `app.manifest.json`. */
|
|
58
78
|
export interface AppManifestWidgets {
|
package/dist/types/comms.d.ts
CHANGED
|
@@ -116,7 +116,8 @@ export interface PushSubscribeResponse {
|
|
|
116
116
|
id: string;
|
|
117
117
|
}
|
|
118
118
|
export interface RegisterPushMethodRequest {
|
|
119
|
-
|
|
119
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
120
|
+
contactId?: string;
|
|
120
121
|
endpoint: string;
|
|
121
122
|
keys: {
|
|
122
123
|
p256dh: string;
|
|
@@ -168,7 +169,8 @@ export interface CommsPublicTopicsResponse {
|
|
|
168
169
|
topics: Record<string, TopicConfig>;
|
|
169
170
|
}
|
|
170
171
|
export interface UnsubscribeQuery {
|
|
171
|
-
|
|
172
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
173
|
+
contactId?: string;
|
|
172
174
|
topic?: string;
|
|
173
175
|
channel?: BroadcastChannel;
|
|
174
176
|
token?: string;
|
|
@@ -180,16 +182,28 @@ export interface UnsubscribeResponse {
|
|
|
180
182
|
topics?: Record<string, boolean>;
|
|
181
183
|
};
|
|
182
184
|
}
|
|
185
|
+
export interface CommsSignupRequest {
|
|
186
|
+
email: string;
|
|
187
|
+
/** Topic ids from the collection's comm settings (e.g. ["newsletter"]). */
|
|
188
|
+
topics?: string[];
|
|
189
|
+
firstName?: string;
|
|
190
|
+
}
|
|
191
|
+
export interface CommsSignupResponse {
|
|
192
|
+
ok: true;
|
|
193
|
+
pending: true;
|
|
194
|
+
}
|
|
183
195
|
export type ConsentChannels = Partial<Record<BroadcastChannel, boolean>>;
|
|
184
196
|
type SubjectType = import('./contact.js').SubjectType;
|
|
185
197
|
export interface CommsConsentUpsertRequest {
|
|
186
|
-
|
|
198
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
199
|
+
contactId?: string;
|
|
187
200
|
channels?: ConsentChannels;
|
|
188
201
|
topics?: Record<string, boolean>;
|
|
189
202
|
topicsByChannel?: Partial<Record<BroadcastChannel, Record<string, boolean>>>;
|
|
190
203
|
}
|
|
191
204
|
export interface CommsPreferencesUpsertRequest {
|
|
192
|
-
|
|
205
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
206
|
+
contactId?: string;
|
|
193
207
|
subject?: {
|
|
194
208
|
type: SubjectType;
|
|
195
209
|
id: string;
|
|
@@ -200,7 +214,8 @@ export interface CommsPreferencesUpsertRequest {
|
|
|
200
214
|
topicsByChannel?: Partial<Record<BroadcastChannel, Record<string, boolean>>>;
|
|
201
215
|
}
|
|
202
216
|
export interface CommsSubscribeRequest {
|
|
203
|
-
|
|
217
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
218
|
+
contactId?: string;
|
|
204
219
|
subject: {
|
|
205
220
|
type: SubjectType;
|
|
206
221
|
id: string;
|
|
@@ -214,7 +229,8 @@ export interface CommsSubscribeResponse {
|
|
|
214
229
|
subscriptionId: string;
|
|
215
230
|
}
|
|
216
231
|
export interface CommsSubscriptionCheckQuery {
|
|
217
|
-
|
|
232
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
233
|
+
contactId?: string;
|
|
218
234
|
subjectType: SubjectType;
|
|
219
235
|
subjectId: string;
|
|
220
236
|
productId?: string;
|
|
@@ -224,7 +240,8 @@ export interface CommsSubscriptionCheckResponse {
|
|
|
224
240
|
subscribed: boolean;
|
|
225
241
|
}
|
|
226
242
|
export interface CommsListMethodsQuery {
|
|
227
|
-
|
|
243
|
+
/** Optional: defaults to the signed-in user's own contact. Only collection admins may name another contact. */
|
|
244
|
+
contactId?: string;
|
|
228
245
|
type?: BroadcastChannel;
|
|
229
246
|
}
|
|
230
247
|
export interface CommsListMethodsResponse {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { WidgetStyleSupport } from './types/appManifest.js';
|
|
2
|
+
/** The styling a person chose for one placed widget (host side). Colours are hex. */
|
|
3
|
+
export interface WidgetStyling {
|
|
4
|
+
accent?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
/** Corner radius in px. */
|
|
7
|
+
radius?: number;
|
|
8
|
+
}
|
|
9
|
+
/** The CSS variables a host sets on a widget's box (only the ones chosen). */
|
|
10
|
+
export declare const WIDGET_STYLE_VARS: {
|
|
11
|
+
readonly accent: "--sl-widget-accent";
|
|
12
|
+
readonly accentContrast: "--sl-widget-accent-contrast";
|
|
13
|
+
readonly text: "--sl-widget-text";
|
|
14
|
+
readonly radius: "--sl-widget-radius";
|
|
15
|
+
};
|
|
16
|
+
/** Readable text colour on a background: near-black or white, whichever contrasts more. */
|
|
17
|
+
export declare function readableOn(hex: string): '#111111' | '#ffffff';
|
|
18
|
+
/**
|
|
19
|
+
* Host helper: the `--sl-widget-*` variables for a widget's box, from the styling chosen — and,
|
|
20
|
+
* when `support` is given, only the ones that widget declared (a host shouldn't set what the widget
|
|
21
|
+
* ignores). The accent's readable text colour is computed here so every host agrees.
|
|
22
|
+
*/
|
|
23
|
+
export declare function widgetStyleVars(styling: WidgetStyling, support?: WidgetStyleSupport | null): Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Host helper: which styling controls to offer for a widget. Layout controls (width, alignment,
|
|
26
|
+
* padding, scale, radius, border) are always offered — the host owns the box. Colour controls only
|
|
27
|
+
* when the widget declared them; Background unless the widget paints its own card.
|
|
28
|
+
* `styleSupport` missing (older widgets) → layout only, and `colours: false` so the host can say
|
|
29
|
+
* "This widget doesn't offer colour customisation."
|
|
30
|
+
*/
|
|
31
|
+
export declare function widgetStyleControls(support?: WidgetStyleSupport | null): {
|
|
32
|
+
accent: boolean;
|
|
33
|
+
text: boolean;
|
|
34
|
+
textAlign: boolean;
|
|
35
|
+
background: boolean;
|
|
36
|
+
colours: boolean;
|
|
37
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Widget style support — the contract between a widget and the page it's dropped into (Link Page,
|
|
2
|
+
// Hub, any host that places widgets). The widget declares what it supports in its manifest entry
|
|
3
|
+
// (`widgets.components[].styleSupport`); the host shows only those styling controls and sets the
|
|
4
|
+
// `--sl-widget-*` variables below on the widget's box. See docs/widgets.md → "Style support".
|
|
5
|
+
/** The CSS variables a host sets on a widget's box (only the ones chosen). */
|
|
6
|
+
export const WIDGET_STYLE_VARS = {
|
|
7
|
+
accent: '--sl-widget-accent',
|
|
8
|
+
accentContrast: '--sl-widget-accent-contrast',
|
|
9
|
+
text: '--sl-widget-text',
|
|
10
|
+
radius: '--sl-widget-radius',
|
|
11
|
+
};
|
|
12
|
+
function luminance(hex) {
|
|
13
|
+
const m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
14
|
+
if (!m)
|
|
15
|
+
return null;
|
|
16
|
+
const h = m[1].length === 3 ? m[1].split('').map((c) => c + c).join('') : m[1];
|
|
17
|
+
const [r, g, b] = [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255).map((c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));
|
|
18
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
19
|
+
}
|
|
20
|
+
/** Readable text colour on a background: near-black or white, whichever contrasts more. */
|
|
21
|
+
export function readableOn(hex) {
|
|
22
|
+
const l = luminance(hex);
|
|
23
|
+
if (l == null)
|
|
24
|
+
return '#ffffff';
|
|
25
|
+
const contrastWhite = 1.05 / (l + 0.05);
|
|
26
|
+
const contrastDark = (l + 0.05) / (luminance('#111111') + 0.05);
|
|
27
|
+
return contrastDark >= contrastWhite ? '#111111' : '#ffffff';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Host helper: the `--sl-widget-*` variables for a widget's box, from the styling chosen — and,
|
|
31
|
+
* when `support` is given, only the ones that widget declared (a host shouldn't set what the widget
|
|
32
|
+
* ignores). The accent's readable text colour is computed here so every host agrees.
|
|
33
|
+
*/
|
|
34
|
+
export function widgetStyleVars(styling, support) {
|
|
35
|
+
const out = {};
|
|
36
|
+
const allows = (k) => !support || support[k] === true;
|
|
37
|
+
if (styling.accent && allows('accent')) {
|
|
38
|
+
out[WIDGET_STYLE_VARS.accent] = styling.accent;
|
|
39
|
+
out[WIDGET_STYLE_VARS.accentContrast] = readableOn(styling.accent);
|
|
40
|
+
}
|
|
41
|
+
if (styling.text && allows('text'))
|
|
42
|
+
out[WIDGET_STYLE_VARS.text] = styling.text;
|
|
43
|
+
if (typeof styling.radius === 'number' && Number.isFinite(styling.radius))
|
|
44
|
+
out[WIDGET_STYLE_VARS.radius] = `${styling.radius}px`;
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Host helper: which styling controls to offer for a widget. Layout controls (width, alignment,
|
|
49
|
+
* padding, scale, radius, border) are always offered — the host owns the box. Colour controls only
|
|
50
|
+
* when the widget declared them; Background unless the widget paints its own card.
|
|
51
|
+
* `styleSupport` missing (older widgets) → layout only, and `colours: false` so the host can say
|
|
52
|
+
* "This widget doesn't offer colour customisation."
|
|
53
|
+
*/
|
|
54
|
+
export function widgetStyleControls(support) {
|
|
55
|
+
if (!support)
|
|
56
|
+
return { accent: false, text: false, textAlign: false, background: true, colours: false };
|
|
57
|
+
return {
|
|
58
|
+
accent: support.accent === true,
|
|
59
|
+
text: support.text === true,
|
|
60
|
+
textAlign: support.textAlign === true,
|
|
61
|
+
background: support.background !== 'own',
|
|
62
|
+
colours: support.accent === true || support.text === true,
|
|
63
|
+
};
|
|
64
|
+
}
|