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.
- package/README.md +18 -1
- package/dist/chunk-2BFRS6ZZ.js +59 -0
- package/dist/chunk-2BFRS6ZZ.js.map +1 -0
- package/dist/{chunk-QMYM2TCH.cjs → chunk-2IRHLFCW.cjs} +5 -5
- package/dist/{chunk-QMYM2TCH.cjs.map → chunk-2IRHLFCW.cjs.map} +1 -1
- package/dist/{chunk-ARJYJVRM.cjs → chunk-2ZSINOCK.cjs} +11 -8
- package/dist/chunk-2ZSINOCK.cjs.map +1 -0
- package/dist/chunk-64V2U2Y4.js +524 -0
- package/dist/chunk-64V2U2Y4.js.map +1 -0
- package/dist/chunk-B3ZQ425T.cjs +462 -0
- package/dist/chunk-B3ZQ425T.cjs.map +1 -0
- package/dist/{chunk-GFN6LIOF.cjs → chunk-CBPY7B6L.cjs} +613 -552
- package/dist/chunk-CBPY7B6L.cjs.map +1 -0
- package/dist/chunk-DPT2LVTT.cjs +550 -0
- package/dist/chunk-DPT2LVTT.cjs.map +1 -0
- package/dist/{chunk-HQOYFF54.js → chunk-EPN5OT5I.js} +604 -524
- package/dist/chunk-EPN5OT5I.js.map +1 -0
- package/dist/{chunk-DE5UFTTG.js → chunk-LIVAF432.js} +3 -3
- package/dist/{chunk-DE5UFTTG.js.map → chunk-LIVAF432.js.map} +1 -1
- package/dist/{chunk-ECBA4GJ3.js → chunk-O4H5QO5P.js} +8 -5
- package/dist/chunk-O4H5QO5P.js.map +1 -0
- package/dist/chunk-YNHXOSMZ.cjs +61 -0
- package/dist/chunk-YNHXOSMZ.cjs.map +1 -0
- package/dist/chunk-ZUOYPCED.js +459 -0
- package/dist/chunk-ZUOYPCED.js.map +1 -0
- package/dist/cli/index.cjs +98 -57
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +55 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/core/cleanup/index.cjs +11 -11
- package/dist/core/cleanup/index.d.cts +2 -2
- package/dist/core/cleanup/index.d.ts +2 -2
- package/dist/core/cleanup/index.js +3 -3
- package/dist/index.cjs +71 -69
- package/dist/index.d.cts +1186 -221
- package/dist/index.d.ts +1186 -221
- package/dist/index.js +6 -4
- package/dist/integration/index.cjs +7 -17
- package/dist/integration/index.cjs.map +1 -1
- package/dist/integration/index.d.cts +0 -14
- package/dist/integration/index.d.ts +0 -14
- package/dist/integration/index.js +1 -18
- package/dist/integration/index.js.map +1 -1
- package/dist/loader-6IZ4CERA.cjs +60 -0
- package/dist/loader-6IZ4CERA.cjs.map +1 -0
- package/dist/loader-JSTO36JJ.js +3 -0
- package/dist/loader-JSTO36JJ.js.map +1 -0
- package/dist/providers/appwrite/index.cjs +3 -3
- package/dist/providers/appwrite/index.d.cts +1 -1
- package/dist/providers/appwrite/index.d.ts +1 -1
- package/dist/providers/appwrite/index.js +1 -1
- package/dist/providers/index.cjs +8 -8
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +2 -2
- package/dist/providers/mysql/index.d.cts +1 -1
- package/dist/providers/mysql/index.d.ts +1 -1
- package/dist/providers/postgres/index.d.cts +1 -1
- package/dist/providers/postgres/index.d.ts +1 -1
- package/dist/providers/sqlite/index.d.cts +1 -1
- package/dist/providers/sqlite/index.d.ts +1 -1
- package/dist/{types-l-ZaFKC-.d.ts → types-BJ8oJgr1.d.ts} +3 -0
- package/dist/{types-LONNVTIF.d.cts → types-D6s-QFkg.d.cts} +3 -0
- package/package.json +1 -1
- package/schemas/intellitester.config.schema.json +5 -1
- package/schemas/pipeline.schema.json +5 -1
- package/schemas/test.schema.json +351 -1
- package/schemas/workflow.schema.json +5 -1
- package/dist/chunk-4B54JUOP.js +0 -234
- package/dist/chunk-4B54JUOP.js.map +0 -1
- package/dist/chunk-ARJYJVRM.cjs.map +0 -1
- package/dist/chunk-ECBA4GJ3.js.map +0 -1
- package/dist/chunk-GFN6LIOF.cjs.map +0 -1
- package/dist/chunk-HQOYFF54.js.map +0 -1
- package/dist/chunk-OFXNJXMV.cjs +0 -237
- 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
|
|
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) =>
|
|
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:
|
|
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-
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
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-
|
|
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
|
|
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 =
|
|
24
|
+
const factory = chunk2IRHLFCW_cjs.providerFactories[config.provider];
|
|
25
25
|
if (!factory) {
|
|
26
|
-
throw new Error(`Unknown provider: ${config.provider}. Available: ${Object.keys(
|
|
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 = { ...
|
|
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.
|
|
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:
|
|
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-
|
|
302
|
-
//# sourceMappingURL=chunk-
|
|
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"]}
|