@proveanything/smartlinks 2.0.47 → 2.0.49

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/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 {
@@ -116,7 +116,8 @@ export interface PushSubscribeResponse {
116
116
  id: string;
117
117
  }
118
118
  export interface RegisterPushMethodRequest {
119
- contactId: string;
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
- contactId: string;
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
- contactId: string;
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
- contactId: string;
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
- contactId: string;
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
- contactId: string;
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
- contactId: string;
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
+ }