@almadar/integrations 2.39.0 → 2.40.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.
@@ -50,7 +50,15 @@ declare class RuntimeIntegrationManager {
50
50
  private credentialStore;
51
51
  private storeEnvBase;
52
52
  private storeFirst;
53
- constructor();
53
+ private readonly tenant;
54
+ /**
55
+ * `tenant`: one tenant of a multi-tenant host. Its services are configured from its credential
56
+ * store alone (never the host's env), and it installs nothing process-wide; resolve its
57
+ * references inside `runWithCredentialScope`.
58
+ */
59
+ constructor(options?: {
60
+ tenant?: boolean;
61
+ });
54
62
  /**
55
63
  * W4: configure with the tenant credential store layered over the env —
56
64
  * store → env → unconfigured. Installs the store as the process-wide
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from '@almadar/logger';
2
2
  import { integratorsRegistry } from '@almadar/core/patterns';
3
3
  import { createHmac, createHash } from 'crypto';
4
+ import { AsyncLocalStorage } from 'async_hooks';
4
5
  import { mkdtempSync, writeFileSync, rmSync, promises } from 'fs';
5
6
  import { join } from 'path';
6
7
  import Stripe2 from 'stripe';
@@ -400,8 +401,7 @@ function getIntegration(name) {
400
401
  function getRegisteredIntegrations() {
401
402
  return Object.keys(INTEGRATION_REGISTRY);
402
403
  }
403
-
404
- // src/factory.ts
404
+ var callLog = createLogger("almadar:integrations:calls");
405
405
  function instanceKey(name, principal) {
406
406
  return principal ? `${name}\0${principal}` : name;
407
407
  }
@@ -446,8 +446,16 @@ var IntegrationFactory = class {
446
446
  * Execute an action on an integration
447
447
  */
448
448
  async execute(integration, action, params, context) {
449
- const instance = this.get(integration, context?.principal);
450
- return await instance.execute(action, params, context);
449
+ const start = performance.now();
450
+ const record = (ok, error) => callLog.call({ kind: "external", service: integration, op: action, durationMs: performance.now() - start, ok, ...error !== void 0 ? { error } : {} });
451
+ try {
452
+ const result = await this.get(integration, context?.principal).execute(action, params, context);
453
+ record(result.success, result.success ? void 0 : result.error?.message);
454
+ return result;
455
+ } catch (err) {
456
+ record(false, err instanceof Error ? err.message : String(err));
457
+ throw err;
458
+ }
451
459
  }
452
460
  /**
453
461
  * Check if integration is configured
@@ -491,9 +499,8 @@ var IntegrationFactory = class {
491
499
  this.configs.clear();
492
500
  }
493
501
  };
494
-
495
- // src/credentials/resolver.ts
496
502
  var installedStore = null;
503
+ var tenantScope = new AsyncLocalStorage();
497
504
  var activeFactory = null;
498
505
  function installActiveFactory(factory) {
499
506
  activeFactory = factory;
@@ -508,6 +515,8 @@ function getInstalledCredentialStore() {
508
515
  return installedStore;
509
516
  }
510
517
  function resolveCredentialRef(ref, env = process.env) {
518
+ const tenant = tenantScope.getStore();
519
+ if (tenant) return tenant.resolve(ref);
511
520
  return installedStore?.resolve(ref) ?? env[ref];
512
521
  }
513
522
  join(".almadar", "dev-credentials.json");
@@ -5437,12 +5446,18 @@ function generateMockFromShape(shape) {
5437
5446
  return data;
5438
5447
  }
5439
5448
  var RuntimeIntegrationManager = class {
5440
- constructor() {
5449
+ /**
5450
+ * `tenant`: one tenant of a multi-tenant host. Its services are configured from its credential
5451
+ * store alone (never the host's env), and it installs nothing process-wide; resolve its
5452
+ * references inside `runWithCredentialScope`.
5453
+ */
5454
+ constructor(options = {}) {
5441
5455
  this.credentialStore = null;
5442
5456
  this.storeEnvBase = null;
5443
5457
  this.storeFirst = false;
5444
5458
  this.factory = new IntegrationFactory();
5445
- installActiveFactory(this.factory);
5459
+ this.tenant = options.tenant === true;
5460
+ if (!this.tenant) installActiveFactory(this.factory);
5446
5461
  }
5447
5462
  /**
5448
5463
  * W4: configure with the tenant credential store layered over the env —
@@ -5454,7 +5469,13 @@ var RuntimeIntegrationManager = class {
5454
5469
  */
5455
5470
  async configureFromStore(store, envOverride) {
5456
5471
  this.credentialStore = store;
5457
- this.storeEnvBase = envOverride ?? process.env;
5472
+ this.storeEnvBase = this.tenant ? {} : envOverride ?? process.env;
5473
+ if (this.tenant) {
5474
+ await store.warm();
5475
+ store.subscribe(() => this.refreshFromStore());
5476
+ this.refreshFromStore();
5477
+ return;
5478
+ }
5458
5479
  this.storeFirst = this.storeEnvBase.ALMADAR_CREDENTIALS_SOURCE === "store";
5459
5480
  installCredentialStore(store);
5460
5481
  await store.warm();