intellitester 0.2.24 → 0.2.26

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.
Files changed (76) hide show
  1. package/README.md +18 -1
  2. package/dist/chunk-2BFRS6ZZ.js +59 -0
  3. package/dist/chunk-2BFRS6ZZ.js.map +1 -0
  4. package/dist/{chunk-QMYM2TCH.cjs → chunk-2IRHLFCW.cjs} +5 -5
  5. package/dist/{chunk-QMYM2TCH.cjs.map → chunk-2IRHLFCW.cjs.map} +1 -1
  6. package/dist/{chunk-ARJYJVRM.cjs → chunk-2ZSINOCK.cjs} +11 -8
  7. package/dist/chunk-2ZSINOCK.cjs.map +1 -0
  8. package/dist/chunk-64V2U2Y4.js +524 -0
  9. package/dist/chunk-64V2U2Y4.js.map +1 -0
  10. package/dist/chunk-B3ZQ425T.cjs +462 -0
  11. package/dist/chunk-B3ZQ425T.cjs.map +1 -0
  12. package/dist/{chunk-GFN6LIOF.cjs → chunk-CBPY7B6L.cjs} +613 -552
  13. package/dist/chunk-CBPY7B6L.cjs.map +1 -0
  14. package/dist/chunk-DPT2LVTT.cjs +550 -0
  15. package/dist/chunk-DPT2LVTT.cjs.map +1 -0
  16. package/dist/{chunk-HQOYFF54.js → chunk-EPN5OT5I.js} +604 -524
  17. package/dist/chunk-EPN5OT5I.js.map +1 -0
  18. package/dist/{chunk-DE5UFTTG.js → chunk-LIVAF432.js} +3 -3
  19. package/dist/{chunk-DE5UFTTG.js.map → chunk-LIVAF432.js.map} +1 -1
  20. package/dist/{chunk-ECBA4GJ3.js → chunk-O4H5QO5P.js} +8 -5
  21. package/dist/chunk-O4H5QO5P.js.map +1 -0
  22. package/dist/chunk-YNHXOSMZ.cjs +61 -0
  23. package/dist/chunk-YNHXOSMZ.cjs.map +1 -0
  24. package/dist/chunk-ZUOYPCED.js +459 -0
  25. package/dist/chunk-ZUOYPCED.js.map +1 -0
  26. package/dist/cli/index.cjs +98 -57
  27. package/dist/cli/index.cjs.map +1 -1
  28. package/dist/cli/index.js +55 -14
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/core/cleanup/index.cjs +11 -11
  31. package/dist/core/cleanup/index.d.cts +2 -2
  32. package/dist/core/cleanup/index.d.ts +2 -2
  33. package/dist/core/cleanup/index.js +3 -3
  34. package/dist/index.cjs +71 -69
  35. package/dist/index.d.cts +1186 -221
  36. package/dist/index.d.ts +1186 -221
  37. package/dist/index.js +6 -4
  38. package/dist/integration/index.cjs +7 -17
  39. package/dist/integration/index.cjs.map +1 -1
  40. package/dist/integration/index.d.cts +0 -14
  41. package/dist/integration/index.d.ts +0 -14
  42. package/dist/integration/index.js +1 -18
  43. package/dist/integration/index.js.map +1 -1
  44. package/dist/loader-6IZ4CERA.cjs +60 -0
  45. package/dist/loader-6IZ4CERA.cjs.map +1 -0
  46. package/dist/loader-JSTO36JJ.js +3 -0
  47. package/dist/loader-JSTO36JJ.js.map +1 -0
  48. package/dist/providers/appwrite/index.cjs +3 -3
  49. package/dist/providers/appwrite/index.d.cts +1 -1
  50. package/dist/providers/appwrite/index.d.ts +1 -1
  51. package/dist/providers/appwrite/index.js +1 -1
  52. package/dist/providers/index.cjs +8 -8
  53. package/dist/providers/index.d.cts +1 -1
  54. package/dist/providers/index.d.ts +1 -1
  55. package/dist/providers/index.js +2 -2
  56. package/dist/providers/mysql/index.d.cts +1 -1
  57. package/dist/providers/mysql/index.d.ts +1 -1
  58. package/dist/providers/postgres/index.d.cts +1 -1
  59. package/dist/providers/postgres/index.d.ts +1 -1
  60. package/dist/providers/sqlite/index.d.cts +1 -1
  61. package/dist/providers/sqlite/index.d.ts +1 -1
  62. package/dist/{types-l-ZaFKC-.d.ts → types-BJ8oJgr1.d.ts} +3 -0
  63. package/dist/{types-LONNVTIF.d.cts → types-D6s-QFkg.d.cts} +3 -0
  64. package/package.json +1 -1
  65. package/schemas/intellitester.config.schema.json +5 -1
  66. package/schemas/pipeline.schema.json +5 -1
  67. package/schemas/test.schema.json +351 -1
  68. package/schemas/workflow.schema.json +5 -1
  69. package/dist/chunk-4B54JUOP.js +0 -234
  70. package/dist/chunk-4B54JUOP.js.map +0 -1
  71. package/dist/chunk-ARJYJVRM.cjs.map +0 -1
  72. package/dist/chunk-ECBA4GJ3.js.map +0 -1
  73. package/dist/chunk-GFN6LIOF.cjs.map +0 -1
  74. package/dist/chunk-HQOYFF54.js.map +0 -1
  75. package/dist/chunk-OFXNJXMV.cjs +0 -237
  76. package/dist/chunk-OFXNJXMV.cjs.map +0 -1
package/README.md CHANGED
@@ -197,4 +197,21 @@ await track({
197
197
  });
198
198
  ```
199
199
 
200
- The `track()` function is production-safe - it's a no-op if the required environment variables aren't set. IntelliTester sets these automatically during test execution.
200
+ The `track()` function is production-safe - it's a no-op if the required environment variables aren't set. IntelliTester sets these automatically during test execution.
201
+
202
+ ### File-Based Tracking (Fallback)
203
+
204
+ IntelliTester can persist tracked resources to disk in addition to (or instead of) the in-memory tracking server. This helps recover from interrupted runs and enables cleanup even if the tracking server is unavailable.
205
+
206
+ By default, the executor sets:
207
+
208
+ - `INTELLITESTER_TRACK_FILE` to a JSONL file in `.intellitester/track/TEST_SESSION_<id>.jsonl`
209
+ - `.intellitester/track/ACTIVE_TESTS.json` for heartbeats and stale session pruning
210
+
211
+ You can override the session ID or tracking directory:
212
+
213
+ ```bash
214
+ intellitester run --session-id my-session --track-dir .intellitester/track
215
+ ```
216
+
217
+ If `INTELLITESTER_TRACK_URL` is set, `track()` will send HTTP requests and also append to the track file (when available). If only the file is set, `track()` writes locally.
@@ -0,0 +1,59 @@
1
+ // src/integration/index.ts
2
+ var cachedTracking = null;
3
+ var resolveTracking = () => {
4
+ const sessionId = process.env.INTELLITESTER_SESSION_ID;
5
+ const trackUrl = process.env.INTELLITESTER_TRACK_URL;
6
+ const trackFile = process.env.INTELLITESTER_TRACK_FILE;
7
+ if (cachedTracking && cachedTracking.sessionId === sessionId && cachedTracking.trackUrl === trackUrl && cachedTracking.trackFile === trackFile) {
8
+ return cachedTracking;
9
+ }
10
+ let mode = "none";
11
+ if (trackUrl && trackFile) {
12
+ mode = "both";
13
+ } else if (trackUrl) {
14
+ mode = "http";
15
+ } else if (trackFile) {
16
+ mode = "file";
17
+ }
18
+ cachedTracking = { sessionId, trackUrl, trackFile, mode };
19
+ return cachedTracking;
20
+ };
21
+ async function track(resource) {
22
+ if (typeof window !== "undefined") return;
23
+ if (typeof process === "undefined") return;
24
+ const { sessionId, trackUrl, trackFile, mode } = resolveTracking();
25
+ if (!sessionId || mode === "none") return;
26
+ if (trackUrl && (mode === "http" || mode === "both")) {
27
+ try {
28
+ const controller = new AbortController();
29
+ const timeoutId = setTimeout(() => controller.abort(), 1e3);
30
+ await fetch(`${trackUrl}/track`, {
31
+ method: "POST",
32
+ headers: { "Content-Type": "application/json" },
33
+ body: JSON.stringify({ sessionId, ...resource }),
34
+ signal: controller.signal
35
+ });
36
+ clearTimeout(timeoutId);
37
+ } catch {
38
+ }
39
+ }
40
+ if (trackFile && (mode === "file" || mode === "both")) {
41
+ try {
42
+ const { appendFile } = await import('fs/promises');
43
+ const { existsSync } = await import('fs');
44
+ if (!existsSync(trackFile)) return;
45
+ const payload = {
46
+ sessionId,
47
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
48
+ ...resource
49
+ };
50
+ await appendFile(trackFile, `${JSON.stringify(payload)}
51
+ `, "utf8");
52
+ } catch {
53
+ }
54
+ }
55
+ }
56
+
57
+ export { track };
58
+ //# sourceMappingURL=chunk-2BFRS6ZZ.js.map
59
+ //# sourceMappingURL=chunk-2BFRS6ZZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/integration/index.ts"],"names":[],"mappings":";AA2CA,IAAI,cAAA,GAKO,IAAA;AAEX,IAAM,kBAAkB,MAKnB;AACH,EAAA,MAAM,SAAA,GAAY,QAAQ,GAAA,CAAI,wBAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,uBAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,QAAQ,GAAA,CAAI,wBAAA;AAE9B,EAAA,IACE,cAAA,IACA,eAAe,SAAA,KAAc,SAAA,IAC7B,eAAe,QAAA,KAAa,QAAA,IAC5B,cAAA,CAAe,SAAA,KAAc,SAAA,EAC7B;AACA,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,GAAqB,MAAA;AACzB,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,IAAA,GAAO,MAAA;AAAA,EACT,WAAW,QAAA,EAAU;AACnB,IAAA,IAAA,GAAO,MAAA;AAAA,EACT,WAAW,SAAA,EAAW;AACpB,IAAA,IAAA,GAAO,MAAA;AAAA,EACT;AAEA,EAAA,cAAA,GAAiB,EAAE,SAAA,EAAW,QAAA,EAAU,SAAA,EAAW,IAAA,EAAK;AACxD,EAAA,OAAO,cAAA;AACT,CAAA;AAEA,eAAsB,MAAM,QAAA,EAA0C;AAEpE,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,IAAI,OAAO,YAAY,WAAA,EAAa;AAEpC,EAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAU,SAAA,EAAW,IAAA,KAAS,eAAA,EAAgB;AAEjE,EAAA,IAAI,CAAC,SAAA,IAAa,IAAA,KAAS,MAAA,EAAQ;AAEnC,EAAA,IAAI,QAAA,KAAa,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,MAAA,CAAA,EAAS;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,MAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,GAAI,CAAA;AAC3D,MAAA,MAAM,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA,MAAA,CAAA,EAAU;AAAA,QAC/B,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,UAAU,CAAA;AAAA,QAC/C,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,IAAI,SAAA,KAAc,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,MAAA,CAAA,EAAS;AACrD,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAM,OAAO,aAAkB,CAAA;AACtD,MAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAM,OAAO,IAAS,CAAA;AAC7C,MAAA,IAAI,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AAC5B,MAAA,MAAM,OAAA,GAAU;AAAA,QACd,SAAA;AAAA,QACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAClC,GAAG;AAAA,OACL;AACA,MAAA,MAAM,WAAW,SAAA,EAAW,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC;AAAA,CAAA,EAAM,MAAM,CAAA;AAAA,IACpE,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF","file":"chunk-2BFRS6ZZ.js","sourcesContent":["/**\n * IntelliTester Integration - Track server-side resources for test cleanup\n *\n * Usage in app SSR code:\n * import { track } from 'intellitester/integration';\n *\n * // Track a database row\n * await track({ type: 'row', id: row.$id, database: 'main', table: 'users' });\n *\n * // Track a team\n * await track({ type: 'team', id: team.$id });\n *\n * // Track anything - it's just metadata for your cleanup handler\n * await track({ type: 'stripe_customer', id: customerId });\n */\n\n/**\n * Track a resource for cleanup after tests.\n * Provider-agnostic - just tracks type, id, and metadata.\n * Cleanup logic is handled by the configured provider.\n */\nexport interface TrackedResource {\n type: string; // 'row', 'team', 'file', 'user', or any custom type\n id: string; // Resource ID\n [key: string]: unknown; // Any additional metadata needed for cleanup\n}\n\n/**\n * Track a resource created in server-side code.\n * No-op if not in test mode.\n *\n * @example\n * // Track a database row\n * await track({ type: 'row', id: row.$id, database: 'main', table: 'users' });\n *\n * // Track a team\n * await track({ type: 'team', id: team.$id });\n *\n * // Track anything - it's just metadata for your cleanup handler\n * await track({ type: 'stripe_customer', id: customerId });\n */\ntype TrackingMode = 'none' | 'http' | 'file' | 'both';\n\nlet cachedTracking: {\n sessionId?: string;\n trackUrl?: string;\n trackFile?: string;\n mode: TrackingMode;\n} | null = null;\n\nconst resolveTracking = (): {\n sessionId?: string;\n trackUrl?: string;\n trackFile?: string;\n mode: TrackingMode;\n} => {\n const sessionId = process.env.INTELLITESTER_SESSION_ID;\n const trackUrl = process.env.INTELLITESTER_TRACK_URL;\n const trackFile = process.env.INTELLITESTER_TRACK_FILE;\n\n if (\n cachedTracking &&\n cachedTracking.sessionId === sessionId &&\n cachedTracking.trackUrl === trackUrl &&\n cachedTracking.trackFile === trackFile\n ) {\n return cachedTracking;\n }\n\n let mode: TrackingMode = 'none';\n if (trackUrl && trackFile) {\n mode = 'both';\n } else if (trackUrl) {\n mode = 'http';\n } else if (trackFile) {\n mode = 'file';\n }\n\n cachedTracking = { sessionId, trackUrl, trackFile, mode };\n return cachedTracking;\n};\n\nexport async function track(resource: TrackedResource): Promise<void> {\n // Only run on server (SSR), not in browser\n if (typeof window !== 'undefined') return;\n if (typeof process === 'undefined') return;\n\n const { sessionId, trackUrl, trackFile, mode } = resolveTracking();\n\n if (!sessionId || mode === 'none') return;\n\n if (trackUrl && (mode === 'http' || mode === 'both')) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 1000);\n await fetch(`${trackUrl}/track`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...resource }),\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n } catch {\n // Silent fail - don't break app\n }\n }\n\n if (trackFile && (mode === 'file' || mode === 'both')) {\n try {\n const { appendFile } = await import('node:fs/promises');\n const { existsSync } = await import('node:fs');\n if (!existsSync(trackFile)) return;\n const payload = {\n sessionId,\n createdAt: new Date().toISOString(),\n ...resource,\n };\n await appendFile(trackFile, `${JSON.stringify(payload)}\\n`, 'utf8');\n } catch {\n // Silent fail - don't break app\n }\n }\n}\n"]}
@@ -1,19 +1,19 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkPAKODOH4_cjs = require('./chunk-PAKODOH4.cjs');
4
- var chunkOFXNJXMV_cjs = require('./chunk-OFXNJXMV.cjs');
4
+ var chunkB3ZQ425T_cjs = require('./chunk-B3ZQ425T.cjs');
5
5
  var chunkUUJXCHVT_cjs = require('./chunk-UUJXCHVT.cjs');
6
6
  var chunk35WJGNDA_cjs = require('./chunk-35WJGNDA.cjs');
7
7
 
8
8
  // src/providers/index.ts
9
9
  var providerFactories = {
10
- appwrite: (config) => chunkOFXNJXMV_cjs.createAppwriteProvider(config),
10
+ appwrite: (config) => chunkB3ZQ425T_cjs.createAppwriteProvider(config),
11
11
  postgres: (config) => chunkUUJXCHVT_cjs.createPostgresProvider(config),
12
12
  mysql: (config) => chunk35WJGNDA_cjs.createMysqlProvider(config),
13
13
  sqlite: (config) => chunkPAKODOH4_cjs.createSqliteProvider(config)
14
14
  };
15
15
  var typeMappingsRegistry = {
16
- appwrite: chunkOFXNJXMV_cjs.appwriteTypeMappings,
16
+ appwrite: chunkB3ZQ425T_cjs.appwriteTypeMappings,
17
17
  postgres: chunkUUJXCHVT_cjs.postgresTypeMappings,
18
18
  mysql: chunk35WJGNDA_cjs.mysqlTypeMappings,
19
19
  sqlite: chunkPAKODOH4_cjs.sqliteTypeMappings
@@ -32,5 +32,5 @@ exports.getDefaultTypeMappings = getDefaultTypeMappings;
32
32
  exports.isProviderAvailable = isProviderAvailable;
33
33
  exports.listAvailableProviders = listAvailableProviders;
34
34
  exports.providerFactories = providerFactories;
35
- //# sourceMappingURL=chunk-QMYM2TCH.cjs.map
36
- //# sourceMappingURL=chunk-QMYM2TCH.cjs.map
35
+ //# sourceMappingURL=chunk-2IRHLFCW.cjs.map
36
+ //# sourceMappingURL=chunk-2IRHLFCW.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/index.ts"],"names":["createAppwriteProvider","createPostgresProvider","createMysqlProvider","createSqliteProvider","appwriteTypeMappings","postgresTypeMappings","mysqlTypeMappings","sqliteTypeMappings"],"mappings":";;;;;;;;AAaO,IAAM,iBAAA,GAAsE;AAAA,EACjF,QAAA,EAAU,CAAC,MAAA,KAAWA,wCAAA,CAAuB,MAAM,CAAA;AAAA,EACnD,QAAA,EAAU,CAAC,MAAA,KAAWC,wCAAA,CAAuB,MAAM,CAAA;AAAA,EACnD,KAAA,EAAO,CAAC,MAAA,KAAWC,qCAAA,CAAoB,MAAM,CAAA;AAAA,EAC7C,MAAA,EAAQ,CAAC,MAAA,KAAWC,sCAAA,CAAqB,MAAM;AACjD;AAGA,IAAM,oBAAA,GAA+D;AAAA,EACnE,QAAA,EAAUC,sCAAA;AAAA,EACV,QAAA,EAAUC,sCAAA;AAAA,EACV,KAAA,EAAOC,mCAAA;AAAA,EACP,MAAA,EAAQC;AACV,CAAA;AAGO,SAAS,uBAAuB,QAAA,EAA0C;AAC/E,EAAA,OAAO,oBAAA,CAAqB,QAAQ,CAAA,IAAK,EAAC;AAC5C;AAGO,SAAS,oBAAoB,QAAA,EAA2B;AAC7D,EAAA,OAAO,QAAA,IAAY,iBAAA;AACrB;AAGO,SAAS,sBAAA,GAAmC;AACjD,EAAA,OAAO,MAAA,CAAO,KAAK,iBAAiB,CAAA;AACtC","file":"chunk-QMYM2TCH.cjs","sourcesContent":["import { createAppwriteProvider, appwriteTypeMappings } from './appwrite/index.js';\nimport { createPostgresProvider, postgresTypeMappings } from './postgres/index.js';\nimport { createMysqlProvider, mysqlTypeMappings } from './mysql/index.js';\nimport { createSqliteProvider, sqliteTypeMappings } from './sqlite/index.js';\nimport type { CleanupProvider } from '../core/cleanup/types.js';\n\n// Re-export for convenience\nexport { createAppwriteProvider, appwriteTypeMappings } from './appwrite/index.js';\nexport { createPostgresProvider, postgresTypeMappings } from './postgres/index.js';\nexport { createMysqlProvider, mysqlTypeMappings } from './mysql/index.js';\nexport { createSqliteProvider, sqliteTypeMappings } from './sqlite/index.js';\n\n// Provider factory registry using static imports\nexport const providerFactories: Record<string, (config: any) => CleanupProvider> = {\n appwrite: (config) => createAppwriteProvider(config),\n postgres: (config) => createPostgresProvider(config),\n mysql: (config) => createMysqlProvider(config),\n sqlite: (config) => createSqliteProvider(config),\n};\n\n// Default type mappings for each provider\nconst typeMappingsRegistry: Record<string, Record<string, string>> = {\n appwrite: appwriteTypeMappings,\n postgres: postgresTypeMappings,\n mysql: mysqlTypeMappings,\n sqlite: sqliteTypeMappings,\n};\n\n// Get default type mappings for a provider\nexport function getDefaultTypeMappings(provider: string): Record<string, string> {\n return typeMappingsRegistry[provider] ?? {};\n}\n\n// Helper to check if a provider is available\nexport function isProviderAvailable(provider: string): boolean {\n return provider in providerFactories;\n}\n\n// Helper to list all available providers\nexport function listAvailableProviders(): string[] {\n return Object.keys(providerFactories);\n}\n"]}
1
+ {"version":3,"sources":["../src/providers/index.ts"],"names":["createAppwriteProvider","createPostgresProvider","createMysqlProvider","createSqliteProvider","appwriteTypeMappings","postgresTypeMappings","mysqlTypeMappings","sqliteTypeMappings"],"mappings":";;;;;;;;AAaO,IAAM,iBAAA,GAAsE;AAAA,EACjF,QAAA,EAAU,CAAC,MAAA,KAAWA,wCAAA,CAAuB,MAAM,CAAA;AAAA,EACnD,QAAA,EAAU,CAAC,MAAA,KAAWC,wCAAA,CAAuB,MAAM,CAAA;AAAA,EACnD,KAAA,EAAO,CAAC,MAAA,KAAWC,qCAAA,CAAoB,MAAM,CAAA;AAAA,EAC7C,MAAA,EAAQ,CAAC,MAAA,KAAWC,sCAAA,CAAqB,MAAM;AACjD;AAGA,IAAM,oBAAA,GAA+D;AAAA,EACnE,QAAA,EAAUC,sCAAA;AAAA,EACV,QAAA,EAAUC,sCAAA;AAAA,EACV,KAAA,EAAOC,mCAAA;AAAA,EACP,MAAA,EAAQC;AACV,CAAA;AAGO,SAAS,uBAAuB,QAAA,EAA0C;AAC/E,EAAA,OAAO,oBAAA,CAAqB,QAAQ,CAAA,IAAK,EAAC;AAC5C;AAGO,SAAS,oBAAoB,QAAA,EAA2B;AAC7D,EAAA,OAAO,QAAA,IAAY,iBAAA;AACrB;AAGO,SAAS,sBAAA,GAAmC;AACjD,EAAA,OAAO,MAAA,CAAO,KAAK,iBAAiB,CAAA;AACtC","file":"chunk-2IRHLFCW.cjs","sourcesContent":["import { createAppwriteProvider, appwriteTypeMappings } from './appwrite/index.js';\nimport { createPostgresProvider, postgresTypeMappings } from './postgres/index.js';\nimport { createMysqlProvider, mysqlTypeMappings } from './mysql/index.js';\nimport { createSqliteProvider, sqliteTypeMappings } from './sqlite/index.js';\nimport type { CleanupProvider } from '../core/cleanup/types.js';\n\n// Re-export for convenience\nexport { createAppwriteProvider, appwriteTypeMappings } from './appwrite/index.js';\nexport { createPostgresProvider, postgresTypeMappings } from './postgres/index.js';\nexport { createMysqlProvider, mysqlTypeMappings } from './mysql/index.js';\nexport { createSqliteProvider, sqliteTypeMappings } from './sqlite/index.js';\n\n// Provider factory registry using static imports\nexport const providerFactories: Record<string, (config: any) => CleanupProvider> = {\n appwrite: (config) => createAppwriteProvider(config),\n postgres: (config) => createPostgresProvider(config),\n mysql: (config) => createMysqlProvider(config),\n sqlite: (config) => createSqliteProvider(config),\n};\n\n// Default type mappings for each provider\nconst typeMappingsRegistry: Record<string, Record<string, string>> = {\n appwrite: appwriteTypeMappings,\n postgres: postgresTypeMappings,\n mysql: mysqlTypeMappings,\n sqlite: sqliteTypeMappings,\n};\n\n// Get default type mappings for a provider\nexport function getDefaultTypeMappings(provider: string): Record<string, string> {\n return typeMappingsRegistry[provider] ?? {};\n}\n\n// Helper to check if a provider is available\nexport function isProviderAvailable(provider: string): boolean {\n return provider in providerFactories;\n}\n\n// Helper to list all available providers\nexport function listAvailableProviders(): string[] {\n return Object.keys(providerFactories);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkQMYM2TCH_cjs = require('./chunk-QMYM2TCH.cjs');
3
+ var chunk2IRHLFCW_cjs = require('./chunk-2IRHLFCW.cjs');
4
4
  var glob = require('glob');
5
5
  var path = require('path');
6
6
  var fs = require('fs');
@@ -21,16 +21,16 @@ async function loadCleanupHandlers(config, cwd = process.cwd()) {
21
21
  if (!providerConfig) {
22
22
  throw new Error(`Provider "${config.provider}" specified but no configuration found`);
23
23
  }
24
- const factory = chunkQMYM2TCH_cjs.providerFactories[config.provider];
24
+ const factory = chunk2IRHLFCW_cjs.providerFactories[config.provider];
25
25
  if (!factory) {
26
- throw new Error(`Unknown provider: ${config.provider}. Available: ${Object.keys(chunkQMYM2TCH_cjs.providerFactories).join(", ")}`);
26
+ throw new Error(`Unknown provider: ${config.provider}. Available: ${Object.keys(chunk2IRHLFCW_cjs.providerFactories).join(", ")}`);
27
27
  }
28
28
  provider = factory(providerConfig);
29
29
  await provider.configure(providerConfig);
30
30
  for (const [methodName, handler] of Object.entries(provider.methods)) {
31
31
  handlers.set(`${provider.name}.${methodName}`, handler);
32
32
  }
33
- typeMappings = { ...chunkQMYM2TCH_cjs.getDefaultTypeMappings(config.provider) };
33
+ typeMappings = { ...chunk2IRHLFCW_cjs.getDefaultTypeMappings(config.provider) };
34
34
  }
35
35
  const rootCleanupPath = path__default.default.join(cwd, "intellitester.cleanup.ts");
36
36
  const rootHandlers = await tryLoadHandlerFile(rootCleanupPath);
@@ -226,7 +226,9 @@ async function executeCleanup(resources, handlers, typeMappings, options = {}) {
226
226
  try {
227
227
  const untrackedResult = await provider.cleanupUntracked({
228
228
  testStartTime: options.testStartTime ?? (/* @__PURE__ */ new Date()).toISOString(),
229
+ testStartTimeProvided: options.testStartTime !== void 0,
229
230
  userId: options.userId,
231
+ userEmail: options.userEmail,
230
232
  sessionId: options.sessionId
231
233
  });
232
234
  if (untrackedResult.deleted.length > 0) {
@@ -247,15 +249,16 @@ async function executeCleanup(resources, handlers, typeMappings, options = {}) {
247
249
  deleted,
248
250
  failed
249
251
  };
250
- if (failed.length > 0 && options.sessionId && options.providerConfig) {
252
+ if (failed.length > 0 && options.providerConfig) {
251
253
  try {
254
+ const persistenceId = options.sessionId ?? options.userId ?? options.userEmail ?? `cleanup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
252
255
  const failedResources = sorted.filter((resource) => {
253
256
  const resourceLabel = `${resource.type}:${resource.id}`;
254
257
  return failed.some((f) => f.startsWith(resourceLabel));
255
258
  });
256
259
  await saveFailedCleanup(
257
260
  {
258
- sessionId: options.sessionId,
261
+ sessionId: persistenceId,
259
262
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
260
263
  resources: failedResources,
261
264
  providerConfig: options.providerConfig,
@@ -298,5 +301,5 @@ exports.loadFailedCleanups = loadFailedCleanups;
298
301
  exports.removeFailedCleanup = removeFailedCleanup;
299
302
  exports.resolveHandler = resolveHandler;
300
303
  exports.saveFailedCleanup = saveFailedCleanup;
301
- //# sourceMappingURL=chunk-ARJYJVRM.cjs.map
302
- //# sourceMappingURL=chunk-ARJYJVRM.cjs.map
304
+ //# sourceMappingURL=chunk-2ZSINOCK.cjs.map
305
+ //# sourceMappingURL=chunk-2ZSINOCK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/cleanup/loader.ts","../src/core/cleanup/persistence.ts","../src/core/cleanup/executor.ts","../src/core/cleanup/index.ts"],"names":["providerFactories","getDefaultTypeMappings","path","glob","fs","result"],"mappings":"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","file":"chunk-2ZSINOCK.cjs","sourcesContent":["import { glob } from 'glob';\nimport path from 'path';\nimport fs from 'fs';\nimport type { CleanupHandler, CleanupConfig, CleanupProvider } from './types.js';\nimport { providerFactories, getDefaultTypeMappings } from '../../providers/index.js';\n\n/**\n * Load all cleanup handlers based on configuration\n *\n * Loading order (later overrides earlier):\n * 1. Built-in provider methods\n * 2. intellitester.cleanup.ts at project root\n * 3. Discovery paths (default: tests/cleanup/**\\/*.ts)\n * 4. Explicit handler files from config\n *\n * @param config - Cleanup configuration object\n * @param cwd - Current working directory (defaults to process.cwd())\n *\n * @example\n * ```typescript\n * // Basic usage with a provider\n * const { handlers, typeMappings } = await loadCleanupHandlers({\n * provider: 'sqlite',\n * sqlite: { database: './test.db' },\n * types: {\n * user: 'sqlite.deleteUser',\n * team: 'sqlite.deleteRow'\n * }\n * });\n *\n * // With custom discovery paths\n * const { handlers, typeMappings } = await loadCleanupHandlers({\n * provider: 'postgres',\n * postgres: { connectionString: 'postgresql://...' },\n * discover: {\n * enabled: true,\n * paths: ['./tests/cleanup', './e2e/cleanup'],\n * pattern: '**\\/*.cleanup.ts'\n * },\n * handlers: ['./custom-cleanup.ts']\n * });\n * ```\n *\n * @returns Object containing loaded handlers map and type mappings\n */\nexport async function loadCleanupHandlers(\n config: CleanupConfig,\n cwd: string = process.cwd()\n): Promise<{\n handlers: Map<string, CleanupHandler>;\n typeMappings: Record<string, string>;\n provider?: CleanupProvider;\n}> {\n const handlers = new Map<string, CleanupHandler>();\n let typeMappings: Record<string, string> = {};\n let provider: CleanupProvider | undefined;\n\n // 1. Load built-in provider methods\n if (config.provider) {\n const providerConfig = config[config.provider] as Record<string, unknown> | undefined;\n if (!providerConfig) {\n throw new Error(`Provider \"${config.provider}\" specified but no configuration found`);\n }\n\n const factory = providerFactories[config.provider];\n if (!factory) {\n throw new Error(`Unknown provider: ${config.provider}. Available: ${Object.keys(providerFactories).join(', ')}`);\n }\n\n provider = factory(providerConfig);\n await provider.configure(providerConfig);\n\n // Register provider methods\n for (const [methodName, handler] of Object.entries(provider.methods)) {\n handlers.set(`${provider.name}.${methodName}`, handler);\n }\n\n // Get default type mappings for this provider\n typeMappings = { ...getDefaultTypeMappings(config.provider) };\n }\n\n // 2. Auto-discover intellitester.cleanup.ts at root\n const rootCleanupPath = path.join(cwd, 'intellitester.cleanup.ts');\n const rootHandlers = await tryLoadHandlerFile(rootCleanupPath);\n if (rootHandlers) {\n mergeHandlers(handlers, rootHandlers);\n }\n\n // 3. Auto-discover from discovery paths\n if (config.discover?.enabled !== false) {\n const discoveryPaths = config.discover?.paths ?? ['./tests/cleanup'];\n const pattern = config.discover?.pattern ?? '**/*.ts';\n\n for (const basePath of discoveryPaths) {\n const absoluteBase = path.isAbsolute(basePath) ? basePath : path.join(cwd, basePath);\n\n try {\n const files = await glob(pattern, {\n cwd: absoluteBase,\n absolute: true,\n ignore: ['**/*.d.ts', '**/node_modules/**']\n });\n\n for (const file of files) {\n const fileHandlers = await tryLoadHandlerFile(file);\n if (fileHandlers) {\n mergeHandlers(handlers, fileHandlers);\n }\n }\n } catch {\n // Directory doesn't exist or no matches - that's fine\n }\n }\n }\n\n // 4. Load explicit handler files\n for (const handlerPath of config.handlers ?? []) {\n const absolutePath = path.isAbsolute(handlerPath)\n ? handlerPath\n : path.join(cwd, handlerPath);\n\n const fileHandlers = await tryLoadHandlerFile(absolutePath);\n if (fileHandlers) {\n mergeHandlers(handlers, fileHandlers);\n } else {\n console.warn(`Warning: Could not load cleanup handler file: ${handlerPath}`);\n }\n }\n\n // Merge config.types over default mappings\n if (config.types) {\n typeMappings = { ...typeMappings, ...config.types };\n }\n\n return { handlers, typeMappings, provider };\n}\n\n/**\n * Try to load a handler file, returning null if it doesn't exist or fails\n */\nasync function tryLoadHandlerFile(filePath: string): Promise<Record<string, CleanupHandler> | null> {\n try {\n // Check if file exists\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n // For TypeScript files, we need to handle them appropriately\n // In a built environment, look for the .js equivalent\n let loadPath = filePath;\n if (filePath.endsWith('.ts')) {\n // In production, TypeScript files will be compiled to .js\n // Try to load the compiled .js version from dist if running compiled\n const jsPath = filePath.replace(/\\.ts$/, '.js');\n if (fs.existsSync(jsPath)) {\n loadPath = jsPath;\n } else {\n // Running in development with tsx/ts-node\n // Try direct import which works with these tools\n loadPath = filePath;\n }\n }\n\n // Use dynamic import with cache busting for fresh load\n const module = await import(`${loadPath}?t=${Date.now()}`);\n\n // Handle default export or named exports\n if (module.default && typeof module.default === 'object') {\n return module.default as Record<string, CleanupHandler>;\n }\n\n // Filter to only include function exports\n const handlers: Record<string, CleanupHandler> = {};\n for (const [key, value] of Object.entries(module)) {\n if (typeof value === 'function' && key !== 'default') {\n handlers[key] = value as CleanupHandler;\n }\n }\n\n return Object.keys(handlers).length > 0 ? handlers : null;\n } catch {\n // File doesn't exist or failed to load\n return null;\n }\n}\n\n/**\n * Merge handlers from a file into the main handlers map\n */\nfunction mergeHandlers(\n target: Map<string, CleanupHandler>,\n source: Record<string, CleanupHandler>\n): void {\n for (const [key, handler] of Object.entries(source)) {\n target.set(key, handler);\n }\n}\n\n/**\n * Get a handler by key, checking both direct keys and provider.method format\n */\nexport function resolveHandler(\n handlers: Map<string, CleanupHandler>,\n typeMappings: Record<string, string>,\n resourceType: string\n): CleanupHandler | null {\n // First check type mappings\n const mappedKey = typeMappings[resourceType];\n if (mappedKey && handlers.has(mappedKey)) {\n return handlers.get(mappedKey)!;\n }\n\n // Then check for direct handler\n if (handlers.has(resourceType)) {\n return handlers.get(resourceType)!;\n }\n\n return null;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { TrackedResource } from '../../integration/index.js';\n\n// Types\nexport interface FailedCleanup {\n sessionId: string;\n timestamp: string;\n resources: TrackedResource[];\n // Generic provider config (no secrets!)\n providerConfig: {\n provider: string; // 'appwrite' | 'postgres' | 'mysql' | 'sqlite'\n [key: string]: unknown; // endpoint, projectId, database, etc. - NO passwords/keys\n };\n errors: string[];\n}\n\nconst CLEANUP_DIR = '.intellitester/cleanup/failed';\n\n// Save failed cleanup to disk\nexport async function saveFailedCleanup(\n cleanup: FailedCleanup,\n cwd: string = process.cwd()\n): Promise<void> {\n const dir = path.join(cwd, CLEANUP_DIR);\n await fs.mkdir(dir, { recursive: true });\n const filePath = path.join(dir, `${cleanup.sessionId}.json`);\n await fs.writeFile(filePath, JSON.stringify(cleanup, null, 2), 'utf8');\n console.log(`Saved failed cleanup to ${filePath}`);\n}\n\n// Load all failed cleanups from disk\nexport async function loadFailedCleanups(\n cwd: string = process.cwd()\n): Promise<FailedCleanup[]> {\n const dir = path.join(cwd, CLEANUP_DIR);\n try {\n const files = await fs.readdir(dir);\n const cleanups: FailedCleanup[] = [];\n for (const file of files) {\n if (file.endsWith('.json')) {\n const content = await fs.readFile(path.join(dir, file), 'utf8');\n cleanups.push(JSON.parse(content));\n }\n }\n return cleanups;\n } catch (error) {\n // Directory doesn't exist = no failed cleanups\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n}\n\n// Remove a failed cleanup file after successful retry\nexport async function removeFailedCleanup(\n sessionId: string,\n cwd: string = process.cwd()\n): Promise<void> {\n const filePath = path.join(cwd, CLEANUP_DIR, `${sessionId}.json`);\n try {\n await fs.unlink(filePath);\n console.log(`Removed failed cleanup file: ${sessionId}.json`);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n","import type { TrackedResource } from '../../integration/index.js';\nimport type { CleanupHandler, CleanupResult, ExecutorOptions, CleanupConfig, CleanupProvider } from './types.js';\nimport { resolveHandler } from './loader.js';\nimport { saveFailedCleanup } from './persistence.js';\n\nconst sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\n\n/**\n * Extended options for cleanup execution including provider and config\n */\nexport interface ExtendedCleanupOptions extends ExecutorOptions {\n config?: CleanupConfig;\n provider?: CleanupProvider;\n}\n\n/**\n * Execute cleanup for all tracked resources\n *\n * @param resources - Array of tracked resources to clean up\n * @param handlers - Map of handler names to cleanup functions\n * @param typeMappings - Map of resource types to handler names\n * @param options - Executor options (parallel, retries, config, provider)\n */\nexport async function executeCleanup(\n resources: TrackedResource[],\n handlers: Map<string, CleanupHandler>,\n typeMappings: Record<string, string>,\n options: ExtendedCleanupOptions = {}\n): Promise<CleanupResult> {\n const { parallel = false, retries = 3, config, provider } = options;\n const deleted: string[] = [];\n const failed: string[] = [];\n\n // Sort by creation time (reverse) - delete newest first (LIFO)\n const sorted = [...resources].sort((a, b) => {\n // Handle optional createdAt field (present at runtime from tracking server)\n const aCreatedAt = 'createdAt' in a ? (a.createdAt as string | undefined) : undefined;\n const bCreatedAt = 'createdAt' in b ? (b.createdAt as string | undefined) : undefined;\n\n const timeA = aCreatedAt ? new Date(aCreatedAt).getTime() : 0;\n const timeB = bCreatedAt ? new Date(bCreatedAt).getTime() : 0;\n\n return timeB - timeA;\n });\n\n const deleteResource = async (resource: TrackedResource): Promise<boolean> => {\n const resourceLabel = `${resource.type}:${resource.id}`;\n\n // Skip already deleted resources (deleted field may be set dynamically)\n const isDeleted = 'deleted' in resource ? (resource.deleted as boolean | undefined) : false;\n if (isDeleted) {\n deleted.push(`${resourceLabel} (already deleted)`);\n return true;\n }\n\n // Resolve the handler\n const handler = resolveHandler(handlers, typeMappings, resource.type);\n\n if (!handler) {\n failed.push(`${resourceLabel} (no handler for type \"${resource.type}\")`);\n console.warn(`No cleanup handler for resource type: ${resource.type}`);\n return false;\n }\n\n // Retry with exponential backoff\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n await handler(resource);\n deleted.push(resourceLabel);\n return true;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (attempt === retries) {\n failed.push(`${resourceLabel} (${errorMessage})`);\n console.warn(\n `Failed to delete ${resourceLabel} after ${retries} attempts:`,\n errorMessage\n );\n return false;\n }\n\n // Exponential backoff: 100ms, 200ms, 400ms, 800ms...\n const delay = 100 * Math.pow(2, attempt - 1);\n console.debug(\n `Cleanup attempt ${attempt}/${retries} failed for ${resourceLabel}, ` +\n `retrying in ${delay}ms...`\n );\n await sleep(delay);\n }\n }\n\n return false;\n };\n\n if (parallel) {\n // Parallel execution\n const results = await Promise.allSettled(sorted.map(deleteResource));\n\n // Log any unexpected rejections (shouldn't happen since deleteResource handles errors)\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n const resource = sorted[index];\n console.error(\n `Unexpected error cleaning up ${resource.type}:${resource.id}:`,\n result.reason\n );\n }\n });\n } else {\n // Sequential execution\n for (const resource of sorted) {\n await deleteResource(resource);\n }\n }\n\n // After tracked cleanup, scan for untracked resources if configured\n if (config?.scanUntracked && provider?.cleanupUntracked) {\n console.log('\\n[Cleanup] Scanning for untracked resources...');\n\n try {\n const untrackedResult = await provider.cleanupUntracked({\n testStartTime: options.testStartTime ?? new Date().toISOString(),\n testStartTimeProvided: options.testStartTime !== undefined,\n userId: options.userId,\n userEmail: options.userEmail,\n sessionId: options.sessionId,\n });\n\n if (untrackedResult.deleted.length > 0) {\n console.log(`[Cleanup] Cleaned up ${untrackedResult.deleted.length} untracked resources`);\n deleted.push(...untrackedResult.deleted);\n }\n\n if (untrackedResult.failed.length > 0) {\n console.log(`[Cleanup] Failed to clean up ${untrackedResult.failed.length} untracked resources`);\n failed.push(...untrackedResult.failed);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`[Cleanup] Untracked resource scan failed: ${errorMessage}`);\n }\n }\n\n const result: CleanupResult = {\n success: failed.length === 0,\n deleted,\n failed,\n };\n\n // Save failed cleanups for retry if there were failures\n if (failed.length > 0 && options.providerConfig) {\n try {\n const persistenceId = options.sessionId\n ?? options.userId\n ?? options.userEmail\n ?? `cleanup-${new Date().toISOString().replace(/[:.]/g, '-')}`;\n\n // Extract the resources that failed\n const failedResources = sorted.filter((resource) => {\n const resourceLabel = `${resource.type}:${resource.id}`;\n return failed.some((f) => f.startsWith(resourceLabel));\n });\n\n await saveFailedCleanup(\n {\n sessionId: persistenceId,\n timestamp: new Date().toISOString(),\n resources: failedResources,\n providerConfig: options.providerConfig,\n errors: failed,\n },\n options.cwd\n );\n } catch (error) {\n // Don't fail the cleanup if we can't save the failed cleanup file\n console.warn('Failed to save cleanup persistence file:', error);\n }\n }\n\n return result;\n}\n\n/**\n * Create a cleanup executor with pre-configured handlers and options\n */\nexport function createCleanupExecutor(\n handlers: Map<string, CleanupHandler>,\n typeMappings: Record<string, string>,\n options: ExecutorOptions = {}\n) {\n return {\n /**\n * Execute cleanup for resources\n */\n cleanup: (resources: TrackedResource[]) =>\n executeCleanup(resources, handlers, typeMappings, options),\n\n /**\n * Execute cleanup for a single resource\n */\n cleanupOne: async (resource: TrackedResource): Promise<boolean> => {\n const result = await executeCleanup([resource], handlers, typeMappings, options);\n return result.success;\n },\n };\n}\n","export * from './types.js';\nimport type { CleanupHandler } from './types.js';\n\nexport { executeCleanup, createCleanupExecutor, type ExtendedCleanupOptions } from './executor.js';\nexport { loadCleanupHandlers, resolveHandler } from './loader.js';\nexport { saveFailedCleanup, loadFailedCleanups, removeFailedCleanup, type FailedCleanup } from './persistence.js';\n\n/**\n * Helper for defining cleanup handlers in user files.\n * Provides type safety for custom cleanup handler definitions.\n *\n * @example\n * // In cleanup.ts\n * import { defineCleanupHandlers } from 'intellitester/cleanup';\n *\n * export default defineCleanupHandlers({\n * async deleteUser(resource) {\n * // cleanup logic\n * },\n * async deleteTeam(resource) {\n * // cleanup logic\n * }\n * });\n */\nexport function defineCleanupHandlers<T extends Record<string, CleanupHandler>>(handlers: T): T {\n return handlers;\n}\n"]}