@proveanything/smartlinks 2.0.55 → 2.0.57

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/http.js CHANGED
@@ -210,6 +210,9 @@ function shouldSkipCache(path) {
210
210
  // Never cache auth, account, or user-identity endpoints — they depend on session state.
211
211
  if (/\/(auth|account)\//i.test(path))
212
212
  return true;
213
+ // Realtime tokens are single-use (a reused one is rejected by the provider) — never cache them.
214
+ if (/\/(push\/token|realtime\/)/i.test(path))
215
+ return true;
213
216
  // Never cache /me endpoints (contact/me, loyalty/me, etc.) — always user-specific.
214
217
  if (/\/me(\?|$)/i.test(path))
215
218
  return true;
package/dist/openapi.yaml CHANGED
@@ -123,7 +123,7 @@ paths:
123
123
  get:
124
124
  tags:
125
125
  - realtime
126
- summary: Get an Ably token for admin real-time communication.
126
+ summary: (subscribe only).
127
127
  operationId: realtime_getAdminToken
128
128
  security:
129
129
  - bearerAuth: []
@@ -13960,7 +13960,7 @@ paths:
13960
13960
  get:
13961
13961
  tags:
13962
13962
  - realtime
13963
- summary: realtime.getPublicToken
13963
+ summary: "`collection:{collectionId}:*` (subscribe; publish only for the collection's admins)."
13964
13964
  operationId: realtime_getPublicToken
13965
13965
  security: []
13966
13966
  parameters:
@@ -14018,6 +14018,33 @@ paths:
14018
14018
  description: Unauthorized
14019
14019
  404:
14020
14020
  description: Not found
14021
+ /public/realtime/publish:
14022
+ post:
14023
+ tags:
14024
+ - realtime
14025
+ summary: "One of your app's declared channels (manifest `realtime.channels`)."
14026
+ operationId: realtime_channel
14027
+ security: []
14028
+ responses:
14029
+ 200:
14030
+ description: Success
14031
+ content:
14032
+ application/json:
14033
+ schema:
14034
+ type: object
14035
+ additionalProperties: true
14036
+ 400:
14037
+ description: Bad request
14038
+ 401:
14039
+ description: Unauthorized
14040
+ 404:
14041
+ description: Not found
14042
+ requestBody:
14043
+ required: true
14044
+ content:
14045
+ application/json:
14046
+ schema:
14047
+ $ref: "#/components/schemas/RealtimeScope"
14021
14048
  /public/tags/{tagId}:
14022
14049
  get:
14023
14050
  tags:
@@ -19618,10 +19645,15 @@ components:
19618
19645
  $ref: "#/components/schemas/AppManifestExecutor"
19619
19646
  functions:
19620
19647
  $ref: "#/components/schemas/AppManifestFunctions"
19648
+ realtime:
19649
+ type: object
19650
+ additionalProperties: true
19621
19651
  data:
19622
19652
  $ref: "#/components/schemas/AppDataDeclaration"
19623
19653
  headless:
19624
19654
  $ref: "#/components/schemas/AppHeadlessDeclaration"
19655
+ connector:
19656
+ $ref: "#/components/schemas/AppConnectorDeclaration"
19625
19657
  required:
19626
19658
  - name
19627
19659
  - version
@@ -19629,6 +19661,268 @@ components:
19629
19661
  - function
19630
19662
  - files
19631
19663
  - components
19664
+ ConnectorConnectionField:
19665
+ type: object
19666
+ properties:
19667
+ name:
19668
+ type: string
19669
+ label:
19670
+ type: string
19671
+ description:
19672
+ type: string
19673
+ secret:
19674
+ type: string
19675
+ required:
19676
+ type: boolean
19677
+ type:
19678
+ type: string
19679
+ enum:
19680
+ - text
19681
+ - url
19682
+ - select
19683
+ - number
19684
+ - boolean
19685
+ options:
19686
+ type: array
19687
+ items:
19688
+ type: object
19689
+ additionalProperties: true
19690
+ placeholder:
19691
+ type: string
19692
+ required:
19693
+ - name
19694
+ - label
19695
+ ConnectorPreset:
19696
+ type: object
19697
+ properties:
19698
+ id:
19699
+ type: string
19700
+ title:
19701
+ type: string
19702
+ description:
19703
+ type: string
19704
+ direction:
19705
+ type: string
19706
+ enum:
19707
+ - inbound
19708
+ - outbound
19709
+ entity:
19710
+ type: string
19711
+ flow:
19712
+ type: object
19713
+ additionalProperties: true
19714
+ required:
19715
+ - id
19716
+ - title
19717
+ - direction
19718
+ - entity
19719
+ ConnectorPanel:
19720
+ type: object
19721
+ properties:
19722
+ id:
19723
+ type: string
19724
+ title:
19725
+ type: string
19726
+ component:
19727
+ type: string
19728
+ required:
19729
+ - id
19730
+ - title
19731
+ - component
19732
+ AppConnectorDeclaration:
19733
+ type: object
19734
+ properties:
19735
+ provider:
19736
+ type: string
19737
+ title:
19738
+ type: string
19739
+ directions:
19740
+ type: array
19741
+ items:
19742
+ type: string
19743
+ enum:
19744
+ - inbound
19745
+ - outbound
19746
+ entities:
19747
+ type: array
19748
+ items:
19749
+ type: string
19750
+ connection:
19751
+ type: object
19752
+ additionalProperties: true
19753
+ settings:
19754
+ type: object
19755
+ additionalProperties: true
19756
+ presets:
19757
+ type: array
19758
+ items:
19759
+ $ref: "#/components/schemas/ConnectorPreset"
19760
+ functions:
19761
+ type: object
19762
+ additionalProperties: true
19763
+ testConnection:
19764
+ type: string
19765
+ describeTarget:
19766
+ type: string
19767
+ sample:
19768
+ type: string
19769
+ transform:
19770
+ type: string
19771
+ send:
19772
+ type: string
19773
+ fetch:
19774
+ type: string
19775
+ panels:
19776
+ type: array
19777
+ items:
19778
+ $ref: "#/components/schemas/ConnectorPanel"
19779
+ aiGuide:
19780
+ type: string
19781
+ required:
19782
+ - provider
19783
+ - directions
19784
+ - entities
19785
+ - functions
19786
+ ConnectorInstallation:
19787
+ type: object
19788
+ properties:
19789
+ collectionId:
19790
+ type: string
19791
+ appId:
19792
+ type: string
19793
+ flowId:
19794
+ type: string
19795
+ connection:
19796
+ type: object
19797
+ additionalProperties: true
19798
+ settings:
19799
+ type: object
19800
+ additionalProperties: true
19801
+ required:
19802
+ - collectionId
19803
+ - appId
19804
+ - connection
19805
+ - settings
19806
+ ConnectorTestResult:
19807
+ type: object
19808
+ properties:
19809
+ ok:
19810
+ type: boolean
19811
+ message:
19812
+ type: string
19813
+ required:
19814
+ - ok
19815
+ - message
19816
+ ConnectorTargetField:
19817
+ type: object
19818
+ properties:
19819
+ path:
19820
+ type: string
19821
+ label:
19822
+ type: string
19823
+ type:
19824
+ type: string
19825
+ enum:
19826
+ - string
19827
+ - number
19828
+ - boolean
19829
+ - date
19830
+ - object
19831
+ - array
19832
+ required:
19833
+ type: boolean
19834
+ description:
19835
+ type: string
19836
+ enum:
19837
+ type: array
19838
+ items:
19839
+ type: string
19840
+ required:
19841
+ - path
19842
+ ConnectorTargetSchema:
19843
+ type: object
19844
+ properties:
19845
+ fields:
19846
+ type: array
19847
+ items:
19848
+ $ref: "#/components/schemas/ConnectorTargetField"
19849
+ required:
19850
+ - fields
19851
+ ConnectorRecords:
19852
+ type: object
19853
+ properties:
19854
+ records:
19855
+ type: array
19856
+ items:
19857
+ type: object
19858
+ additionalProperties: true
19859
+ nextCursor:
19860
+ type: string
19861
+ required:
19862
+ - records
19863
+ ConnectorTransformInput:
19864
+ type: object
19865
+ properties:
19866
+ installation:
19867
+ $ref: "#/components/schemas/ConnectorInstallation"
19868
+ records:
19869
+ type: array
19870
+ items:
19871
+ type: object
19872
+ additionalProperties: true
19873
+ mapping:
19874
+ type: array
19875
+ items:
19876
+ $ref: "#/components/schemas/FieldMapping"
19877
+ required:
19878
+ - installation
19879
+ - records
19880
+ - mapping
19881
+ ConnectorTransformResult:
19882
+ type: object
19883
+ properties:
19884
+ payloads:
19885
+ type: array
19886
+ items: {}
19887
+ skipped:
19888
+ type: array
19889
+ items:
19890
+ type: object
19891
+ additionalProperties: true
19892
+ required:
19893
+ - payloads
19894
+ ConnectorSendInput:
19895
+ type: object
19896
+ properties:
19897
+ installation:
19898
+ $ref: "#/components/schemas/ConnectorInstallation"
19899
+ payloads:
19900
+ type: array
19901
+ items: {}
19902
+ required:
19903
+ - installation
19904
+ - payloads
19905
+ ConnectorSendResult:
19906
+ type: object
19907
+ properties:
19908
+ results:
19909
+ type: array
19910
+ items:
19911
+ type: object
19912
+ additionalProperties: true
19913
+ required:
19914
+ - results
19915
+ ConnectorFetchInput:
19916
+ type: object
19917
+ properties:
19918
+ installation:
19919
+ $ref: "#/components/schemas/ConnectorInstallation"
19920
+ cursor:
19921
+ type: string
19922
+ limit:
19923
+ type: number
19924
+ required:
19925
+ - installation
19632
19926
  CollectionAppWidget:
19633
19927
  type: object
19634
19928
  properties:
@@ -25883,6 +26177,18 @@ components:
25883
26177
  type: string
25884
26178
  auth:
25885
26179
  $ref: "#/components/schemas/FlowConnectionAuth"
26180
+ FlowConnectorRef:
26181
+ type: object
26182
+ properties:
26183
+ appId:
26184
+ type: string
26185
+ preset:
26186
+ type: string
26187
+ settings:
26188
+ type: object
26189
+ additionalProperties: true
26190
+ required:
26191
+ - appId
25886
26192
  IntegrationFlowConfig:
25887
26193
  type: object
25888
26194
  properties:
@@ -25892,6 +26198,8 @@ components:
25892
26198
  type: array
25893
26199
  items:
25894
26200
  $ref: "#/components/schemas/FieldMapping"
26201
+ connector:
26202
+ $ref: "#/components/schemas/FlowConnectorRef"
25895
26203
  IntegrationFlow:
25896
26204
  type: object
25897
26205
  properties:
@@ -26024,6 +26332,12 @@ components:
26024
26332
  type: number
26025
26333
  failed:
26026
26334
  type: number
26335
+ created:
26336
+ type: number
26337
+ updated:
26338
+ type: number
26339
+ skipped:
26340
+ type: number
26027
26341
  status:
26028
26342
  $ref: "#/components/schemas/RunStatus"
26029
26343
  runId:
@@ -26032,9 +26346,47 @@ components:
26032
26346
  - flowId
26033
26347
  - direction
26034
26348
  - records
26035
- - sent
26036
26349
  - failed
26037
26350
  - status
26351
+ InstalledConnector:
26352
+ type: object
26353
+ properties:
26354
+ appId:
26355
+ type: string
26356
+ name:
26357
+ type: string
26358
+ channel:
26359
+ type: string
26360
+ version:
26361
+ type: string
26362
+ connector:
26363
+ type: object
26364
+ additionalProperties: true
26365
+ installation:
26366
+ type: object
26367
+ additionalProperties: true
26368
+ secrets:
26369
+ type: object
26370
+ additionalProperties:
26371
+ type: object
26372
+ additionalProperties: true
26373
+ required:
26374
+ - appId
26375
+ - name
26376
+ - channel
26377
+ - version
26378
+ - connector
26379
+ - installation
26380
+ - secrets
26381
+ SaveConnectorInstallationInput:
26382
+ type: object
26383
+ properties:
26384
+ connection:
26385
+ type: object
26386
+ additionalProperties: true
26387
+ settings:
26388
+ type: object
26389
+ additionalProperties: true
26038
26390
  CapturedRequest:
26039
26391
  type: object
26040
26392
  properties:
@@ -26376,6 +26728,13 @@ components:
26376
26728
  - none
26377
26729
  UpdateFlowInput:
26378
26730
  $ref: "#/components/schemas/CreateFlowInput"
26731
+ ConnectorConsoleStep:
26732
+ type: string
26733
+ enum:
26734
+ - testConnection
26735
+ - describeTarget
26736
+ - sample
26737
+ - transform
26379
26738
  RunTrigger:
26380
26739
  type: string
26381
26740
  enum:
@@ -29830,6 +30189,79 @@ components:
29830
30189
  - nonce
29831
30190
  - mac
29832
30191
  - clientId
30192
+ RealtimeScope:
30193
+ type: object
30194
+ properties:
30195
+ collectionId:
30196
+ type: string
30197
+ appId:
30198
+ type: string
30199
+ required:
30200
+ - collectionId
30201
+ RealtimeMessage:
30202
+ type: object
30203
+ properties:
30204
+ channel:
30205
+ type: string
30206
+ event:
30207
+ type: string
30208
+ data: {}
30209
+ at:
30210
+ type: number
30211
+ required:
30212
+ - channel
30213
+ - event
30214
+ - data
30215
+ RealtimeChangeEvent:
30216
+ type: object
30217
+ properties:
30218
+ type:
30219
+ type: string
30220
+ id:
30221
+ type: string
30222
+ appId:
30223
+ type: string
30224
+ recordType:
30225
+ type: string
30226
+ productId:
30227
+ type: string
30228
+ proofId:
30229
+ type: string
30230
+ status:
30231
+ type: string
30232
+ at:
30233
+ type: number
30234
+ required:
30235
+ - type
30236
+ - at
30237
+ RealtimeChangeFilter:
30238
+ type: object
30239
+ properties:
30240
+ type:
30241
+ type: string
30242
+ id:
30243
+ type: string
30244
+ appId:
30245
+ type: string
30246
+ recordType:
30247
+ type: string
30248
+ productId:
30249
+ type: string
30250
+ proofId:
30251
+ type: string
30252
+ RealtimeChannelDeclaration:
30253
+ type: object
30254
+ properties:
30255
+ name:
30256
+ type: string
30257
+ subscribe:
30258
+ type: object
30259
+ additionalProperties: true
30260
+ publish:
30261
+ type: object
30262
+ additionalProperties: true
30263
+ required:
30264
+ - name
29833
30265
  RealtimeChannelPattern:
29834
30266
  type: string
29835
30267
  ResearchFetchRequest:
@@ -1,6 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  import type { AppDataDeclaration, AppHeadlessDeclaration } from './headless.js';
4
+ import type { RealtimeChannelDeclaration } from './realtime.js';
5
+ import type { FieldMapping } from './integrations.js';
4
6
  /**
5
7
  * A bundle (widget or container) as returned by the collection widgets endpoint.
6
8
  *
@@ -806,6 +808,16 @@ export interface AppManifest {
806
808
  * @see AppManifestFunctions
807
809
  */
808
810
  functions?: AppManifestFunctions;
811
+ /**
812
+ * SmartLinks Realtime: the live channels this app uses, with who may listen and who may send
813
+ * (docs/realtime.md). Only declared channels exist — anything else is refused.
814
+ * ```json
815
+ * "realtime": { "channels": [ { "name": "draw", "subscribe": "public", "publish": "admin" } ] }
816
+ * ```
817
+ */
818
+ realtime?: {
819
+ channels: RealtimeChannelDeclaration[];
820
+ };
809
821
  /**
810
822
  * The app's public data model: its data types, how each is stored, fields, examples and read
811
823
  * recipes. Required for `headless`. @see AppDataDeclaration · docs/headless-providers.md
@@ -816,8 +828,162 @@ export interface AppManifest {
816
828
  * provider). Validated by `smartlinks-headless`. @see AppHeadlessDeclaration
817
829
  */
818
830
  headless?: AppHeadlessDeclaration;
831
+ /**
832
+ * This app is an integration CONNECTOR for one external provider (Syndigo, OneWorldSync, …): the
833
+ * integrations console lists it, draws its connect form and settings, and the integration engine
834
+ * calls its server functions to test, describe, sample, transform, send and fetch.
835
+ * @see AppConnectorDeclaration · docs/connectors.md
836
+ */
837
+ connector?: AppConnectorDeclaration;
819
838
  [key: string]: any;
820
839
  }
840
+ /** One field of a connector's "Connect" form. */
841
+ export interface ConnectorConnectionField {
842
+ /** Key in the installation's connection settings (non-secret fields) — `name` for a secret too. */
843
+ name: string;
844
+ label: string;
845
+ description?: string;
846
+ /** Store the value as this app's SECRET of this name (sealed, write-only; the function reads it with
847
+ * `ctx.secrets.get(secret)`), never in the settings. Declare `secrets:<name>` on the functions. */
848
+ secret?: string;
849
+ required?: boolean;
850
+ /** Input hint for the form. Default 'text'. */
851
+ type?: 'text' | 'url' | 'select' | 'number' | 'boolean';
852
+ options?: Array<{
853
+ value: string;
854
+ label: string;
855
+ }>;
856
+ placeholder?: string;
857
+ }
858
+ /** A ready-made flow a connector offers ("Products → Syndigo"). */
859
+ export interface ConnectorPreset {
860
+ id: string;
861
+ title: string;
862
+ description?: string;
863
+ direction: 'inbound' | 'outbound';
864
+ /** SmartLinks entity: outbound source / inbound target. */
865
+ entity: string;
866
+ /** Defaults for the flow (event types, schedule, mapping, settings…). */
867
+ flow?: Record<string, unknown>;
868
+ }
869
+ /** A panel the connector contributes to the integrations console (e.g. an API explorer). */
870
+ export interface ConnectorPanel {
871
+ id: string;
872
+ title: string;
873
+ /** Exported component name in the app's widgets bundle (manifest `widgets.files`). */
874
+ component: string;
875
+ }
876
+ /**
877
+ * The connector contract. Every function named here is one of this app's server functions
878
+ * (manifest `functions.definitions`); the engine calls it with collection authority, capped by the
879
+ * capabilities the function declares. A connector fills in only what it needs.
880
+ */
881
+ export interface AppConnectorDeclaration {
882
+ /** Stable provider key, e.g. 'syndigo', 'oneworldsync'. */
883
+ provider: string;
884
+ /** Display name of the provider ("1WorldSync"). Defaults to the app name. */
885
+ title?: string;
886
+ directions: Array<'inbound' | 'outbound'>;
887
+ /** SmartLinks entities it maps, e.g. ['product']. */
888
+ entities: string[];
889
+ /** The console's "Connect" form. */
890
+ connection?: {
891
+ fields: ConnectorConnectionField[];
892
+ };
893
+ /** Per-installation settings: a JSON Schema the console renders as a form. */
894
+ settings?: Record<string, unknown>;
895
+ presets?: ConnectorPreset[];
896
+ /** Names of this app's server functions implementing each step. */
897
+ functions: {
898
+ /** → ConnectorTestResult. */
899
+ testConnection?: string;
900
+ /** → ConnectorTargetSchema: the provider's fields for THIS customer (the mapper's right-hand side). */
901
+ describeTarget?: string;
902
+ /** → ConnectorRecords: real records for the mapper, the AI assistant and dry runs (inbound). */
903
+ sample?: string;
904
+ /** (ConnectorTransformInput) → ConnectorTransformResult. Must be deterministic — no AI at run time. */
905
+ transform?: string;
906
+ /** (ConnectorSendInput) → ConnectorSendResult. Omit to use a generic transport (HTTP, Event Hub). */
907
+ send?: string;
908
+ /** (ConnectorFetchInput) → ConnectorRecords: inbound pull, one page per call. */
909
+ fetch?: string;
910
+ };
911
+ panels?: ConnectorPanel[];
912
+ /** Path (under the app's public files) of a guide the AI mapping assistant reads. */
913
+ aiGuide?: string;
914
+ }
915
+ /**
916
+ * What every connector function receives about the installation it serves. The engine assembles it
917
+ * from the connector app's config on the collection (`connector.connection` / `connector.settings`)
918
+ * with the flow's `config.connector.settings` layered on top.
919
+ */
920
+ export interface ConnectorInstallation {
921
+ collectionId: string;
922
+ /** The connector app. */
923
+ appId: string;
924
+ /** The flow being run / configured, when there is one. */
925
+ flowId?: string | null;
926
+ /** Non-secret connection fields (secrets are read with ctx.secrets.get). */
927
+ connection: Record<string, unknown>;
928
+ /** Installation settings, overridden per flow. */
929
+ settings: Record<string, unknown>;
930
+ }
931
+ export interface ConnectorTestResult {
932
+ ok: boolean;
933
+ /** Shown to the admin: "Connected as …" or what's wrong. */
934
+ message: string;
935
+ }
936
+ export interface ConnectorTargetField {
937
+ /** Path in the provider payload, e.g. 'attributes.brandName'. */
938
+ path: string;
939
+ label?: string;
940
+ type?: 'string' | 'number' | 'boolean' | 'date' | 'object' | 'array';
941
+ required?: boolean;
942
+ description?: string;
943
+ /** Allowed values, when the provider fixes them. */
944
+ enum?: string[];
945
+ }
946
+ export interface ConnectorTargetSchema {
947
+ fields: ConnectorTargetField[];
948
+ }
949
+ export interface ConnectorRecords {
950
+ records: Array<Record<string, unknown>>;
951
+ /** Inbound paging: pass back to the next fetch; absent when there's no more. */
952
+ nextCursor?: string | null;
953
+ }
954
+ export interface ConnectorTransformInput {
955
+ installation: ConnectorInstallation;
956
+ /** SmartLinks records (outbound) or provider records (inbound). */
957
+ records: Array<Record<string, unknown>>;
958
+ /** The flow's saved mapping (`config.fieldMappings`) — the same shape the engine's mapper runs. */
959
+ mapping: FieldMapping[];
960
+ }
961
+ export interface ConnectorTransformResult {
962
+ /** One payload per input record, in the same order (null = skip that record, with a reason). */
963
+ payloads: Array<unknown | null>;
964
+ skipped?: Array<{
965
+ index: number;
966
+ reason: string;
967
+ }>;
968
+ }
969
+ export interface ConnectorSendInput {
970
+ installation: ConnectorInstallation;
971
+ payloads: unknown[];
972
+ }
973
+ export interface ConnectorSendResult {
974
+ results: Array<{
975
+ index: number;
976
+ ok: boolean;
977
+ status?: number;
978
+ error?: string;
979
+ externalId?: string;
980
+ }>;
981
+ }
982
+ export interface ConnectorFetchInput {
983
+ installation: ConnectorInstallation;
984
+ cursor?: string | null;
985
+ limit?: number;
986
+ }
821
987
  /**
822
988
  * One app entry in the collection widgets response.
823
989
  */