@proveanything/smartlinks 2.0.58 → 2.0.62

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/openapi.yaml CHANGED
@@ -4417,6 +4417,65 @@ paths:
4417
4417
  description: Unauthorized
4418
4418
  404:
4419
4419
  description: Not found
4420
+ /admin/collection/{collectionId}/integrations/health:
4421
+ get:
4422
+ tags:
4423
+ - integrations
4424
+ summary: "Every flow at a glance: paused?, running?, last 24h, backlog."
4425
+ operationId: integrations_getHealth
4426
+ security:
4427
+ - bearerAuth: []
4428
+ parameters:
4429
+ - name: collectionId
4430
+ in: path
4431
+ required: true
4432
+ schema:
4433
+ type: string
4434
+ responses:
4435
+ 200:
4436
+ description: Success
4437
+ content:
4438
+ application/json:
4439
+ schema:
4440
+ $ref: "#/components/schemas/IntegrationHealth"
4441
+ 400:
4442
+ description: Bad request
4443
+ 401:
4444
+ description: Unauthorized
4445
+ 404:
4446
+ description: Not found
4447
+ /admin/collection/{collectionId}/integrations/lineage/product/{productId}:
4448
+ get:
4449
+ tags:
4450
+ - integrations
4451
+ summary: "Where a product's data came from (the provider record, when it was fetched and imported, by which run, with the current mapping or an older one) and where it went (each outbound flow's last delivery)."
4452
+ operationId: integrations_getProductLineage
4453
+ security:
4454
+ - bearerAuth: []
4455
+ parameters:
4456
+ - name: collectionId
4457
+ in: path
4458
+ required: true
4459
+ schema:
4460
+ type: string
4461
+ - name: productId
4462
+ in: path
4463
+ required: true
4464
+ schema:
4465
+ type: string
4466
+ responses:
4467
+ 200:
4468
+ description: Success
4469
+ content:
4470
+ application/json:
4471
+ schema:
4472
+ $ref: "#/components/schemas/ProductLineage"
4473
+ 400:
4474
+ description: Bad request
4475
+ 401:
4476
+ description: Unauthorized
4477
+ 404:
4478
+ description: Not found
4420
4479
  /admin/collection/{collectionId}/integrations/record-types:
4421
4480
  get:
4422
4481
  tags:
@@ -15474,6 +15533,212 @@ components:
15474
15533
  name: X-API-Key
15475
15534
  description: API key for server-to-server calls
15476
15535
  schemas:
15536
+ AdminCardRefresh:
15537
+ type: object
15538
+ properties:
15539
+ on:
15540
+ type: array
15541
+ items:
15542
+ $ref: "#/components/schemas/AdminCardRefreshOn"
15543
+ maxAge:
15544
+ type: object
15545
+ additionalProperties: true
15546
+ AdminCardDeclaration:
15547
+ type: object
15548
+ properties:
15549
+ id:
15550
+ type: string
15551
+ title:
15552
+ type: string
15553
+ description:
15554
+ type: string
15555
+ kind:
15556
+ type: string
15557
+ enum:
15558
+ - data
15559
+ - component
15560
+ function:
15561
+ type: string
15562
+ component:
15563
+ type: string
15564
+ sizes:
15565
+ type: array
15566
+ items:
15567
+ $ref: "#/components/schemas/AdminCardSize"
15568
+ priority:
15569
+ type: number
15570
+ levels:
15571
+ type: array
15572
+ items:
15573
+ type: string
15574
+ enum:
15575
+ - collection
15576
+ refresh:
15577
+ $ref: "#/components/schemas/AdminCardRefresh"
15578
+ required:
15579
+ - id
15580
+ - title
15581
+ AppManifestAdminCards:
15582
+ type: object
15583
+ properties:
15584
+ cards:
15585
+ type: array
15586
+ items:
15587
+ $ref: "#/components/schemas/AdminCardDeclaration"
15588
+ files:
15589
+ type: object
15590
+ additionalProperties: true
15591
+ js:
15592
+ type: object
15593
+ additionalProperties: true
15594
+ css:
15595
+ type: string
15596
+ required:
15597
+ - cards
15598
+ - js
15599
+ AdminCardAction:
15600
+ type: object
15601
+ properties:
15602
+ label:
15603
+ type: string
15604
+ path:
15605
+ type: string
15606
+ url:
15607
+ type: string
15608
+ required:
15609
+ - label
15610
+ AdminCardPayload:
15611
+ type: object
15612
+ properties:
15613
+ title:
15614
+ type: string
15615
+ value:
15616
+ type: object
15617
+ additionalProperties: true
15618
+ label:
15619
+ type: string
15620
+ unit:
15621
+ type: string
15622
+ trend:
15623
+ type: object
15624
+ additionalProperties: true
15625
+ status:
15626
+ type: object
15627
+ additionalProperties: true
15628
+ progress:
15629
+ type: object
15630
+ additionalProperties: true
15631
+ items:
15632
+ type: array
15633
+ items:
15634
+ type: object
15635
+ additionalProperties: true
15636
+ todo:
15637
+ type: array
15638
+ items:
15639
+ type: object
15640
+ additionalProperties: true
15641
+ actions:
15642
+ type: array
15643
+ items:
15644
+ $ref: "#/components/schemas/AdminCardAction"
15645
+ empty:
15646
+ type: object
15647
+ additionalProperties: true
15648
+ AdminCard:
15649
+ type: object
15650
+ properties:
15651
+ key:
15652
+ type: string
15653
+ appId:
15654
+ type: string
15655
+ cardId:
15656
+ type: string
15657
+ title:
15658
+ type: string
15659
+ description:
15660
+ type: string
15661
+ kind:
15662
+ type: string
15663
+ enum:
15664
+ - data
15665
+ - component
15666
+ sizes:
15667
+ type: array
15668
+ items:
15669
+ $ref: "#/components/schemas/AdminCardSize"
15670
+ size:
15671
+ $ref: "#/components/schemas/AdminCardSize"
15672
+ priority:
15673
+ type: number
15674
+ state:
15675
+ $ref: "#/components/schemas/AdminCardState"
15676
+ payload:
15677
+ $ref: "#/components/schemas/AdminCardPayload"
15678
+ computedAt:
15679
+ type: number
15680
+ error:
15681
+ type: string
15682
+ component:
15683
+ type: object
15684
+ additionalProperties: true
15685
+ required:
15686
+ - key
15687
+ - appId
15688
+ - cardId
15689
+ - title
15690
+ - kind
15691
+ - sizes
15692
+ - size
15693
+ - priority
15694
+ - state
15695
+ - payload
15696
+ - computedAt
15697
+ StudioHomeLayout:
15698
+ type: object
15699
+ properties:
15700
+ version:
15701
+ type: object
15702
+ additionalProperties: true
15703
+ cards:
15704
+ type: array
15705
+ items:
15706
+ type: object
15707
+ additionalProperties: true
15708
+ required:
15709
+ - version
15710
+ - cards
15711
+ AdminCardsResponse:
15712
+ type: object
15713
+ properties:
15714
+ cards:
15715
+ type: array
15716
+ items:
15717
+ $ref: "#/components/schemas/AdminCard"
15718
+ hidden:
15719
+ type: array
15720
+ items:
15721
+ $ref: "#/components/schemas/AdminCard"
15722
+ layout:
15723
+ $ref: "#/components/schemas/StudioHomeLayout"
15724
+ required:
15725
+ - cards
15726
+ - hidden
15727
+ - layout
15728
+ AdminCardSize:
15729
+ type: string
15730
+ enum:
15731
+ - small
15732
+ - medium
15733
+ - wide
15734
+ - full
15735
+ AdminCardRefreshOn:
15736
+ type: object
15737
+ additionalProperties: true
15738
+ AdminCardState:
15739
+ type: string
15740
+ enum:
15741
+ - fresh
15477
15742
  ContentPart:
15478
15743
  type: object
15479
15744
  properties:
@@ -19648,6 +19913,8 @@ components:
19648
19913
  realtime:
19649
19914
  type: object
19650
19915
  additionalProperties: true
19916
+ adminCards:
19917
+ $ref: "#/components/schemas/AppManifestAdminCards"
19651
19918
  data:
19652
19919
  $ref: "#/components/schemas/AppDataDeclaration"
19653
19920
  headless:
@@ -19780,6 +20047,11 @@ components:
19780
20047
  $ref: "#/components/schemas/ConnectorPanel"
19781
20048
  aiGuide:
19782
20049
  type: string
20050
+ recordId:
20051
+ type: string
20052
+ limits:
20053
+ type: object
20054
+ additionalProperties: true
19783
20055
  required:
19784
20056
  - provider
19785
20057
  - directions
@@ -19933,12 +20205,26 @@ components:
19933
20205
  type: object
19934
20206
  properties:
19935
20207
  results:
19936
- type: array
19937
- items:
19938
- type: object
19939
- additionalProperties: true
20208
+ type: object
20209
+ additionalProperties: true
20210
+ index:
20211
+ type: number
20212
+ ok:
20213
+ type: boolean
20214
+ status:
20215
+ type: number
20216
+ error:
20217
+ type: string
20218
+ externalId:
20219
+ type: string
20220
+ retryable:
20221
+ type: boolean
20222
+ retryAfterSeconds:
20223
+ type: number
19940
20224
  required:
19941
20225
  - results
20226
+ - index
20227
+ - ok
19942
20228
  ConnectorFetchInput:
19943
20229
  type: object
19944
20230
  properties:
@@ -26278,6 +26564,12 @@ components:
26278
26564
  type: string
26279
26565
  totalSynced:
26280
26566
  type: number
26567
+ circuitOpenedAt:
26568
+ type: string
26569
+ circuitProbeAt:
26570
+ type: string
26571
+ circuitReason:
26572
+ type: string
26281
26573
  required:
26282
26574
  - id
26283
26575
  - orgId
@@ -26294,6 +26586,210 @@ components:
26294
26586
  - createdBy
26295
26587
  - createdAt
26296
26588
  - updatedAt
26589
+ FailedRecord:
26590
+ type: object
26591
+ properties:
26592
+ id:
26593
+ type: string
26594
+ entityId:
26595
+ type: string
26596
+ externalId:
26597
+ type: string
26598
+ status:
26599
+ type: string
26600
+ enum:
26601
+ - failed
26602
+ - dead
26603
+ attempts:
26604
+ type: number
26605
+ nextAttemptAt:
26606
+ type: string
26607
+ lastError:
26608
+ type: string
26609
+ updatedAt:
26610
+ type: string
26611
+ required:
26612
+ - id
26613
+ - status
26614
+ - attempts
26615
+ FlowHealth:
26616
+ type: object
26617
+ properties:
26618
+ flowId:
26619
+ type: string
26620
+ name:
26621
+ type: string
26622
+ direction:
26623
+ $ref: "#/components/schemas/FlowDirection"
26624
+ status:
26625
+ $ref: "#/components/schemas/FlowStatus"
26626
+ paused:
26627
+ type: object
26628
+ additionalProperties: true
26629
+ running:
26630
+ type: object
26631
+ additionalProperties: true
26632
+ lastRun:
26633
+ type: object
26634
+ additionalProperties: true
26635
+ last24h:
26636
+ type: object
26637
+ additionalProperties: true
26638
+ runs:
26639
+ type: number
26640
+ byStatus:
26641
+ type: object
26642
+ additionalProperties:
26643
+ type: number
26644
+ records:
26645
+ type: number
26646
+ delivered:
26647
+ type: number
26648
+ failed:
26649
+ type: number
26650
+ failureRate:
26651
+ type: number
26652
+ avgRunMs:
26653
+ type: number
26654
+ recordsPerSecond:
26655
+ type: number
26656
+ backlog:
26657
+ type: object
26658
+ additionalProperties: true
26659
+ landed:
26660
+ type: number
26661
+ waiting:
26662
+ type: number
26663
+ oldestWaitingSince:
26664
+ type: string
26665
+ retrying:
26666
+ type: number
26667
+ retriesDue:
26668
+ type: number
26669
+ gaveUp:
26670
+ type: number
26671
+ required:
26672
+ - flowId
26673
+ - name
26674
+ - direction
26675
+ - status
26676
+ - paused
26677
+ - running
26678
+ - lastRun
26679
+ - last24h
26680
+ - runs
26681
+ - byStatus
26682
+ - records
26683
+ - delivered
26684
+ - failed
26685
+ - failureRate
26686
+ - avgRunMs
26687
+ - recordsPerSecond
26688
+ - backlog
26689
+ - retrying
26690
+ - retriesDue
26691
+ - gaveUp
26692
+ IntegrationHealth:
26693
+ type: object
26694
+ properties:
26695
+ flows:
26696
+ type: array
26697
+ items:
26698
+ $ref: "#/components/schemas/FlowHealth"
26699
+ summary:
26700
+ type: object
26701
+ additionalProperties: true
26702
+ required:
26703
+ - flows
26704
+ - summary
26705
+ ProductLineage:
26706
+ type: object
26707
+ properties:
26708
+ productId:
26709
+ type: string
26710
+ sources:
26711
+ type: object
26712
+ additionalProperties: true
26713
+ source:
26714
+ type: string
26715
+ externalId:
26716
+ type: string
26717
+ flow:
26718
+ type: object
26719
+ additionalProperties: true
26720
+ fetchedAt:
26721
+ type: string
26722
+ processedAt:
26723
+ type: string
26724
+ processedRunId:
26725
+ type: string
26726
+ status:
26727
+ type: string
26728
+ enum:
26729
+ - sent
26730
+ - failed
26731
+ - dead
26732
+ lastError:
26733
+ type: string
26734
+ currentMapping:
26735
+ type: boolean
26736
+ mapping:
26737
+ type: array
26738
+ items:
26739
+ $ref: "#/components/schemas/FieldMapping"
26740
+ payload: {}
26741
+ deliveries:
26742
+ type: object
26743
+ additionalProperties: true
26744
+ lastSentAt:
26745
+ type: string
26746
+ attempts:
26747
+ type: number
26748
+ nextAttemptAt:
26749
+ type: string
26750
+ lastRunId:
26751
+ type: string
26752
+ recentRuns:
26753
+ type: array
26754
+ items:
26755
+ $ref: "#/components/schemas/FlowRun"
26756
+ required:
26757
+ - productId
26758
+ - sources
26759
+ - source
26760
+ - externalId
26761
+ - flow
26762
+ - fetchedAt
26763
+ - processedAt
26764
+ - processedRunId
26765
+ - status
26766
+ - lastError
26767
+ - currentMapping
26768
+ - mapping
26769
+ - deliveries
26770
+ - flow
26771
+ - status
26772
+ - lastSentAt
26773
+ - attempts
26774
+ - nextAttemptAt
26775
+ - lastError
26776
+ - lastRunId
26777
+ - recentRuns
26778
+ FailedRecordList:
26779
+ type: object
26780
+ properties:
26781
+ direction:
26782
+ $ref: "#/components/schemas/FlowDirection"
26783
+ items:
26784
+ type: array
26785
+ items:
26786
+ $ref: "#/components/schemas/FailedRecord"
26787
+ nextCursor:
26788
+ type: string
26789
+ required:
26790
+ - direction
26791
+ - items
26792
+ - nextCursor
26297
26793
  CreateFlowInput:
26298
26794
  type: object
26299
26795
  properties:
@@ -26365,6 +26861,8 @@ components:
26365
26861
  type: number
26366
26862
  skipped:
26367
26863
  type: number
26864
+ held:
26865
+ type: number
26368
26866
  status:
26369
26867
  $ref: "#/components/schemas/RunStatus"
26370
26868
  runId:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "2.0.58",
3
+ "version": "2.0.62",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -338,6 +338,54 @@ if (meta.respectsHostTheme) {
338
338
  }
339
339
  }
340
340
 
341
+ // ---- admin cards: declared right, cached, and backed by an admin function ---------------------
342
+ // docs/admin-cards.md. A data card with no function (or a public one) can't load; a card with no
343
+ // refresh rule falls back to a 6h maxAge, which is rarely what's wanted.
344
+ if (manifest.adminCards) {
345
+ const cards = Array.isArray(manifest.adminCards.cards) ? manifest.adminCards.cards : [];
346
+ const fns = new Map(((manifest.functions && manifest.functions.definitions) || []).map((f) => [f && f.name, f]));
347
+ const SIZES = new Set(['small', 'medium', 'wide', 'full']);
348
+ const ON = /^(records(:[A-Za-z0-9._-]{1,60})?|products|proofs|assets|apps|collection|settings(:[A-Za-z0-9._-]{1,60})?)$/;
349
+ const cardProblems = [];
350
+ const before = warnings.length;
351
+ const seen = new Set();
352
+ if (!cards.length) warnings.push('adminCards is declared but has no cards.');
353
+ for (const c of cards) {
354
+ const id = c && typeof c.id === 'string' ? c.id : '';
355
+ const label = `admin card "${id || '?'}"`;
356
+ if (!/^[A-Za-z0-9_-]{1,40}$/.test(id)) { cardProblems.push(`${label}: id must be 1–40 letters, digits, "-" or "_".`); continue; }
357
+ if (seen.has(id)) cardProblems.push(`${label}: declared twice.`);
358
+ seen.add(id);
359
+ if (!c.title) warnings.push(`${label}: has no title.`);
360
+ const kind = c.kind || 'data';
361
+ if (kind !== 'data' && kind !== 'component') cardProblems.push(`${label}: kind must be "data" or "component".`);
362
+ if (kind === 'data' && !c.function) cardProblems.push(`${label}: a data card needs a "function" (an admin server function returning its payload).`);
363
+ if (c.function) {
364
+ const fn = fns.get(c.function);
365
+ if (!fn) cardProblems.push(`${label}: function "${c.function}" isn't in functions.definitions.`);
366
+ else if ((fn.trigger && fn.trigger.type) !== 'http') cardProblems.push(`${label}: function "${c.function}" must be an http function.`);
367
+ else if ((fn.visibility || 'admin') !== 'admin') cardProblems.push(`${label}: function "${c.function}" must have visibility "admin" — card data is for the collection's admins.`);
368
+ }
369
+ if (kind === 'component') {
370
+ if (!c.component) cardProblems.push(`${label}: a component card needs "component" (the export name in the adminCards bundle).`);
371
+ if (!manifest.adminCards.files || !manifest.adminCards.files.js) cardProblems.push(`${label}: component cards need adminCards.files (the adminCards bundle).`);
372
+ if (!c.function) warnings.push(`${label}: give the component a "function" too — it then gets cached data as a prop instead of fetching on every dashboard load.`);
373
+ }
374
+ for (const s of c.sizes || []) if (!SIZES.has(s)) cardProblems.push(`${label}: unknown size "${s}" (small, medium, wide, full).`);
375
+ const refresh = c.refresh || {};
376
+ for (const on of refresh.on || []) if (!ON.test(String(on))) cardProblems.push(`${label}: refresh.on "${on}" isn't a change kind (records, records:<type>, products, proofs, assets, apps, collection, settings, settings:<group>).`);
377
+ if (!(refresh.on || []).length && refresh.maxAge == null) {
378
+ warnings.push(`${label}: no refresh rule — it's recomputed every 6h. Add refresh.on (what its data depends on, e.g. "records:question") so it updates when that changes and never otherwise.`);
379
+ }
380
+ }
381
+ for (const msg of cardProblems) problems.push({ surface: 'adminCards', spec: null, msg });
382
+ if (cardProblems.length) {
383
+ console.log(`${RED}✗${RESET} admin cards`);
384
+ for (const msg of cardProblems) console.log(` ${RED}${msg}${RESET}`);
385
+ } else if (warnings.length === before) console.log(`${GREEN}✓${RESET} admin cards ${DIM}— ${cards.length} card${cards.length === 1 ? '' : 's'}, each backed and cached${RESET}`);
386
+ else console.log(`${YELLOW}⚠${RESET} admin cards — see below`);
387
+ }
388
+
341
389
  // ---- package.json scripts point at files that exist ------------------------------------------
342
390
  // An upgrade that copies a script LINE but not the script FILE breaks every build at that step
343
391
  // (e.g. `postbuild: node scripts/smartlinks-deploy.mjs` with no scripts/smartlinks-deploy.mjs).
@@ -366,8 +414,13 @@ console.log('');
366
414
  for (const w of warnings) console.log(`${YELLOW}⚠ ${w}${RESET}`);
367
415
 
368
416
  if (problems.length) {
369
- console.log(`\n${RED}${BOLD}FAIL${RESET} — ${problems.length} problem${problems.length === 1 ? '' : 's'} outside the shared-dependency contract.`);
370
- console.log(`${DIM}Externalize only the ${CONTRACT.size} contract specifiers (import { SHARED_DEPENDENCY_SPECIFIERS } from '@proveanything/smartlinks'); bundle everything else.${RESET}`);
417
+ const contractProblems = problems.filter((p) => p.surface !== 'adminCards').length;
418
+ const cardCount = problems.length - contractProblems;
419
+ if (contractProblems) {
420
+ console.log(`\n${RED}${BOLD}FAIL${RESET} — ${contractProblems} problem${contractProblems === 1 ? '' : 's'} outside the shared-dependency contract.`);
421
+ console.log(`${DIM}Externalize only the ${CONTRACT.size} contract specifiers (import { SHARED_DEPENDENCY_SPECIFIERS } from '@proveanything/smartlinks'); bundle everything else.${RESET}`);
422
+ }
423
+ if (cardCount) console.log(`\n${RED}${BOLD}FAIL${RESET} — ${cardCount} admin card problem${cardCount === 1 ? '' : 's'} (docs/admin-cards.md).`);
371
424
  process.exit(1);
372
425
  }
373
426