@almadar/integrations 2.2.1 → 2.3.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.
package/LICENSE CHANGED
@@ -1,21 +1,72 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Almadar Team
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: Almadar FZE
6
+ Licensed Work: KFlow Builder / Almadar
7
+ The Licensed Work is (c) 2025-2026 Almadar FZE.
8
+ Additional Use Grant: You may make production use of the Licensed Work for
9
+ non-commercial purposes and for internal evaluation.
10
+ Production use for commercial purposes requires a
11
+ commercial license from the Licensor.
12
+ Change Date: 2030-02-01
13
+ Change License: Apache License, Version 2.0
14
+
15
+ Terms
16
+
17
+ The Licensor hereby grants you the right to copy, modify, create derivative
18
+ works, redistribute, and make non-production use of the Licensed Work. The
19
+ Licensor may make an Additional Use Grant, above, permitting limited
20
+ production use.
21
+
22
+ Effective on the Change Date, or the fourth anniversary of the first publicly
23
+ available distribution of a specific version of the Licensed Work under this
24
+ License, whichever comes first, the Licensor hereby grants you rights under
25
+ the terms of the Change License, and the rights granted in the paragraph
26
+ above terminate.
27
+
28
+ If your use of the Licensed Work does not comply with the requirements
29
+ currently in effect as described in this License, you must purchase a
30
+ commercial license from the Licensor, its affiliated entities, or authorized
31
+ resellers, or you must refrain from using the Licensed Work.
32
+
33
+ All copies of the original and modified Licensed Work, and derivative works
34
+ of the Licensed Work, are subject to this License. This License applies
35
+ separately for each version of the Licensed Work and the Change Date may vary
36
+ for each version of the Licensed Work released by Licensor.
37
+
38
+ You must conspicuously display this License on each original or modified copy
39
+ of the Licensed Work. If you receive the Licensed Work in original or
40
+ modified form from a third party, the terms and conditions set forth in this
41
+ License apply to your use of that work.
42
+
43
+ Any use of the Licensed Work in violation of this License will automatically
44
+ terminate your rights under this License for the current and all other
45
+ versions of the Licensed Work.
46
+
47
+ This License does not grant you any right in any trademark or logo of
48
+ Licensor or its affiliates (provided that you may use a trademark or logo of
49
+ Licensor as expressly required by this License).
50
+
51
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
52
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
53
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
55
+ TITLE.
56
+
57
+ ---
58
+
59
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
60
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
61
+
62
+ ADDITIONAL TERMS:
63
+
64
+ Documentation (builder/packages/website/docs/) is licensed under CC BY 4.0.
65
+
66
+ TRADEMARKS:
67
+
68
+ "Orbital", "KFlow", "Almadar", and the Almadar logo are trademarks of
69
+ Almadar FZE. You may not use these trademarks without prior written
70
+ permission from Almadar FZE.
71
+
72
+ For licensing inquiries: licensing@almadar.io
package/README.md CHANGED
@@ -287,4 +287,4 @@ class MyIntegration extends BaseIntegration {
287
287
 
288
288
  ## License
289
289
 
290
- MIT
290
+ BSL 1.1 (Business Source License). Converts to Apache 2.0 on 2030-02-01. Non-production use is free.
@@ -3,15 +3,28 @@ import '../BaseIntegration-DNSuiUnG.js';
3
3
 
4
4
  /**
5
5
  * Runtime integration manager
6
- * Auto-configures integrations from environment variables
6
+ * Auto-configures integrations from environment variables.
7
+ * When USE_MOCK_DATA=true, registers mock integrations for all services
8
+ * using response shapes from services-registry.json.
7
9
  */
8
10
  declare class RuntimeIntegrationManager {
9
11
  private factory;
10
12
  constructor();
11
13
  /**
12
- * Configure from environment variables
14
+ * Configure from environment variables.
15
+ * In mock mode (USE_MOCK_DATA=true), all services return realistic mock data.
13
16
  */
14
17
  configureFromEnv(): void;
18
+ /**
19
+ * Configure mock mode: register MockIntegration for all known services
20
+ * with auto-generated responses from the services registry.
21
+ */
22
+ private configureMockMode;
23
+ /**
24
+ * Load services registry from @almadar/patterns.
25
+ * Returns a map of service name to { actions: [...] }.
26
+ */
27
+ private loadServicesRegistry;
15
28
  /**
16
29
  * Get effect handler for runtime
17
30
  */
@@ -1,3 +1,8 @@
1
+ import { createRequire } from 'module';
2
+ import { integratorsRegistry } from '@almadar/patterns';
3
+
4
+ // src/runtime/RuntimeIntegrationManager.ts
5
+
1
6
  // src/registry.ts
2
7
  var INTEGRATION_REGISTRY = {};
3
8
  function getIntegration(name) {
@@ -65,6 +70,258 @@ var IntegrationFactory = class {
65
70
  }
66
71
  };
67
72
 
73
+ // src/core/logger.ts
74
+ var ConsoleLogger = class {
75
+ constructor(level = "info") {
76
+ this.level = level;
77
+ }
78
+ debug(message, meta) {
79
+ if (this.shouldLog("debug")) {
80
+ console.debug(`[DEBUG] ${message}`, meta || "");
81
+ }
82
+ }
83
+ info(message, meta) {
84
+ if (this.shouldLog("info")) {
85
+ console.log(`[INFO] ${message}`, meta || "");
86
+ }
87
+ }
88
+ warn(message, meta) {
89
+ if (this.shouldLog("warn")) {
90
+ console.warn(`[WARN] ${message}`, meta || "");
91
+ }
92
+ }
93
+ error(message, meta) {
94
+ if (this.shouldLog("error")) {
95
+ console.error(`[ERROR] ${message}`, meta || "");
96
+ }
97
+ }
98
+ shouldLog(level) {
99
+ const levels = ["debug", "info", "warn", "error"];
100
+ return levels.indexOf(level) >= levels.indexOf(this.level);
101
+ }
102
+ };
103
+ function validateParams(integration, action, params) {
104
+ const typedRegistry = integratorsRegistry;
105
+ const registry = typedRegistry.integrators[integration];
106
+ if (!registry) {
107
+ return {
108
+ valid: false,
109
+ errors: [
110
+ {
111
+ param: "integration",
112
+ message: `Unknown integration: ${integration}`
113
+ }
114
+ ]
115
+ };
116
+ }
117
+ const actionDef = registry.actions.find((a) => a.name === action);
118
+ if (!actionDef) {
119
+ return {
120
+ valid: false,
121
+ errors: [{ param: "action", message: `Unknown action: ${action}` }]
122
+ };
123
+ }
124
+ const errors = [];
125
+ for (const paramDef of actionDef.params) {
126
+ if (paramDef.required && !(paramDef.name in params)) {
127
+ errors.push({
128
+ param: paramDef.name,
129
+ message: `Missing required parameter: ${paramDef.name}`
130
+ });
131
+ }
132
+ if (paramDef.name in params) {
133
+ const value = params[paramDef.name];
134
+ const expectedType = paramDef.type;
135
+ const actualType = typeof value;
136
+ if (expectedType === "number" && actualType !== "number") {
137
+ errors.push({
138
+ param: paramDef.name,
139
+ message: `Expected ${expectedType}, got ${actualType}`
140
+ });
141
+ }
142
+ if (expectedType === "string" && actualType !== "string") {
143
+ errors.push({
144
+ param: paramDef.name,
145
+ message: `Expected ${expectedType}, got ${actualType}`
146
+ });
147
+ }
148
+ if (expectedType === "array" && !Array.isArray(value)) {
149
+ errors.push({
150
+ param: paramDef.name,
151
+ message: `Expected array, got ${actualType}`
152
+ });
153
+ }
154
+ if (expectedType === "object" && (actualType !== "object" || Array.isArray(value) || value === null)) {
155
+ errors.push({
156
+ param: paramDef.name,
157
+ message: `Expected object, got ${actualType}`
158
+ });
159
+ }
160
+ }
161
+ }
162
+ return {
163
+ valid: errors.length === 0,
164
+ errors
165
+ };
166
+ }
167
+
168
+ // src/core/retry.ts
169
+ async function withRetry(fn, config) {
170
+ const {
171
+ maxAttempts,
172
+ backoffMs,
173
+ maxBackoffMs = 3e4,
174
+ retryableErrors
175
+ } = config;
176
+ let lastError;
177
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
178
+ try {
179
+ return await fn();
180
+ } catch (error) {
181
+ lastError = error;
182
+ if (error && typeof error === "object" && "code" in error && retryableErrors) {
183
+ const integrationError = error;
184
+ if (!retryableErrors.includes(integrationError.code)) {
185
+ throw error;
186
+ }
187
+ }
188
+ if (attempt === maxAttempts) {
189
+ throw error;
190
+ }
191
+ const delay = Math.min(
192
+ backoffMs * Math.pow(2, attempt - 1),
193
+ maxBackoffMs
194
+ );
195
+ await new Promise((resolve) => setTimeout(resolve, delay));
196
+ }
197
+ }
198
+ throw lastError;
199
+ }
200
+
201
+ // src/core/BaseIntegration.ts
202
+ var BaseIntegration = class {
203
+ constructor(config) {
204
+ this.config = config;
205
+ this.logger = config.logger || new ConsoleLogger();
206
+ }
207
+ /**
208
+ * Validate action params against registry
209
+ */
210
+ validateParams(action, params) {
211
+ return validateParams(this.config.name, action, params);
212
+ }
213
+ /**
214
+ * Handle errors uniformly
215
+ */
216
+ handleError(action, error) {
217
+ this.logger.error(`Integration error in ${this.config.name}.${action}`, {
218
+ error
219
+ });
220
+ const integrationError = error instanceof Error ? error : new Error(String(error));
221
+ return {
222
+ success: false,
223
+ error: integrationError,
224
+ metadata: this.createMetadata(action, 0, 0)
225
+ };
226
+ }
227
+ /**
228
+ * Create metadata for result
229
+ */
230
+ createMetadata(action, duration, retries = 0) {
231
+ return {
232
+ integration: this.config.name,
233
+ action,
234
+ duration,
235
+ retries,
236
+ timestamp: Date.now()
237
+ };
238
+ }
239
+ /**
240
+ * Execute with retry logic
241
+ */
242
+ async executeWithRetry(fn) {
243
+ if (!this.config.retry) {
244
+ return fn();
245
+ }
246
+ return withRetry(fn, {
247
+ maxAttempts: this.config.retry.maxAttempts,
248
+ backoffMs: this.config.retry.backoffMs,
249
+ maxBackoffMs: this.config.retry.maxBackoffMs,
250
+ retryableErrors: [
251
+ "TIMEOUT_ERROR",
252
+ "NETWORK_ERROR",
253
+ "RATE_LIMIT_ERROR"
254
+ ]
255
+ });
256
+ }
257
+ };
258
+
259
+ // src/types.ts
260
+ var IntegrationError = class extends Error {
261
+ constructor(message, code = "UNKNOWN_ERROR", details) {
262
+ super(message);
263
+ this.name = "IntegrationError";
264
+ this.code = code;
265
+ this.details = details;
266
+ }
267
+ toJSON() {
268
+ return {
269
+ name: this.name,
270
+ message: this.message,
271
+ code: this.code,
272
+ integration: this.integration,
273
+ action: this.action,
274
+ details: this.details
275
+ };
276
+ }
277
+ };
278
+
279
+ // src/mocks/MockIntegration.ts
280
+ var MockIntegration = class extends BaseIntegration {
281
+ constructor(config) {
282
+ super(config);
283
+ this.responses = /* @__PURE__ */ new Map();
284
+ this.calls = [];
285
+ }
286
+ /**
287
+ * Set mock response for an action
288
+ */
289
+ setResponse(action, data) {
290
+ this.responses.set(action, data);
291
+ }
292
+ /**
293
+ * Get all calls made to this integration
294
+ */
295
+ getCalls() {
296
+ return this.calls;
297
+ }
298
+ /**
299
+ * Clear all calls
300
+ */
301
+ clearCalls() {
302
+ this.calls = [];
303
+ }
304
+ async execute(action, params) {
305
+ this.calls.push({ action, params });
306
+ const data = this.responses.get(action);
307
+ if (!data) {
308
+ return {
309
+ success: false,
310
+ error: new IntegrationError(
311
+ `No mock response for action: ${action}`,
312
+ "UNKNOWN_ERROR"
313
+ ),
314
+ metadata: this.createMetadata(action, 0)
315
+ };
316
+ }
317
+ return {
318
+ success: true,
319
+ data,
320
+ metadata: this.createMetadata(action, 0)
321
+ };
322
+ }
323
+ };
324
+
68
325
  // src/runtime/effectHandler.ts
69
326
  function createCallServiceHandler(factory) {
70
327
  return async (service, action, params) => {
@@ -77,15 +334,45 @@ function createCallServiceHandler(factory) {
77
334
  }
78
335
 
79
336
  // src/runtime/RuntimeIntegrationManager.ts
337
+ function generateMockFromShape(shape) {
338
+ const data = {};
339
+ for (const [key, type] of Object.entries(shape)) {
340
+ switch (type) {
341
+ case "string":
342
+ data[key] = `mock_${key}`;
343
+ break;
344
+ case "number":
345
+ data[key] = 42;
346
+ break;
347
+ case "boolean":
348
+ data[key] = true;
349
+ break;
350
+ case "object":
351
+ data[key] = {};
352
+ break;
353
+ case "string[]":
354
+ data[key] = [];
355
+ break;
356
+ default:
357
+ data[key] = `mock_${key}`;
358
+ }
359
+ }
360
+ return data;
361
+ }
80
362
  var RuntimeIntegrationManager = class {
81
363
  constructor() {
82
364
  this.factory = new IntegrationFactory();
83
365
  }
84
366
  /**
85
- * Configure from environment variables
367
+ * Configure from environment variables.
368
+ * In mock mode (USE_MOCK_DATA=true), all services return realistic mock data.
86
369
  */
87
370
  configureFromEnv() {
88
371
  const env = process.env;
372
+ if (env.USE_MOCK_DATA === "true") {
373
+ this.configureMockMode();
374
+ return;
375
+ }
89
376
  if (env.STRIPE_SECRET_KEY) {
90
377
  this.factory.configure("stripe", {
91
378
  env: {
@@ -160,6 +447,50 @@ var RuntimeIntegrationManager = class {
160
447
  });
161
448
  }
162
449
  }
450
+ /**
451
+ * Configure mock mode: register MockIntegration for all known services
452
+ * with auto-generated responses from the services registry.
453
+ */
454
+ configureMockMode() {
455
+ const registry = this.loadServicesRegistry();
456
+ for (const [serviceName, service] of Object.entries(registry)) {
457
+ const mock = new MockIntegration({ name: serviceName, env: {} });
458
+ for (const action of service.actions) {
459
+ if (action.responseShape && Object.keys(action.responseShape).length > 0) {
460
+ mock.setResponse(action.name, generateMockFromShape(action.responseShape));
461
+ } else {
462
+ mock.setResponse(action.name, { success: true, _mock: true, _action: action.name });
463
+ }
464
+ }
465
+ this.factory.configure(serviceName, { env: {} });
466
+ this.factory.instances.set(serviceName, mock);
467
+ }
468
+ const originalExecute = this.factory.execute.bind(this.factory);
469
+ this.factory.execute = async (integration, action, params) => {
470
+ try {
471
+ return await originalExecute(integration, action, params);
472
+ } catch {
473
+ return {
474
+ success: true,
475
+ data: { ...params, _mock: true, _service: integration, _action: action },
476
+ metadata: { integration, action, duration: 0, retries: 0, timestamp: Date.now() }
477
+ };
478
+ }
479
+ };
480
+ }
481
+ /**
482
+ * Load services registry from @almadar/patterns.
483
+ * Returns a map of service name to { actions: [...] }.
484
+ */
485
+ loadServicesRegistry() {
486
+ try {
487
+ const esmRequire = createRequire(import.meta.url);
488
+ const registry = esmRequire("@almadar/patterns/services-registry.json");
489
+ return registry.services;
490
+ } catch {
491
+ return {};
492
+ }
493
+ }
163
494
  /**
164
495
  * Get effect handler for runtime
165
496
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/registry.ts","../../src/factory.ts","../../src/runtime/effectHandler.ts","../../src/runtime/RuntimeIntegrationManager.ts"],"names":[],"mappings":";AAaO,IAAM,uBAA+D,EAAC;AAetE,SAAS,eACd,IAAA,EACoC;AACpC,EAAA,OAAO,qBAAqB,IAAI,CAAA;AAClC;;;ACzBO,IAAM,qBAAN,MAAyB;AAAA,EAAzB,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,SAAA,uBAA8C,GAAA,EAAI;AAC1D,IAAA,IAAA,CAAQ,OAAA,uBAA8C,GAAA,EAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAK1D,SAAA,CAAU,MAAc,MAAA,EAA+C;AACrE,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,IAAA,EAAM,EAAE,IAAA,EAAM,GAAG,QAAQ,CAAA;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAA,EAA+B;AAEjC,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AAC5B,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,IAChC;AAGA,IAAA,MAAM,WAAA,GAAc,eAAe,IAAI,CAAA;AACvC,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,IAAI,CAAA,0BAAA,CAA4B,CAAA;AAAA,IAC1E;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,+BAA+B,IAAI,CAAA,yBAAA;AAAA,OACrC;AAAA,IACF;AAGA,IAAA,MAAM,QAAA,GAAW,IAAI,WAAA,CAAY,MAAM,CAAA;AACvC,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAA,EAAM,QAAQ,CAAA;AAEjC,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CACJ,WAAA,EACA,MAAA,EACA,MAAA,EAC4B;AAC5B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,IAAA,OAAO,MAAM,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,IAAA,EAAuB;AAClC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF,CAAA;;;AC3EO,SAAS,yBAAyB,OAAA,EAA6B;AACpE,EAAA,OAAO,OACL,OAAA,EACA,MAAA,EACA,MAAA,KACqB;AACrB,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,MAAA,EAAQ,MAAA,IAAU,EAAE,CAAA;AAElE,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,MAAA,CAAO,KAAA;AAAA,IACf;AAEA,IAAA,OAAO,MAAA,CAAO,IAAA;AAAA,EAChB,CAAA;AACF;;;ACbO,IAAM,4BAAN,MAAgC;AAAA,EAGrC,WAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,kBAAA,EAAmB;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAAyB;AACvB,IAAA,MAAM,MAAM,OAAA,CAAQ,GAAA;AAGpB,IAAA,IAAI,IAAI,iBAAA,EAAmB;AACzB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,QAAA,EAAU;AAAA,QAC/B,GAAA,EAAK;AAAA,UACH,mBAAmB,GAAA,CAAI;AAAA;AACzB,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,IAAI,eAAA,EAAiB;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,SAAA,EAAW;AAAA,QAChC,GAAA,EAAK;AAAA,UACH,iBAAiB,GAAA,CAAI;AAAA;AACvB,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,GAAA,CAAI,kBAAA,IAAsB,GAAA,CAAI,iBAAA,EAAmB;AACnD,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,QAAA,EAAU;AAAA,QAC/B,GAAA,EAAK;AAAA,UACH,oBAAoB,GAAA,CAAI,kBAAA;AAAA,UACxB,mBAAmB,GAAA,CAAI,iBAAA;AAAA,UACvB,mBAAA,EAAqB,IAAI,mBAAA,IAAuB;AAAA;AAClD,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,IAAI,gBAAA,EAAkB;AACxB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,OAAA,EAAS;AAAA,QAC9B,GAAA,EAAK;AAAA,UACH,QAAA,EAAU,UAAA;AAAA,UACV,kBAAkB,GAAA,CAAI,gBAAA;AAAA,UACtB,UAAA,EAAY,IAAI,UAAA,IAAc;AAAA;AAChC,OACD,CAAA;AAAA,IACH,CAAA,MAAA,IAES,IAAI,cAAA,EAAgB;AAC3B,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,OAAA,EAAS;AAAA,QAC9B,GAAA,EAAK;AAAA,UACH,QAAA,EAAU,QAAA;AAAA,UACV,gBAAgB,GAAA,CAAI,cAAA;AAAA,UACpB,UAAA,EAAY,IAAI,UAAA,IAAc;AAAA;AAChC,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,IAAI,iBAAA,EAAmB;AACzB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,KAAA,EAAO;AAAA,QAC5B,GAAA,EAAK;AAAA,UACH,QAAA,EAAU,WAAA;AAAA,UACV,mBAAmB,GAAA,CAAI;AAAA;AACzB,OACD,CAAA;AAAA,IACH,CAAA,MAAA,IAES,IAAI,cAAA,EAAgB;AAC3B,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,KAAA,EAAO;AAAA,QAC5B,GAAA,EAAK;AAAA,UACH,QAAA,EAAU,QAAA;AAAA,UACV,gBAAgB,GAAA,CAAI;AAAA;AACtB,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,IAAI,iBAAA,EAAmB;AACzB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,WAAA,EAAa;AAAA,QAClC,GAAA,EAAK;AAAA,UACH,mBAAmB,GAAA,CAAI,iBAAA;AAAA,UACvB,iBAAA,EAAmB,IAAI,iBAAA,IAAqB;AAAA;AAC9C,OACD,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,IAAI,YAAA,EAAc;AACpB,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,QAAA,EAAU;AAAA,QAC/B,GAAA,EAAK;AAAA,UACH,cAAc,GAAA,CAAI,YAAA;AAAA,UAClB,YAAA,EAAc,IAAI,YAAA,IAAgB,EAAA;AAAA,UAClC,WAAA,EAAa,IAAI,WAAA,IAAe,EAAA;AAAA,UAChC,eAAA,EAAiB,IAAI,eAAA,IAAmB;AAAA;AAC1C,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAA,GAAwB;AACtB,IAAA,OAAO,wBAAA,CAAyB,KAAK,OAAO,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AACF","file":"index.js","sourcesContent":["import type { IntegrationConfig } from './types';\nimport { BaseIntegration } from './core/BaseIntegration';\n\n/**\n * Integration constructor type\n */\nexport type IntegrationConstructor = new (\n config: IntegrationConfig,\n) => BaseIntegration;\n\n/**\n * Integration registry (populated as integrations are imported)\n */\nexport const INTEGRATION_REGISTRY: Record<string, IntegrationConstructor> = {};\n\n/**\n * Register an integration\n */\nexport function registerIntegration(\n name: string,\n constructor: IntegrationConstructor,\n): void {\n INTEGRATION_REGISTRY[name] = constructor;\n}\n\n/**\n * Get integration constructor by name\n */\nexport function getIntegration(\n name: string,\n): IntegrationConstructor | undefined {\n return INTEGRATION_REGISTRY[name];\n}\n\n/**\n * Check if integration is known\n */\nexport function isKnownIntegration(name: string): boolean {\n return name in INTEGRATION_REGISTRY;\n}\n\n/**\n * Get all registered integration names\n */\nexport function getRegisteredIntegrations(): string[] {\n return Object.keys(INTEGRATION_REGISTRY);\n}\n","import type { IntegrationConfig, IntegrationResult } from './types';\nimport { BaseIntegration } from './core/BaseIntegration';\nimport { getIntegration } from './registry';\n\n/**\n * Factory for creating and managing integration instances\n */\nexport class IntegrationFactory {\n private instances: Map<string, BaseIntegration> = new Map();\n private configs: Map<string, IntegrationConfig> = new Map();\n\n /**\n * Configure an integration (doesn't instantiate yet)\n */\n configure(name: string, config: Omit<IntegrationConfig, 'name'>): void {\n this.configs.set(name, { name, ...config });\n }\n\n /**\n * Get or create an integration instance\n */\n get(name: string): BaseIntegration {\n // Return existing instance\n if (this.instances.has(name)) {\n return this.instances.get(name)!;\n }\n\n // Get constructor\n const Constructor = getIntegration(name);\n if (!Constructor) {\n throw new Error(`Unknown integration: ${name}. Make sure it's imported.`);\n }\n\n // Get config\n const config = this.configs.get(name);\n if (!config) {\n throw new Error(\n `Integration not configured: ${name}. Call configure() first.`,\n );\n }\n\n // Create instance\n const instance = new Constructor(config);\n this.instances.set(name, instance);\n\n return instance;\n }\n\n /**\n * Execute an action on an integration\n */\n async execute(\n integration: string,\n action: string,\n params: Record<string, unknown>,\n ): Promise<IntegrationResult> {\n const instance = this.get(integration);\n return await instance.execute(action, params);\n }\n\n /**\n * Check if integration is configured\n */\n isConfigured(name: string): boolean {\n return this.configs.has(name);\n }\n\n /**\n * Clear all instances (useful for testing)\n */\n clear(): void {\n this.instances.clear();\n }\n\n /**\n * Clear all instances and configs\n */\n reset(): void {\n this.instances.clear();\n this.configs.clear();\n }\n}\n\nlet _factory: IntegrationFactory | null = null;\n\nexport function getIntegrationFactory(): IntegrationFactory {\n if (!_factory) {\n _factory = new IntegrationFactory();\n }\n return _factory;\n}\n\nexport function resetIntegrationFactory(): void {\n _factory?.reset();\n _factory = null;\n}\n","import { IntegrationFactory } from '../factory';\nimport type { IntegrationResult } from '../types';\n\n/**\n * Create a callService effect handler for @almadar/runtime\n */\nexport function createCallServiceHandler(factory: IntegrationFactory) {\n return async (\n service: string,\n action: string,\n params: Record<string, unknown> | undefined,\n ): Promise<unknown> => {\n const result = await factory.execute(service, action, params || {});\n\n if (!result.success) {\n throw result.error;\n }\n\n return result.data;\n };\n}\n","import { IntegrationFactory } from '../factory';\nimport { createCallServiceHandler } from './effectHandler';\n\n/**\n * Runtime integration manager\n * Auto-configures integrations from environment variables\n */\nexport class RuntimeIntegrationManager {\n private factory: IntegrationFactory;\n\n constructor() {\n this.factory = new IntegrationFactory();\n }\n\n /**\n * Configure from environment variables\n */\n configureFromEnv(): void {\n const env = process.env;\n\n // Stripe\n if (env.STRIPE_SECRET_KEY) {\n this.factory.configure('stripe', {\n env: {\n STRIPE_SECRET_KEY: env.STRIPE_SECRET_KEY,\n },\n });\n }\n\n // YouTube\n if (env.YOUTUBE_API_KEY) {\n this.factory.configure('youtube', {\n env: {\n YOUTUBE_API_KEY: env.YOUTUBE_API_KEY,\n },\n });\n }\n\n // Twilio\n if (env.TWILIO_ACCOUNT_SID && env.TWILIO_AUTH_TOKEN) {\n this.factory.configure('twilio', {\n env: {\n TWILIO_ACCOUNT_SID: env.TWILIO_ACCOUNT_SID,\n TWILIO_AUTH_TOKEN: env.TWILIO_AUTH_TOKEN,\n TWILIO_PHONE_NUMBER: env.TWILIO_PHONE_NUMBER || '',\n },\n });\n }\n\n // Email (SendGrid)\n if (env.SENDGRID_API_KEY) {\n this.factory.configure('email', {\n env: {\n PROVIDER: 'sendgrid',\n SENDGRID_API_KEY: env.SENDGRID_API_KEY,\n FROM_EMAIL: env.FROM_EMAIL || 'noreply@example.com',\n },\n });\n }\n // Email (Resend)\n else if (env.RESEND_API_KEY) {\n this.factory.configure('email', {\n env: {\n PROVIDER: 'resend',\n RESEND_API_KEY: env.RESEND_API_KEY,\n FROM_EMAIL: env.FROM_EMAIL || 'noreply@example.com',\n },\n });\n }\n\n // LLM (Anthropic)\n if (env.ANTHROPIC_API_KEY) {\n this.factory.configure('llm', {\n env: {\n PROVIDER: 'anthropic',\n ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,\n },\n });\n }\n // LLM (OpenAI)\n else if (env.OPENAI_API_KEY) {\n this.factory.configure('llm', {\n env: {\n PROVIDER: 'openai',\n OPENAI_API_KEY: env.OPENAI_API_KEY,\n },\n });\n }\n\n // DeepAgent\n if (env.DEEPAGENT_API_URL) {\n this.factory.configure('deepagent', {\n env: {\n DEEPAGENT_API_URL: env.DEEPAGENT_API_URL,\n DEEPAGENT_API_KEY: env.DEEPAGENT_API_KEY || '',\n },\n });\n }\n\n // GitHub\n if (env.GITHUB_TOKEN) {\n this.factory.configure('github', {\n env: {\n GITHUB_TOKEN: env.GITHUB_TOKEN,\n GITHUB_OWNER: env.GITHUB_OWNER || '',\n GITHUB_REPO: env.GITHUB_REPO || '',\n GITHUB_WORK_DIR: env.GITHUB_WORK_DIR || '',\n },\n });\n }\n }\n\n /**\n * Get effect handler for runtime\n */\n getCallServiceHandler() {\n return createCallServiceHandler(this.factory);\n }\n\n /**\n * Get factory (for advanced usage)\n */\n getFactory(): IntegrationFactory {\n return this.factory;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/registry.ts","../../src/factory.ts","../../src/core/logger.ts","../../src/core/validation.ts","../../src/core/retry.ts","../../src/core/BaseIntegration.ts","../../src/types.ts","../../src/mocks/MockIntegration.ts","../../src/runtime/effectHandler.ts","../../src/runtime/RuntimeIntegrationManager.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { IntegrationConfig } from './types';\nimport { BaseIntegration } from './core/BaseIntegration';\n\n/**\n * Integration constructor type\n */\nexport type IntegrationConstructor = new (\n config: IntegrationConfig,\n) => BaseIntegration;\n\n/**\n * Integration registry (populated as integrations are imported)\n */\nexport const INTEGRATION_REGISTRY: Record<string, IntegrationConstructor> = {};\n\n/**\n * Register an integration\n */\nexport function registerIntegration(\n name: string,\n constructor: IntegrationConstructor,\n): void {\n INTEGRATION_REGISTRY[name] = constructor;\n}\n\n/**\n * Get integration constructor by name\n */\nexport function getIntegration(\n name: string,\n): IntegrationConstructor | undefined {\n return INTEGRATION_REGISTRY[name];\n}\n\n/**\n * Check if integration is known\n */\nexport function isKnownIntegration(name: string): boolean {\n return name in INTEGRATION_REGISTRY;\n}\n\n/**\n * Get all registered integration names\n */\nexport function getRegisteredIntegrations(): string[] {\n return Object.keys(INTEGRATION_REGISTRY);\n}\n","import type { IntegrationConfig, IntegrationResult } from './types';\nimport { BaseIntegration } from './core/BaseIntegration';\nimport { getIntegration } from './registry';\n\n/**\n * Factory for creating and managing integration instances\n */\nexport class IntegrationFactory {\n private instances: Map<string, BaseIntegration> = new Map();\n private configs: Map<string, IntegrationConfig> = new Map();\n\n /**\n * Configure an integration (doesn't instantiate yet)\n */\n configure(name: string, config: Omit<IntegrationConfig, 'name'>): void {\n this.configs.set(name, { name, ...config });\n }\n\n /**\n * Get or create an integration instance\n */\n get(name: string): BaseIntegration {\n // Return existing instance\n if (this.instances.has(name)) {\n return this.instances.get(name)!;\n }\n\n // Get constructor\n const Constructor = getIntegration(name);\n if (!Constructor) {\n throw new Error(`Unknown integration: ${name}. Make sure it's imported.`);\n }\n\n // Get config\n const config = this.configs.get(name);\n if (!config) {\n throw new Error(\n `Integration not configured: ${name}. Call configure() first.`,\n );\n }\n\n // Create instance\n const instance = new Constructor(config);\n this.instances.set(name, instance);\n\n return instance;\n }\n\n /**\n * Execute an action on an integration\n */\n async execute(\n integration: string,\n action: string,\n params: Record<string, unknown>,\n ): Promise<IntegrationResult> {\n const instance = this.get(integration);\n return await instance.execute(action, params);\n }\n\n /**\n * Check if integration is configured\n */\n isConfigured(name: string): boolean {\n return this.configs.has(name);\n }\n\n /**\n * Clear all instances (useful for testing)\n */\n clear(): void {\n this.instances.clear();\n }\n\n /**\n * Clear all instances and configs\n */\n reset(): void {\n this.instances.clear();\n this.configs.clear();\n }\n}\n\nlet _factory: IntegrationFactory | null = null;\n\nexport function getIntegrationFactory(): IntegrationFactory {\n if (!_factory) {\n _factory = new IntegrationFactory();\n }\n return _factory;\n}\n\nexport function resetIntegrationFactory(): void {\n _factory?.reset();\n _factory = null;\n}\n","import { IntegrationLogger } from '../types';\n\n/**\n * Console-based logger implementation\n */\nexport class ConsoleLogger implements IntegrationLogger {\n private level: 'debug' | 'info' | 'warn' | 'error';\n\n constructor(level: 'debug' | 'info' | 'warn' | 'error' = 'info') {\n this.level = level;\n }\n\n debug(message: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('debug')) {\n console.debug(`[DEBUG] ${message}`, meta || '');\n }\n }\n\n info(message: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('info')) {\n console.log(`[INFO] ${message}`, meta || '');\n }\n }\n\n warn(message: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('warn')) {\n console.warn(`[WARN] ${message}`, meta || '');\n }\n }\n\n error(message: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('error')) {\n console.error(`[ERROR] ${message}`, meta || '');\n }\n }\n\n private shouldLog(level: string): boolean {\n const levels = ['debug', 'info', 'warn', 'error'];\n return levels.indexOf(level) >= levels.indexOf(this.level);\n }\n}\n","import type { ValidationResult, ValidationError } from '../types';\n\n// Import integrators registry from the package main export (JSON is inlined in the bundle)\nimport { integratorsRegistry } from '@almadar/patterns';\n\ninterface ActionParam {\n name: string;\n type: string;\n required?: boolean;\n description?: string;\n}\n\ninterface ActionDef {\n name: string;\n description?: string;\n params: ActionParam[];\n}\n\ninterface IntegratorEntry {\n name: string;\n description?: string;\n category?: string;\n actions: ActionDef[];\n}\n\ntype IntegratorsRegistry = Record<string, {\n version?: string;\n exportedAt?: string;\n integrators: Record<string, IntegratorEntry>;\n}>;\n\n/**\n * Validate action params against registry schema\n */\nexport function validateParams(\n integration: string,\n action: string,\n params: Record<string, unknown>,\n): ValidationResult {\n const typedRegistry = integratorsRegistry as unknown as IntegratorsRegistry[string];\n const registry = typedRegistry.integrators[integration];\n\n if (!registry) {\n return {\n valid: false,\n errors: [\n {\n param: 'integration',\n message: `Unknown integration: ${integration}`,\n },\n ],\n };\n }\n\n const actionDef = registry.actions.find((a: ActionDef) => a.name === action);\n\n if (!actionDef) {\n return {\n valid: false,\n errors: [{ param: 'action', message: `Unknown action: ${action}` }],\n };\n }\n\n const errors: ValidationError[] = [];\n\n // Check required params\n for (const paramDef of actionDef.params) {\n if (paramDef.required && !(paramDef.name in params)) {\n errors.push({\n param: paramDef.name,\n message: `Missing required parameter: ${paramDef.name}`,\n });\n }\n\n // Type validation\n if (paramDef.name in params) {\n const value = params[paramDef.name];\n const expectedType = paramDef.type;\n const actualType = typeof value;\n\n if (expectedType === 'number' && actualType !== 'number') {\n errors.push({\n param: paramDef.name,\n message: `Expected ${expectedType}, got ${actualType}`,\n });\n }\n\n if (expectedType === 'string' && actualType !== 'string') {\n errors.push({\n param: paramDef.name,\n message: `Expected ${expectedType}, got ${actualType}`,\n });\n }\n\n if (expectedType === 'array' && !Array.isArray(value)) {\n errors.push({\n param: paramDef.name,\n message: `Expected array, got ${actualType}`,\n });\n }\n\n if (\n expectedType === 'object' &&\n (actualType !== 'object' || Array.isArray(value) || value === null)\n ) {\n errors.push({\n param: paramDef.name,\n message: `Expected object, got ${actualType}`,\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","import type { IntegrationError, IntegrationErrorCode } from '../types';\n\n/**\n * Retry configuration\n */\nexport interface RetryConfig {\n maxAttempts: number;\n backoffMs: number;\n maxBackoffMs?: number;\n retryableErrors?: IntegrationErrorCode[];\n}\n\n/**\n * Execute a function with retry logic\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig,\n): Promise<T> {\n const {\n maxAttempts,\n backoffMs,\n maxBackoffMs = 30000,\n retryableErrors,\n } = config;\n\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Check if error is retryable\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n retryableErrors\n ) {\n const integrationError = error as IntegrationError;\n if (!retryableErrors.includes(integrationError.code)) {\n throw error;\n }\n }\n\n // Last attempt, throw\n if (attempt === maxAttempts) {\n throw error;\n }\n\n // Wait before retry (exponential backoff)\n const delay = Math.min(\n backoffMs * Math.pow(2, attempt - 1),\n maxBackoffMs,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}\n","import type {\n IntegrationConfig,\n IntegrationResult,\n IntegrationLogger,\n IntegrationError,\n} from '../types';\nimport { ConsoleLogger } from './logger';\nimport { validateParams } from './validation';\nimport { withRetry } from './retry';\n\n/**\n * Base class for all integrations\n */\nexport abstract class BaseIntegration {\n protected config: IntegrationConfig;\n protected logger: IntegrationLogger;\n\n constructor(config: IntegrationConfig) {\n this.config = config;\n this.logger = config.logger || new ConsoleLogger();\n }\n\n /**\n * Execute an action\n */\n abstract execute(\n action: string,\n params: Record<string, unknown>,\n ): Promise<IntegrationResult>;\n\n /**\n * Validate action params against registry\n */\n protected validateParams(\n action: string,\n params: Record<string, unknown>,\n ): ReturnType<typeof validateParams> {\n return validateParams(this.config.name, action, params);\n }\n\n /**\n * Handle errors uniformly\n */\n protected handleError(action: string, error: unknown): IntegrationResult {\n this.logger.error(`Integration error in ${this.config.name}.${action}`, {\n error,\n });\n\n const integrationError =\n error instanceof Error\n ? error\n : new Error(String(error));\n\n return {\n success: false,\n error: integrationError as IntegrationError,\n metadata: this.createMetadata(action, 0, 0),\n };\n }\n\n /**\n * Create metadata for result\n */\n protected createMetadata(\n action: string,\n duration: number,\n retries: number = 0,\n ): IntegrationResult['metadata'] {\n return {\n integration: this.config.name,\n action,\n duration,\n retries,\n timestamp: Date.now(),\n };\n }\n\n /**\n * Execute with retry logic\n */\n protected async executeWithRetry<T>(\n fn: () => Promise<T>,\n ): Promise<T> {\n if (!this.config.retry) {\n return fn();\n }\n\n return withRetry(fn, {\n maxAttempts: this.config.retry.maxAttempts,\n backoffMs: this.config.retry.backoffMs,\n maxBackoffMs: this.config.retry.maxBackoffMs,\n retryableErrors: [\n 'TIMEOUT_ERROR',\n 'NETWORK_ERROR',\n 'RATE_LIMIT_ERROR',\n ],\n });\n }\n}\n","/**\n * Core types for Almadar integrations\n */\n\n/**\n * Configuration for an integration instance\n */\nexport interface IntegrationConfig {\n /** Integration name (matches registry) */\n name: string;\n\n /** Environment variables (API keys, secrets) */\n env: Record<string, string>;\n\n /** Optional logger */\n logger?: IntegrationLogger;\n\n /** Optional rate limiting config */\n rateLimit?: {\n requestsPerSecond: number;\n burstSize: number;\n };\n\n /** Optional timeout (ms) */\n timeout?: number;\n\n /** Optional retry config */\n retry?: {\n maxAttempts: number;\n backoffMs: number;\n maxBackoffMs?: number;\n };\n}\n\n/**\n * Result of an integration action call\n */\nexport interface IntegrationResult<T = unknown> {\n /** Success flag */\n success: boolean;\n\n /** Response data (on success) */\n data?: T;\n\n /** Error (on failure) */\n error?: IntegrationError;\n\n /** Metadata (timing, retries, etc.) */\n metadata: {\n integration: string;\n action: string;\n duration: number;\n retries: number;\n timestamp: number;\n };\n}\n\n/**\n * Integration error codes\n */\nexport type IntegrationErrorCode =\n | 'VALIDATION_ERROR'\n | 'AUTH_ERROR'\n | 'RATE_LIMIT_ERROR'\n | 'TIMEOUT_ERROR'\n | 'NETWORK_ERROR'\n | 'SERVICE_ERROR'\n | 'UNKNOWN_ERROR';\n\n/**\n * Integration error\n */\nexport class IntegrationError extends Error {\n code: IntegrationErrorCode;\n integration?: string;\n action?: string;\n details?: unknown;\n\n constructor(\n message: string,\n code: IntegrationErrorCode = 'UNKNOWN_ERROR',\n details?: unknown,\n ) {\n super(message);\n this.name = 'IntegrationError';\n this.code = code;\n this.details = details;\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n integration: this.integration,\n action: this.action,\n details: this.details,\n };\n }\n}\n\n/**\n * Logger interface\n */\nexport interface IntegrationLogger {\n debug(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n error(message: string, meta?: Record<string, unknown>): void;\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n/**\n * Validation error\n */\nexport interface ValidationError {\n param: string;\n message: string;\n}\n","import { BaseIntegration } from '../core/BaseIntegration';\nimport type { IntegrationConfig, IntegrationResult } from '../types';\nimport { IntegrationError } from '../types';\n\n/**\n * Mock integration for testing\n */\nexport class MockIntegration extends BaseIntegration {\n private responses: Map<string, unknown> = new Map();\n private calls: Array<{ action: string; params: Record<string, unknown> }> =\n [];\n\n constructor(config: IntegrationConfig) {\n super(config);\n }\n\n /**\n * Set mock response for an action\n */\n setResponse(action: string, data: unknown): void {\n this.responses.set(action, data);\n }\n\n /**\n * Get all calls made to this integration\n */\n getCalls(): Array<{ action: string; params: Record<string, unknown> }> {\n return this.calls;\n }\n\n /**\n * Clear all calls\n */\n clearCalls(): void {\n this.calls = [];\n }\n\n async execute(\n action: string,\n params: Record<string, unknown>,\n ): Promise<IntegrationResult> {\n // Record the call\n this.calls.push({ action, params });\n\n const data = this.responses.get(action);\n\n if (!data) {\n return {\n success: false,\n error: new IntegrationError(\n `No mock response for action: ${action}`,\n 'UNKNOWN_ERROR',\n ),\n metadata: this.createMetadata(action, 0),\n };\n }\n\n return {\n success: true,\n data,\n metadata: this.createMetadata(action, 0),\n };\n }\n}\n","import { IntegrationFactory } from '../factory';\nimport type { IntegrationResult } from '../types';\n\n/**\n * Create a callService effect handler for @almadar/runtime\n */\nexport function createCallServiceHandler(factory: IntegrationFactory) {\n return async (\n service: string,\n action: string,\n params: Record<string, unknown> | undefined,\n ): Promise<unknown> => {\n const result = await factory.execute(service, action, params || {});\n\n if (!result.success) {\n throw result.error;\n }\n\n return result.data;\n };\n}\n","import { createRequire } from 'node:module';\nimport { IntegrationFactory } from '../factory';\nimport { MockIntegration } from '../mocks/MockIntegration';\nimport { createCallServiceHandler } from './effectHandler';\nimport type { IntegrationResult } from '../types';\n\n/**\n * Generate mock data from a responseShape definition.\n * Maps type strings to realistic placeholder values.\n */\nfunction generateMockFromShape(shape: Record<string, string>): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (const [key, type] of Object.entries(shape)) {\n switch (type) {\n case 'string': data[key] = `mock_${key}`; break;\n case 'number': data[key] = 42; break;\n case 'boolean': data[key] = true; break;\n case 'object': data[key] = {}; break;\n case 'string[]': data[key] = []; break;\n default: data[key] = `mock_${key}`;\n }\n }\n return data;\n}\n\n/**\n * Runtime integration manager\n * Auto-configures integrations from environment variables.\n * When USE_MOCK_DATA=true, registers mock integrations for all services\n * using response shapes from services-registry.json.\n */\nexport class RuntimeIntegrationManager {\n private factory: IntegrationFactory;\n\n constructor() {\n this.factory = new IntegrationFactory();\n }\n\n /**\n * Configure from environment variables.\n * In mock mode (USE_MOCK_DATA=true), all services return realistic mock data.\n */\n configureFromEnv(): void {\n const env = process.env;\n\n if (env.USE_MOCK_DATA === 'true') {\n this.configureMockMode();\n return;\n }\n\n // Stripe\n if (env.STRIPE_SECRET_KEY) {\n this.factory.configure('stripe', {\n env: {\n STRIPE_SECRET_KEY: env.STRIPE_SECRET_KEY,\n },\n });\n }\n\n // YouTube\n if (env.YOUTUBE_API_KEY) {\n this.factory.configure('youtube', {\n env: {\n YOUTUBE_API_KEY: env.YOUTUBE_API_KEY,\n },\n });\n }\n\n // Twilio\n if (env.TWILIO_ACCOUNT_SID && env.TWILIO_AUTH_TOKEN) {\n this.factory.configure('twilio', {\n env: {\n TWILIO_ACCOUNT_SID: env.TWILIO_ACCOUNT_SID,\n TWILIO_AUTH_TOKEN: env.TWILIO_AUTH_TOKEN,\n TWILIO_PHONE_NUMBER: env.TWILIO_PHONE_NUMBER || '',\n },\n });\n }\n\n // Email (SendGrid)\n if (env.SENDGRID_API_KEY) {\n this.factory.configure('email', {\n env: {\n PROVIDER: 'sendgrid',\n SENDGRID_API_KEY: env.SENDGRID_API_KEY,\n FROM_EMAIL: env.FROM_EMAIL || 'noreply@example.com',\n },\n });\n }\n // Email (Resend)\n else if (env.RESEND_API_KEY) {\n this.factory.configure('email', {\n env: {\n PROVIDER: 'resend',\n RESEND_API_KEY: env.RESEND_API_KEY,\n FROM_EMAIL: env.FROM_EMAIL || 'noreply@example.com',\n },\n });\n }\n\n // LLM (Anthropic)\n if (env.ANTHROPIC_API_KEY) {\n this.factory.configure('llm', {\n env: {\n PROVIDER: 'anthropic',\n ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,\n },\n });\n }\n // LLM (OpenAI)\n else if (env.OPENAI_API_KEY) {\n this.factory.configure('llm', {\n env: {\n PROVIDER: 'openai',\n OPENAI_API_KEY: env.OPENAI_API_KEY,\n },\n });\n }\n\n // DeepAgent\n if (env.DEEPAGENT_API_URL) {\n this.factory.configure('deepagent', {\n env: {\n DEEPAGENT_API_URL: env.DEEPAGENT_API_URL,\n DEEPAGENT_API_KEY: env.DEEPAGENT_API_KEY || '',\n },\n });\n }\n\n // GitHub\n if (env.GITHUB_TOKEN) {\n this.factory.configure('github', {\n env: {\n GITHUB_TOKEN: env.GITHUB_TOKEN,\n GITHUB_OWNER: env.GITHUB_OWNER || '',\n GITHUB_REPO: env.GITHUB_REPO || '',\n GITHUB_WORK_DIR: env.GITHUB_WORK_DIR || '',\n },\n });\n }\n }\n\n /**\n * Configure mock mode: register MockIntegration for all known services\n * with auto-generated responses from the services registry.\n */\n private configureMockMode(): void {\n // Load registry and populate mocks\n const registry = this.loadServicesRegistry();\n\n for (const [serviceName, service] of Object.entries(registry)) {\n const mock = new MockIntegration({ name: serviceName, env: {} });\n\n for (const action of service.actions) {\n if (action.responseShape && Object.keys(action.responseShape).length > 0) {\n mock.setResponse(action.name, generateMockFromShape(action.responseShape));\n } else {\n // No responseShape defined: return generic success\n mock.setResponse(action.name, { success: true, _mock: true, _action: action.name });\n }\n }\n\n this.factory.configure(serviceName, { env: {} });\n // Inject mock instance directly into the factory\n (this.factory as unknown as { instances: Map<string, unknown> }).instances.set(serviceName, mock);\n }\n\n // Wrap factory.execute with a fallback for unknown services (e.g., custom-bearer-api).\n // Unknown services return an echo response with the input params.\n const originalExecute = this.factory.execute.bind(this.factory);\n this.factory.execute = async (\n integration: string,\n action: string,\n params: Record<string, unknown>,\n ): Promise<IntegrationResult> => {\n try {\n return await originalExecute(integration, action, params);\n } catch {\n // Unknown/unconfigured service in mock mode: echo params\n return {\n success: true,\n data: { ...params, _mock: true, _service: integration, _action: action },\n metadata: { integration, action, duration: 0, retries: 0, timestamp: Date.now() },\n };\n }\n };\n }\n\n /**\n * Load services registry from @almadar/patterns.\n * Returns a map of service name to { actions: [...] }.\n */\n private loadServicesRegistry(): Record<string, { actions: Array<{ name: string; responseShape: Record<string, string> }> }> {\n try {\n const esmRequire = createRequire(import.meta.url);\n const registry = esmRequire('@almadar/patterns/services-registry.json') as {\n services: Record<string, { actions: Array<{ name: string; responseShape: Record<string, string> }> }>;\n };\n return registry.services;\n } catch {\n // Registry not available (e.g., not installed). Return empty - fallback mock handles everything.\n return {};\n }\n }\n\n /**\n * Get effect handler for runtime\n */\n getCallServiceHandler() {\n return createCallServiceHandler(this.factory);\n }\n\n /**\n * Get factory (for advanced usage)\n */\n getFactory(): IntegrationFactory {\n return this.factory;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/integrations",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "External service integrations for Almadar applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -58,7 +58,7 @@
58
58
  "url": "https://github.com/almadar-io/almadar-integrations.git",
59
59
  "directory": "docs/packages/integrations"
60
60
  },
61
- "license": "MIT",
61
+ "license": "BSL-1.1",
62
62
  "keywords": [
63
63
  "almadar",
64
64
  "integrations",