@almadar/integrations 2.24.0 → 2.25.0

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.
@@ -1,4 +1,4 @@
1
- import { ServiceParamsValue, ServiceParams } from '@almadar/core';
1
+ import { ServiceParamsValue, ServiceParams, EntityRow } from '@almadar/core';
2
2
  import { d as IntegrationParamValue, e as IntegrationParams } from './BaseIntegration-MA-b4fh8.js';
3
3
 
4
4
  /** Scalar value admissible as a SQL bind parameter. */
@@ -79,8 +79,9 @@ type GitHubActions = {
79
79
  params: {
80
80
  title: string;
81
81
  body: string;
82
- head: string;
83
- base: string;
82
+ baseBranch: string;
83
+ headBranch: string;
84
+ draft?: boolean;
84
85
  };
85
86
  result: {
86
87
  number: number;
@@ -368,6 +369,336 @@ type WebhookActions = {
368
369
  };
369
370
  };
370
371
  };
372
+ type PushActions = {
373
+ send: {
374
+ params: {
375
+ subscription: {
376
+ endpoint: string;
377
+ keys: {
378
+ p256dh: string;
379
+ auth: string;
380
+ };
381
+ };
382
+ title: string;
383
+ body: string;
384
+ url?: string;
385
+ icon?: string;
386
+ };
387
+ result: {
388
+ statusCode: number;
389
+ ok: boolean;
390
+ expired: boolean;
391
+ };
392
+ };
393
+ };
394
+ type CalendarActions = {
395
+ listEvents: {
396
+ params: {
397
+ calendarId?: string;
398
+ timeMin?: string;
399
+ timeMax?: string;
400
+ syncToken?: string;
401
+ maxResults?: number;
402
+ };
403
+ result: {
404
+ events: Array<{
405
+ id: string;
406
+ summary: string;
407
+ description: string;
408
+ location: string;
409
+ start: string;
410
+ end: string;
411
+ status: string;
412
+ updated: string;
413
+ }>;
414
+ nextSyncToken: string | null;
415
+ };
416
+ };
417
+ createEvent: {
418
+ params: {
419
+ calendarId?: string;
420
+ summary: string;
421
+ description?: string;
422
+ location?: string;
423
+ start: string;
424
+ end?: string;
425
+ durationMinutes?: number;
426
+ };
427
+ result: {
428
+ id: string;
429
+ status: string;
430
+ htmlLink: string;
431
+ };
432
+ };
433
+ updateEvent: {
434
+ params: {
435
+ calendarId?: string;
436
+ eventId: string;
437
+ summary?: string;
438
+ description?: string;
439
+ location?: string;
440
+ start?: string;
441
+ end?: string;
442
+ };
443
+ result: {
444
+ id: string;
445
+ status: string;
446
+ };
447
+ };
448
+ deleteEvent: {
449
+ params: {
450
+ calendarId?: string;
451
+ eventId: string;
452
+ };
453
+ result: {
454
+ id: string;
455
+ deleted: boolean;
456
+ };
457
+ };
458
+ freeBusy: {
459
+ params: {
460
+ calendarId?: string;
461
+ timeMin: string;
462
+ timeMax: string;
463
+ };
464
+ result: {
465
+ busy: Array<{
466
+ start: string;
467
+ end: string;
468
+ }>;
469
+ };
470
+ };
471
+ watch: {
472
+ params: {
473
+ calendarId?: string;
474
+ channelId: string;
475
+ address: string;
476
+ ttlSeconds?: number;
477
+ };
478
+ result: {
479
+ channelId: string;
480
+ resourceId: string;
481
+ expiration: string;
482
+ };
483
+ };
484
+ stopWatch: {
485
+ params: {
486
+ channelId: string;
487
+ resourceId: string;
488
+ };
489
+ result: {
490
+ stopped: boolean;
491
+ };
492
+ };
493
+ };
494
+ type DriveActions = {
495
+ listFiles: {
496
+ params: {
497
+ folderId?: string;
498
+ query?: string;
499
+ maxResults?: number;
500
+ };
501
+ result: {
502
+ files: Array<{
503
+ id: string;
504
+ name: string;
505
+ mimeType: string;
506
+ size: number;
507
+ modifiedTime: string;
508
+ webViewLink: string;
509
+ }>;
510
+ };
511
+ };
512
+ getFile: {
513
+ params: {
514
+ fileId: string;
515
+ };
516
+ result: {
517
+ id: string;
518
+ name: string;
519
+ mimeType: string;
520
+ content: string;
521
+ size: number;
522
+ };
523
+ };
524
+ uploadFile: {
525
+ params: {
526
+ name: string;
527
+ content: string;
528
+ mimeType?: string;
529
+ folderId?: string;
530
+ };
531
+ result: {
532
+ id: string;
533
+ name: string;
534
+ webViewLink: string;
535
+ };
536
+ };
537
+ createFolder: {
538
+ params: {
539
+ name: string;
540
+ parentId?: string;
541
+ };
542
+ result: {
543
+ id: string;
544
+ name: string;
545
+ };
546
+ };
547
+ shareFile: {
548
+ params: {
549
+ fileId: string;
550
+ email: string;
551
+ role?: 'reader' | 'writer' | 'commenter';
552
+ };
553
+ result: {
554
+ shared: boolean;
555
+ permissionId: string;
556
+ };
557
+ };
558
+ };
559
+ type MetaAdsActions = {
560
+ getSpend: {
561
+ params: {
562
+ accountId?: string;
563
+ since: string;
564
+ until: string;
565
+ clientTag?: string;
566
+ };
567
+ result: {
568
+ spend: number;
569
+ currency: string;
570
+ impressions: number;
571
+ clicks: number;
572
+ };
573
+ };
574
+ listCampaigns: {
575
+ params: {
576
+ accountId?: string;
577
+ status?: string;
578
+ };
579
+ result: {
580
+ campaigns: Array<{
581
+ id: string;
582
+ name: string;
583
+ status: string;
584
+ dailyBudget: number;
585
+ }>;
586
+ };
587
+ };
588
+ };
589
+ type AccountingActions = {
590
+ exportInvoices: {
591
+ params: {
592
+ invoices: Array<{
593
+ id: string;
594
+ number: string;
595
+ customer: string;
596
+ issuedAt: string;
597
+ dueAt: string;
598
+ currency: string;
599
+ net: number;
600
+ tax: number;
601
+ gross: number;
602
+ status: string;
603
+ }>;
604
+ format?: 'csv';
605
+ };
606
+ result: {
607
+ content: string;
608
+ filename: string;
609
+ count: number;
610
+ };
611
+ };
612
+ exportJournal: {
613
+ params: {
614
+ entries: Array<{
615
+ date: string;
616
+ account: string;
617
+ description: string;
618
+ debit: number;
619
+ credit: number;
620
+ reference: string;
621
+ }>;
622
+ format?: 'csv';
623
+ };
624
+ result: {
625
+ content: string;
626
+ filename: string;
627
+ count: number;
628
+ };
629
+ };
630
+ };
631
+ type BankingActions = {
632
+ createRequisition: {
633
+ params: {
634
+ institutionId: string;
635
+ redirectUrl: string;
636
+ reference?: string;
637
+ };
638
+ result: {
639
+ requisitionId: string;
640
+ link: string;
641
+ };
642
+ };
643
+ listAccounts: {
644
+ params: {
645
+ requisitionId: string;
646
+ };
647
+ result: {
648
+ accounts: string[];
649
+ };
650
+ };
651
+ listTransactions: {
652
+ params: {
653
+ accountId: string;
654
+ dateFrom?: string;
655
+ dateTo?: string;
656
+ };
657
+ result: {
658
+ transactions: Array<{
659
+ id: string;
660
+ amount: number;
661
+ currency: string;
662
+ date: string;
663
+ description: string;
664
+ counterparty: string;
665
+ }>;
666
+ };
667
+ };
668
+ };
669
+ type EsignActions = {
670
+ sendEnvelope: {
671
+ params: {
672
+ recipientEmail: string;
673
+ recipientName: string;
674
+ documentName: string;
675
+ documentContent: string;
676
+ emailSubject?: string;
677
+ };
678
+ result: {
679
+ envelopeId: string;
680
+ status: string;
681
+ };
682
+ };
683
+ getEnvelopeStatus: {
684
+ params: {
685
+ envelopeId: string;
686
+ };
687
+ result: {
688
+ status: string;
689
+ completedAt: string;
690
+ };
691
+ };
692
+ downloadDocument: {
693
+ params: {
694
+ envelopeId: string;
695
+ };
696
+ result: {
697
+ content: string;
698
+ documentName: string;
699
+ };
700
+ };
701
+ };
371
702
  type DockerActions = {
372
703
  build: {
373
704
  params: {
@@ -490,7 +821,12 @@ type StorageActions = {
490
821
  key?: string;
491
822
  content?: string;
492
823
  contentType?: string;
493
- file?: IntegrationParams;
824
+ file?: {
825
+ name: string;
826
+ size: number;
827
+ type: string;
828
+ content?: string;
829
+ };
494
830
  acl?: 'public' | 'private';
495
831
  maxSize?: number;
496
832
  metadata?: IntegrationParams;
@@ -500,6 +836,8 @@ type StorageActions = {
500
836
  bucket: string;
501
837
  size: number;
502
838
  etag: string;
839
+ id: string;
840
+ url: string;
503
841
  };
504
842
  };
505
843
  download: {
@@ -763,6 +1101,60 @@ type OAuthActions = {
763
1101
  };
764
1102
  };
765
1103
  };
1104
+ type CredentialsActions = {
1105
+ list: {
1106
+ params: {
1107
+ service?: string;
1108
+ };
1109
+ result: {
1110
+ enabled: boolean;
1111
+ entries: Array<{
1112
+ service: string;
1113
+ envVar: string;
1114
+ required: boolean;
1115
+ description: string;
1116
+ configured: boolean;
1117
+ source: 'store' | 'env' | 'none';
1118
+ last4: string;
1119
+ }>;
1120
+ };
1121
+ };
1122
+ set: {
1123
+ params: {
1124
+ service: string;
1125
+ envVar: string;
1126
+ value: string;
1127
+ };
1128
+ result: {
1129
+ saved: boolean;
1130
+ service: string;
1131
+ envVar: string;
1132
+ last4: string;
1133
+ };
1134
+ };
1135
+ remove: {
1136
+ params: {
1137
+ service: string;
1138
+ envVar: string;
1139
+ };
1140
+ result: {
1141
+ removed: boolean;
1142
+ };
1143
+ };
1144
+ test: {
1145
+ params: {
1146
+ service: string;
1147
+ };
1148
+ result: {
1149
+ service: string;
1150
+ configured: boolean;
1151
+ missing: string[];
1152
+ probed: boolean;
1153
+ ok: boolean;
1154
+ message: string;
1155
+ };
1156
+ };
1157
+ };
766
1158
  type OtelActions = {
767
1159
  startSpan: {
768
1160
  params: {
@@ -989,11 +1381,19 @@ type IntegrationContracts = {
989
1381
  twilio: TwilioActions;
990
1382
  email: EmailActions;
991
1383
  webhook: WebhookActions;
1384
+ push: PushActions;
1385
+ calendar: CalendarActions;
1386
+ drive: DriveActions;
1387
+ metaAds: MetaAdsActions;
1388
+ accounting: AccountingActions;
1389
+ banking: BankingActions;
1390
+ esign: EsignActions;
992
1391
  docker: DockerActions;
993
1392
  storage: StorageActions;
994
1393
  queue: QueueActions;
995
1394
  redis: RedisActions;
996
1395
  oauth: OAuthActions;
1396
+ credentials: CredentialsActions;
997
1397
  otel: OtelActions;
998
1398
  cli: CLIActions;
999
1399
  deepagent: DeepAgentActions;
@@ -1015,4 +1415,75 @@ type IntegrationName = keyof IntegrationContracts;
1015
1415
  */
1016
1416
  type IntegrationActionName<K extends IntegrationName> = keyof IntegrationContracts[K] & string;
1017
1417
 
1018
- export type { ArxivActions as A, CLIActions as C, DatabaseActions as D, EmailActions as E, GitHubActions as G, IconifyActions as I, LLMIntegrationActions as L, MLActions as M, OAuthActions as O, QueueActions as Q, RedisActions as R, StorageActions as S, TwilioActions as T, WebhookActions as W, YouTubeActions as Y, DatabaseDriver as a, DatabaseQueryParamValue as b, DatabaseQueryParams as c, DatabaseQueryResult as d, DatabaseRow as e, DeepAgentActions as f, DockerActions as g, IntegrationActionName as h, IntegrationContracts as i, IntegrationName as j, OtelActions as k, StripeActions as l, WikimediaActions as m };
1418
+ /** Entity type the credential rows persist under (never a `.lolo`-declared entity). */
1419
+ declare const CREDENTIAL_ENTITY_TYPE = "AlmadarIntegrationCredential";
1420
+ /** Env var holding the 64-char-hex AES-256 master key (Secret Manager in production). */
1421
+ declare const CREDENTIAL_MASTER_KEY_ENV = "ALMADAR_CREDENTIAL_MASTER_KEY";
1422
+ /**
1423
+ * Structural subset of `@almadar/runtime`'s `PersistenceAdapter` — declared
1424
+ * here because the dependency axis runs integrations → runtime, never the
1425
+ * reverse. Every `PersistenceAdapter` implementation satisfies it as-is.
1426
+ */
1427
+ interface CredentialPersistence {
1428
+ create(entityType: string, data: EntityRow): Promise<{
1429
+ id: string;
1430
+ }>;
1431
+ update(entityType: string, id: string, data: EntityRow): Promise<void>;
1432
+ delete(entityType: string, id: string): Promise<void>;
1433
+ list(entityType: string): Promise<EntityRow[]>;
1434
+ }
1435
+ /** Masked view of one stored credential — safe to return to a settings page. */
1436
+ interface CredentialEntry {
1437
+ service: string;
1438
+ envVar: string;
1439
+ last4: string;
1440
+ updatedAt: number;
1441
+ }
1442
+ /**
1443
+ * Tenant-scoped (app-wide) credential store: one AES-256-GCM-encrypted row
1444
+ * per (service, envVar) through the host's persistence adapter, master key
1445
+ * `ALMADAR_CREDENTIAL_MASTER_KEY` held alone in the platform secret store.
1446
+ *
1447
+ * Resolution contract: credential keys ARE env-var names (the same names
1448
+ * `serviceCredentials` declares and `connectionRef` carries), so a stored
1449
+ * value transparently shadows its env counterpart — store → env →
1450
+ * unconfigured, everywhere.
1451
+ *
1452
+ * `warm()` decrypts all rows into memory so resolution stays synchronous;
1453
+ * every write re-warms the affected entry and notifies subscribers (the
1454
+ * `RuntimeIntegrationManager` re-configures on that signal, so new keys go
1455
+ * live without a restart).
1456
+ */
1457
+ declare class CredentialStore {
1458
+ private readonly adapter;
1459
+ private readonly masterKeyHex;
1460
+ private readonly byEnvVar;
1461
+ private readonly listeners;
1462
+ private warmed;
1463
+ constructor(adapter: CredentialPersistence, masterKey?: string);
1464
+ /** True when a valid master key is present (writes and decryption enabled). */
1465
+ get enabled(): boolean;
1466
+ /** Subscribe to credential changes; returns an unsubscribe function. */
1467
+ subscribe(listener: () => void): () => void;
1468
+ private notify;
1469
+ private encrypt;
1470
+ private decrypt;
1471
+ /**
1472
+ * Load and decrypt every stored row into memory. Returns the number of
1473
+ * resolvable credentials. Without a master key nothing decrypts (rows are
1474
+ * left in place, resolution falls through to env).
1475
+ */
1476
+ warm(): Promise<number>;
1477
+ /** Resolve one credential by env-var name (warmed values only). */
1478
+ resolve(envVar: string): string | undefined;
1479
+ /** All warmed values as an env-shaped map, for merging over the process env. */
1480
+ snapshotEnv(): Record<string, string>;
1481
+ /** Masked entries for display — never includes plaintext. */
1482
+ entries(): CredentialEntry[];
1483
+ /** Upsert one credential (encrypts, persists, re-warms the entry, notifies). */
1484
+ set(service: string, envVar: string, value: string): Promise<CredentialEntry>;
1485
+ /** Delete one credential row; resolution falls back to env afterwards. */
1486
+ remove(envVar: string): Promise<boolean>;
1487
+ }
1488
+
1489
+ export { type ArxivActions as A, type CLIActions as C, type DatabaseActions as D, type EmailActions as E, type GitHubActions as G, type IconifyActions as I, type LLMIntegrationActions as L, type MLActions as M, type OAuthActions as O, type QueueActions as Q, type RedisActions as R, type StorageActions as S, type TwilioActions as T, type WebhookActions as W, type YouTubeActions as Y, CREDENTIAL_ENTITY_TYPE as a, CREDENTIAL_MASTER_KEY_ENV as b, type CredentialEntry as c, type CredentialPersistence as d, CredentialStore as e, type DatabaseDriver as f, type DatabaseQueryParamValue as g, type DatabaseQueryParams as h, type DatabaseQueryResult as i, type DatabaseRow as j, type DeepAgentActions as k, type DockerActions as l, type IntegrationActionName as m, type IntegrationContracts as n, type IntegrationName as o, type OtelActions as p, type StripeActions as q, type WikimediaActions as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/integrations",
3
- "version": "2.24.0",
3
+ "version": "2.25.0",
4
4
  "description": "External service integrations for Almadar applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,29 +33,34 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@almadar/core": "^10.58.0",
37
- "@almadar/llm": "^2.40.0",
36
+ "@almadar/core": "^10.66.0",
37
+ "@almadar/llm": "^2.41.0",
38
38
  "@almadar/logger": "^1.11.0",
39
+ "@aws-sdk/client-s3": "^3.700.0",
40
+ "@aws-sdk/s3-request-presigner": "^3.700.0",
39
41
  "@sendgrid/mail": "^8.1.4",
40
42
  "dotenv": "^16.4.0",
41
43
  "googleapis": "^144.0.0",
44
+ "openid-client": "6.8.7",
42
45
  "pg": "^8.13.1",
43
46
  "resend": "^4.0.1",
44
47
  "stripe": "^17.5.0",
45
48
  "twilio": "^5.3.6",
49
+ "web-push": "^3.6.7",
46
50
  "zod": "^3.23.0"
47
51
  },
48
52
  "devDependencies": {
49
53
  "@almadar/eslint-plugin": "^2.15.0",
50
54
  "@types/node": "^20.0.0",
51
55
  "@types/pg": "^8.11.10",
56
+ "@types/web-push": "^3.6.4",
52
57
  "@typescript-eslint/parser": "8.65.0",
58
+ "@typescript/native": "npm:typescript@^7.0.2",
53
59
  "eslint": "10.0.0",
54
60
  "tsup": "^8.0.0",
55
- "vitest": "^2.1.0",
56
61
  "turbo": "^2.8.17",
57
- "@typescript/native": "npm:typescript@^7.0.2",
58
- "typescript": "npm:@typescript/typescript6@^6.0.2"
62
+ "typescript": "npm:@typescript/typescript6@^6.0.2",
63
+ "vitest": "^2.1.0"
59
64
  },
60
65
  "repository": {
61
66
  "type": "git",
@@ -75,7 +80,7 @@
75
80
  ],
76
81
  "homepage": "https://github.com/almadar-io/almadar#readme",
77
82
  "scripts": {
78
- "build": "tsup",
83
+ "build": "NODE_OPTIONS=--max-old-space-size=8192 tsup",
79
84
  "build:watch": "tsup --watch",
80
85
  "test": "vitest --run",
81
86
  "test:watch": "vitest",
@@ -1,41 +0,0 @@
1
- import { I as IntegrationConfig, B as BaseIntegration, e as IntegrationParams, f as IntegrationResult } from './BaseIntegration-MA-b4fh8.js';
2
-
3
- /**
4
- * Factory for creating and managing integration instances
5
- */
6
- declare class IntegrationFactory {
7
- private instances;
8
- private configs;
9
- /**
10
- * Configure an integration (doesn't instantiate yet)
11
- */
12
- configure(name: string, config: Omit<IntegrationConfig, 'name'>): void;
13
- /**
14
- * Get or create an integration instance
15
- */
16
- get(name: string): BaseIntegration;
17
- /**
18
- * Execute an action on an integration
19
- */
20
- execute(integration: string, action: string, params: IntegrationParams): Promise<IntegrationResult>;
21
- /**
22
- * Check if integration is configured
23
- */
24
- isConfigured(name: string): boolean;
25
- /**
26
- * Register an integration instance directly (used by mock infrastructure)
27
- */
28
- registerInstance(name: string, instance: BaseIntegration): void;
29
- /**
30
- * Clear all instances (useful for testing)
31
- */
32
- clear(): void;
33
- /**
34
- * Clear all instances and configs
35
- */
36
- reset(): void;
37
- }
38
- declare function getIntegrationFactory(): IntegrationFactory;
39
- declare function resetIntegrationFactory(): void;
40
-
41
- export { IntegrationFactory as I, getIntegrationFactory as g, resetIntegrationFactory as r };