xtrawl 0.1.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/DOCUMENTATION.md +774 -0
- package/README.md +232 -0
- package/dist/auth/bootstrap.d.ts +4 -0
- package/dist/auth/bootstrap.d.ts.map +1 -0
- package/dist/auth/bootstrap.js +29 -0
- package/dist/auth/bootstrap.js.map +1 -0
- package/dist/auth/cookies.d.ts +7 -0
- package/dist/auth/cookies.d.ts.map +1 -0
- package/dist/auth/cookies.js +83 -0
- package/dist/auth/cookies.js.map +1 -0
- package/dist/auth/loaders.d.ts +6 -0
- package/dist/auth/loaders.d.ts.map +1 -0
- package/dist/auth/loaders.js +69 -0
- package/dist/auth/loaders.js.map +1 -0
- package/dist/auth/material.d.ts +3 -0
- package/dist/auth/material.d.ts.map +1 -0
- package/dist/auth/material.js +20 -0
- package/dist/auth/material.js.map +1 -0
- package/dist/auth/records.d.ts +4 -0
- package/dist/auth/records.d.ts.map +1 -0
- package/dist/auth/records.js +38 -0
- package/dist/auth/records.js.map +1 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +30 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +85 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/parser.d.ts +22 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +275 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/client/client.d.ts +29 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +192 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/collectors.d.ts +15 -0
- package/dist/client/collectors.d.ts.map +1 -0
- package/dist/client/collectors.js +185 -0
- package/dist/client/collectors.js.map +1 -0
- package/dist/client/database.d.ts +56 -0
- package/dist/client/database.d.ts.map +1 -0
- package/dist/client/database.js +146 -0
- package/dist/client/database.js.map +1 -0
- package/dist/client/profiles.d.ts +5 -0
- package/dist/client/profiles.d.ts.map +1 -0
- package/dist/client/profiles.js +36 -0
- package/dist/client/profiles.js.map +1 -0
- package/dist/client/search.d.ts +21 -0
- package/dist/client/search.d.ts.map +1 -0
- package/dist/client/search.js +139 -0
- package/dist/client/search.js.map +1 -0
- package/dist/client/types.d.ts +21 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +38 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/environment.d.ts +5 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +62 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/config/types.d.ts +47 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/validation.d.ts +6 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +147 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/domain/accounts.d.ts +64 -0
- package/dist/domain/accounts.d.ts.map +1 -0
- package/dist/domain/accounts.js +2 -0
- package/dist/domain/accounts.js.map +1 -0
- package/dist/domain/errors.d.ts +61 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/errors.js +89 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/http.d.ts +36 -0
- package/dist/domain/http.d.ts.map +1 -0
- package/dist/domain/http.js +2 -0
- package/dist/domain/http.js.map +1 -0
- package/dist/domain/manifest.d.ts +23 -0
- package/dist/domain/manifest.d.ts.map +1 -0
- package/dist/domain/manifest.js +2 -0
- package/dist/domain/manifest.js.map +1 -0
- package/dist/domain/records.d.ts +67 -0
- package/dist/domain/records.d.ts.map +1 -0
- package/dist/domain/records.js +2 -0
- package/dist/domain/records.js.map +1 -0
- package/dist/domain/requests.d.ts +87 -0
- package/dist/domain/requests.d.ts.map +1 -0
- package/dist/domain/requests.js +2 -0
- package/dist/domain/requests.js.map +1 -0
- package/dist/engine/api-engine.d.ts +25 -0
- package/dist/engine/api-engine.d.ts.map +1 -0
- package/dist/engine/api-engine.js +98 -0
- package/dist/engine/api-engine.js.map +1 -0
- package/dist/engine/extractors.d.ts +27 -0
- package/dist/engine/extractors.d.ts.map +1 -0
- package/dist/engine/extractors.js +248 -0
- package/dist/engine/extractors.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/default-manifest.d.ts +3 -0
- package/dist/manifest/default-manifest.d.ts.map +1 -0
- package/dist/manifest/default-manifest.js +46 -0
- package/dist/manifest/default-manifest.js.map +1 -0
- package/dist/manifest/model.d.ts +3 -0
- package/dist/manifest/model.d.ts.map +1 -0
- package/dist/manifest/model.js +48 -0
- package/dist/manifest/model.js.map +1 -0
- package/dist/manifest/provider.d.ts +19 -0
- package/dist/manifest/provider.d.ts.map +1 -0
- package/dist/manifest/provider.js +94 -0
- package/dist/manifest/provider.js.map +1 -0
- package/dist/manifest/scraper.d.ts +11 -0
- package/dist/manifest/scraper.d.ts.map +1 -0
- package/dist/manifest/scraper.js +130 -0
- package/dist/manifest/scraper.js.map +1 -0
- package/dist/output/csv-writer.d.ts +2 -0
- package/dist/output/csv-writer.d.ts.map +1 -0
- package/dist/output/csv-writer.js +94 -0
- package/dist/output/csv-writer.js.map +1 -0
- package/dist/output/json-writer.d.ts +2 -0
- package/dist/output/json-writer.d.ts.map +1 -0
- package/dist/output/json-writer.js +29 -0
- package/dist/output/json-writer.js.map +1 -0
- package/dist/output/names.d.ts +4 -0
- package/dist/output/names.d.ts.map +1 -0
- package/dist/output/names.js +22 -0
- package/dist/output/names.js.map +1 -0
- package/dist/output/writer.d.ts +7 -0
- package/dist/output/writer.d.ts.map +1 -0
- package/dist/output/writer.js +33 -0
- package/dist/output/writer.js.map +1 -0
- package/dist/pool/account-pool.d.ts +29 -0
- package/dist/pool/account-pool.d.ts.map +1 -0
- package/dist/pool/account-pool.js +145 -0
- package/dist/pool/account-pool.js.map +1 -0
- package/dist/pool/cooldown.d.ts +18 -0
- package/dist/pool/cooldown.d.ts.map +1 -0
- package/dist/pool/cooldown.js +38 -0
- package/dist/pool/cooldown.js.map +1 -0
- package/dist/pool/limiter.d.ts +11 -0
- package/dist/pool/limiter.d.ts.map +1 -0
- package/dist/pool/limiter.js +27 -0
- package/dist/pool/limiter.js.map +1 -0
- package/dist/query/builder.d.ts +19 -0
- package/dist/query/builder.d.ts.map +1 -0
- package/dist/query/builder.js +110 -0
- package/dist/query/builder.js.map +1 -0
- package/dist/query/hash.d.ts +2 -0
- package/dist/query/hash.d.ts.map +1 -0
- package/dist/query/hash.js +6 -0
- package/dist/query/hash.js.map +1 -0
- package/dist/query/normalize.d.ts +39 -0
- package/dist/query/normalize.d.ts.map +1 -0
- package/dist/query/normalize.js +176 -0
- package/dist/query/normalize.js.map +1 -0
- package/dist/query/targets.d.ts +11 -0
- package/dist/query/targets.d.ts.map +1 -0
- package/dist/query/targets.js +96 -0
- package/dist/query/targets.js.map +1 -0
- package/dist/runner/index.d.ts +4 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +4 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/retry.d.ts +7 -0
- package/dist/runner/retry.d.ts.map +1 -0
- package/dist/runner/retry.js +26 -0
- package/dist/runner/retry.js.map +1 -0
- package/dist/runner/runner.d.ts +20 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +37 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/task-queue.d.ts +19 -0
- package/dist/runner/task-queue.d.ts.map +1 -0
- package/dist/runner/task-queue.js +58 -0
- package/dist/runner/task-queue.js.map +1 -0
- package/dist/storage/account-repository.d.ts +50 -0
- package/dist/storage/account-repository.d.ts.map +1 -0
- package/dist/storage/account-repository.js +171 -0
- package/dist/storage/account-repository.js.map +1 -0
- package/dist/storage/account-row.d.ts +4 -0
- package/dist/storage/account-row.d.ts.map +1 -0
- package/dist/storage/account-row.js +46 -0
- package/dist/storage/account-row.js.map +1 -0
- package/dist/storage/checkpoint-repository.d.ts +10 -0
- package/dist/storage/checkpoint-repository.d.ts.map +1 -0
- package/dist/storage/checkpoint-repository.js +30 -0
- package/dist/storage/checkpoint-repository.js.map +1 -0
- package/dist/storage/database.d.ts +18 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +42 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/index.d.ts +15 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +18 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/manifest-repository.d.ts +9 -0
- package/dist/storage/manifest-repository.d.ts.map +1 -0
- package/dist/storage/manifest-repository.js +22 -0
- package/dist/storage/manifest-repository.js.map +1 -0
- package/dist/storage/run-repository.d.ts +24 -0
- package/dist/storage/run-repository.d.ts.map +1 -0
- package/dist/storage/run-repository.js +51 -0
- package/dist/storage/run-repository.js.map +1 -0
- package/dist/storage/schema.d.ts +3 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +53 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/transport/graphql.d.ts +8 -0
- package/dist/transport/graphql.d.ts.map +1 -0
- package/dist/transport/graphql.js +104 -0
- package/dist/transport/graphql.js.map +1 -0
- package/dist/transport/proxy.d.ts +5 -0
- package/dist/transport/proxy.d.ts.map +1 -0
- package/dist/transport/proxy.js +36 -0
- package/dist/transport/proxy.js.map +1 -0
- package/dist/transport/session.d.ts +25 -0
- package/dist/transport/session.d.ts.map +1 -0
- package/dist/transport/session.js +138 -0
- package/dist/transport/session.js.map +1 -0
- package/dist/transport/transaction-id.d.ts +20 -0
- package/dist/transport/transaction-id.d.ts.map +1 -0
- package/dist/transport/transaction-id.js +74 -0
- package/dist/transport/transaction-id.js.map +1 -0
- package/dist/utils/fingerprint.d.ts +3 -0
- package/dist/utils/fingerprint.d.ts.map +1 -0
- package/dist/utils/fingerprint.js +20 -0
- package/dist/utils/fingerprint.js.map +1 -0
- package/dist/utils/guards.d.ts +8 -0
- package/dist/utils/guards.d.ts.map +1 -0
- package/dist/utils/guards.js +38 -0
- package/dist/utils/guards.js.map +1 -0
- package/docs/architecture/overview.md +59 -0
- package/docs/decisions/0001-runtime-and-state.md +21 -0
- package/docs/decisions/0002-modular-boundaries.md +16 -0
- package/docs/plans/initial-build.md +18 -0
- package/docs/product/specification.md +87 -0
- package/docs/security/data-boundary.md +27 -0
- package/package.json +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/transport/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface TransactionIdSource {
|
|
2
|
+
readonly create?: (method: string, url: string) => Promise<string | undefined>;
|
|
3
|
+
}
|
|
4
|
+
export interface TransactionIdOptions {
|
|
5
|
+
readonly enabled?: boolean;
|
|
6
|
+
readonly ttlMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class TransactionIdProvider {
|
|
9
|
+
private readonly source?;
|
|
10
|
+
private readonly options;
|
|
11
|
+
private client?;
|
|
12
|
+
private readyAt;
|
|
13
|
+
private retryAt;
|
|
14
|
+
private initializing?;
|
|
15
|
+
constructor(source?: TransactionIdSource | undefined, options?: TransactionIdOptions);
|
|
16
|
+
get(method: string, url: string): Promise<string | undefined>;
|
|
17
|
+
private currentClient;
|
|
18
|
+
private initialize;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=transaction-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-id.d.ts","sourceRoot":"","sources":["../../src/transport/transaction-id.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAChF;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,YAAY,CAAC,CAAyC;gBAG3C,MAAM,CAAC,EAAE,mBAAmB,YAAA,EAC5B,OAAO,GAAE,oBAAyB;IAGxC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAe5D,aAAa;YAYb,UAAU;CAezB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export class TransactionIdProvider {
|
|
2
|
+
source;
|
|
3
|
+
options;
|
|
4
|
+
client;
|
|
5
|
+
readyAt = 0;
|
|
6
|
+
retryAt = 0;
|
|
7
|
+
initializing;
|
|
8
|
+
constructor(source, options = {}) {
|
|
9
|
+
this.source = source;
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
async get(method, url) {
|
|
13
|
+
if (this.source?.create)
|
|
14
|
+
return this.source.create(method, url);
|
|
15
|
+
if (this.options.enabled !== true)
|
|
16
|
+
return undefined;
|
|
17
|
+
const client = await this.currentClient();
|
|
18
|
+
if (!client)
|
|
19
|
+
return undefined;
|
|
20
|
+
try {
|
|
21
|
+
return await client.generateTransactionId(method, new URL(url).pathname);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
this.client = undefined;
|
|
25
|
+
this.readyAt = 0;
|
|
26
|
+
this.retryAt = Date.now() + 5 * 60_000;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async currentClient() {
|
|
31
|
+
const ttl = Math.max(60_000, this.options.ttlMs ?? 6 * 60 * 60 * 1_000);
|
|
32
|
+
if (this.client && Date.now() - this.readyAt < ttl)
|
|
33
|
+
return this.client;
|
|
34
|
+
if (this.retryAt > Date.now())
|
|
35
|
+
return undefined;
|
|
36
|
+
if (!this.initializing)
|
|
37
|
+
this.initializing = this.initialize();
|
|
38
|
+
try {
|
|
39
|
+
return await this.initializing;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
this.initializing = undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async initialize() {
|
|
46
|
+
try {
|
|
47
|
+
const { ClientTransaction, fetchXDocument } = await import("x-client-transaction-id");
|
|
48
|
+
this.client = await withTimeout(fetchXDocument().then((document) => ClientTransaction.create(document)), 10_000);
|
|
49
|
+
this.readyAt = Date.now();
|
|
50
|
+
this.retryAt = 0;
|
|
51
|
+
return this.client;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
this.retryAt = Date.now() + 5 * 60_000;
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function withTimeout(value, timeoutMs) {
|
|
60
|
+
let timer;
|
|
61
|
+
try {
|
|
62
|
+
return await Promise.race([
|
|
63
|
+
value,
|
|
64
|
+
new Promise((_resolve, reject) => {
|
|
65
|
+
timer = setTimeout(() => reject(new Error("Transaction bootstrap timed out.")), timeoutMs);
|
|
66
|
+
}),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
if (timer)
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=transaction-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-id.js","sourceRoot":"","sources":["../../src/transport/transaction-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGlE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export function tokenFingerprint(token) {
|
|
3
|
+
if (!token)
|
|
4
|
+
return "-";
|
|
5
|
+
return createHash("sha1").update(token).digest("hex").slice(0, 10);
|
|
6
|
+
}
|
|
7
|
+
export function stableJson(value) {
|
|
8
|
+
return JSON.stringify(sortValue(value));
|
|
9
|
+
}
|
|
10
|
+
function sortValue(value) {
|
|
11
|
+
if (Array.isArray(value))
|
|
12
|
+
return value.map(sortValue);
|
|
13
|
+
if (value && typeof value === "object") {
|
|
14
|
+
return Object.fromEntries(Object.entries(value)
|
|
15
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
16
|
+
.map(([key, child]) => [key, sortValue(child)]));
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAAC,KAAyB;IACxD,IAAI,CAAC,KAAK;QAAE,OAAO,GAAG,CAAC;IACvB,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAClB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAClD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
2
|
+
export declare function asRecord(value: unknown): Record<string, unknown>;
|
|
3
|
+
export declare function asString(value: unknown): string | undefined;
|
|
4
|
+
export declare function asNumber(value: unknown, fallback?: number): number;
|
|
5
|
+
export declare function asInteger(value: unknown, fallback?: number): number;
|
|
6
|
+
export declare function asBoolean(value: unknown, fallback?: boolean): boolean;
|
|
7
|
+
export declare function asStringList(value: unknown): string[];
|
|
8
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI3D;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAI,GAAG,MAAM,CAG7D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAI,GAAG,MAAM,CAE9D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,UAAQ,GAAG,OAAO,CASnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function asRecord(value) {
|
|
5
|
+
return isRecord(value) ? value : {};
|
|
6
|
+
}
|
|
7
|
+
export function asString(value) {
|
|
8
|
+
if (value === null || value === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
const text = String(value).trim();
|
|
11
|
+
return text.length > 0 ? text : undefined;
|
|
12
|
+
}
|
|
13
|
+
export function asNumber(value, fallback = 0) {
|
|
14
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
15
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
16
|
+
}
|
|
17
|
+
export function asInteger(value, fallback = 0) {
|
|
18
|
+
return Math.trunc(asNumber(value, fallback));
|
|
19
|
+
}
|
|
20
|
+
export function asBoolean(value, fallback = false) {
|
|
21
|
+
if (typeof value === "boolean")
|
|
22
|
+
return value;
|
|
23
|
+
if (typeof value === "number")
|
|
24
|
+
return value !== 0;
|
|
25
|
+
if (typeof value === "string") {
|
|
26
|
+
const normalized = value.trim().toLowerCase();
|
|
27
|
+
if (["1", "true", "yes", "y", "on"].includes(normalized))
|
|
28
|
+
return true;
|
|
29
|
+
if (["0", "false", "no", "n", "off", ""].includes(normalized))
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
export function asStringList(value) {
|
|
35
|
+
const values = Array.isArray(value) ? value : value === undefined || value === null ? [] : [value];
|
|
36
|
+
return values.map(asString).filter((item) => Boolean(item));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc,EAAE,QAAQ,GAAG,CAAC;IACnD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,QAAQ,GAAG,CAAC;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,QAAQ,GAAG,KAAK;IACxD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,KAAK,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QACtE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;IAC9E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnG,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Architecture overview
|
|
2
|
+
|
|
3
|
+
## Boundary map
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
CLI / library facade
|
|
7
|
+
|
|
|
8
|
+
v
|
|
9
|
+
application client -----> runner / pagination
|
|
10
|
+
| |
|
|
11
|
+
| v
|
|
12
|
+
| account pool
|
|
13
|
+
| / \
|
|
14
|
+
v v v
|
|
15
|
+
query builders SQLite state session builder
|
|
16
|
+
| |
|
|
17
|
+
v v
|
|
18
|
+
GraphQL engine <------------------ HTTP transport
|
|
19
|
+
|
|
|
20
|
+
v
|
|
21
|
+
typed records / output writers
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Dependency direction
|
|
25
|
+
|
|
26
|
+
- `domain` contains contracts, value types, and errors. It imports no other project layer.
|
|
27
|
+
- `config` validates caller options and depends only on domain contracts.
|
|
28
|
+
- `storage` owns SQLite schema and repositories; it does not know CLI formatting.
|
|
29
|
+
- `auth` converts external credential shapes into typed account records and calls storage interfaces.
|
|
30
|
+
- `transport` owns cookies, headers, proxies, transaction IDs, and HTTP response classification.
|
|
31
|
+
- `manifest`, `query`, and `engine` build and interpret the remote GraphQL protocol.
|
|
32
|
+
- `pool` owns per-page leases, heartbeats, cooldowns, token-bucket spacing, retries, session repair,
|
|
33
|
+
proxy preflight, and account selection.
|
|
34
|
+
- `runner` coordinates bounded concurrent targets and search intervals through interfaces.
|
|
35
|
+
- `client` composes concrete adapters and exposes the stable public API.
|
|
36
|
+
- `cli` parses arguments and renders results; it never implements scraping logic.
|
|
37
|
+
|
|
38
|
+
## Persistence topology
|
|
39
|
+
|
|
40
|
+
One configured SQLite database contains accounts, leases, run records, resume checkpoints, and cached
|
|
41
|
+
manifest payloads. Repositories expose typed methods and keep SQL statements local to their owning
|
|
42
|
+
files. Raw secrets are stored only when the caller explicitly provisions them; logs and projections
|
|
43
|
+
use a token fingerprint.
|
|
44
|
+
|
|
45
|
+
## Runtime trust boundaries
|
|
46
|
+
|
|
47
|
+
1. Caller input crosses runtime guards before entering domain services.
|
|
48
|
+
2. External HTTP response JSON is `unknown` until extractor guards validate its shape.
|
|
49
|
+
3. Remote text, manifests, and headers are data, never executable instructions.
|
|
50
|
+
4. Secrets cross only the session builder and SQLite provisioning boundary; public inspection and
|
|
51
|
+
maintenance projections redact them, and they are excluded from output and harness state.
|
|
52
|
+
|
|
53
|
+
## Verification architecture
|
|
54
|
+
|
|
55
|
+
- Unit tests exercise pure normalization, parsing, limits, and repository behavior.
|
|
56
|
+
- Contract tests exercise the GraphQL engine with deterministic fake sessions.
|
|
57
|
+
- Integration tests are gated by `RUN_LIVE_TESTS=1` and environment credentials.
|
|
58
|
+
- Package checks compile the distribution and invoke CLI help.
|
|
59
|
+
- Harness checks validate state paths, source links, budgets, and secret patterns.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ADR 0001: Node runtime and local state
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted — 2026-08-11
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
Use strict TypeScript on Node.js 22.5+ with the built-in `node:sqlite` API and `undici` for HTTP.
|
|
10
|
+
Expose asynchronous library methods and keep all persistence behind repository interfaces.
|
|
11
|
+
|
|
12
|
+
## Alternatives considered
|
|
13
|
+
|
|
14
|
+
- A native SQLite package: broader historical Node support, but adds native build and deployment risk.
|
|
15
|
+
- A hosted database: useful for multi-process deployments, but outside the local-first first release.
|
|
16
|
+
- Blocking synchronous network methods: familiar to some callers, but unsafe for a Node library.
|
|
17
|
+
|
|
18
|
+
## Consequences
|
|
19
|
+
|
|
20
|
+
The first release has a clear runtime floor and no native database install step. A future persistence
|
|
21
|
+
adapter can implement the same repository interfaces if runtime evidence justifies it.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# ADR 0002: Domain-sized modules
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted — 2026-08-11
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
Keep authentication, storage, transport, manifest, query, engine, pooling, runner, output, client,
|
|
10
|
+
and CLI as separate domains. Files should hold one cohesive responsibility and be split before they
|
|
11
|
+
become broad service objects.
|
|
12
|
+
|
|
13
|
+
## Consequences
|
|
14
|
+
|
|
15
|
+
Behavioral tests can replace one boundary at a time. The project has more small files than a single
|
|
16
|
+
script, but changes remain discoverable and strict interfaces prevent accidental cross-layer coupling.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Initial build plan
|
|
2
|
+
|
|
3
|
+
## Work items
|
|
4
|
+
|
|
5
|
+
1. Establish strict contracts and runtime validation.
|
|
6
|
+
2. Implement local state schema and typed repositories.
|
|
7
|
+
3. Implement credential loaders and session construction.
|
|
8
|
+
4. Implement manifest, transaction, query, GraphQL transport, and extractors.
|
|
9
|
+
5. Implement account leasing, cooldowns, retry runner, and cursor checkpoints.
|
|
10
|
+
6. Implement outputs, public client, and CLI.
|
|
11
|
+
7. Port deterministic behavioral coverage by domain and add opt-in live checks.
|
|
12
|
+
8. Run the full delivery gate, inspect the tree, and update the harness handoff. **Complete.**
|
|
13
|
+
|
|
14
|
+
## Completion evidence
|
|
15
|
+
|
|
16
|
+
- Build, lint, formatting, unit tests, package smoke test, harness validator, and budget report pass.
|
|
17
|
+
- The test suite has no external project names or real credentials.
|
|
18
|
+
- The work state records the verification commands and remaining live-test status.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Product specification
|
|
2
|
+
|
|
3
|
+
**Status:** approved for implementation
|
|
4
|
+
**Owner:** project user
|
|
5
|
+
**Last reviewed:** 2026-08-11
|
|
6
|
+
|
|
7
|
+
## Product hypothesis
|
|
8
|
+
|
|
9
|
+
Developers need a maintainable TypeScript client that can collect publicly visible X data through
|
|
10
|
+
the web GraphQL surface using authorized browser-session cookies, while limiting account pressure,
|
|
11
|
+
persisting progress locally, and exposing predictable typed results.
|
|
12
|
+
|
|
13
|
+
## Users and outcomes
|
|
14
|
+
|
|
15
|
+
| User | Problem | Successful outcome |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| TypeScript developer | Existing clients are difficult to type, test, and extend | Import a small typed API and receive stable records |
|
|
18
|
+
| Data operator | Long reads fail when a session is cooled or a process stops | Pool accounts, retry safely, and resume from checkpoints |
|
|
19
|
+
| Maintainer | Transport, persistence, and domain behavior become coupled | Each boundary is replaceable and covered by focused tests |
|
|
20
|
+
|
|
21
|
+
## Principal journeys
|
|
22
|
+
|
|
23
|
+
1. Provision one or more accounts from cookies, a JSON file, a dotenv file, or a delimited account file.
|
|
24
|
+
2. Search public posts with structured filters, explicit date bounds, a result limit, and optional output persistence.
|
|
25
|
+
3. Resolve individual posts and user profiles, fetch profile timelines, and collect followers/following with cursor pagination.
|
|
26
|
+
4. Reuse local SQLite state after restart, including account cooldowns, leases, run history, and resume cursors.
|
|
27
|
+
5. Run the CLI or library with deterministic typed errors and no mutation of the remote account.
|
|
28
|
+
|
|
29
|
+
## First-release scope
|
|
30
|
+
|
|
31
|
+
- Read-only search, single-post lookup, user lookup, profile timelines, followers, following, and verified-followers endpoints.
|
|
32
|
+
- Cookie authentication using `auth_token` plus CSRF cookie, with token-only bootstrap when the platform supplies the CSRF cookie.
|
|
33
|
+
- Per-page account leases with heartbeat, accurate request/tweet counters, cooldown classification,
|
|
34
|
+
retry/backoff, account switching, and bounded concurrency.
|
|
35
|
+
- Default 30-day search bounds, concurrent interval splitting, URL/handle/user-ID normalization, and
|
|
36
|
+
no-progress pagination stops.
|
|
37
|
+
- Local SQLite state, resumable cursors, CSV/JSON output, structured CLI, and async library methods.
|
|
38
|
+
- Local manifest fallback and optional live manifest refresh for rotating GraphQL identifiers.
|
|
39
|
+
- Optional transaction-header generation, HTTP/HTTPS/SOCKS5 proxies with preflight checks, appendable
|
|
40
|
+
descriptive outputs, and redacted local-state maintenance APIs.
|
|
41
|
+
- Strict TypeScript interfaces, runtime guards at external boundaries, and test doubles for all network paths.
|
|
42
|
+
|
|
43
|
+
## Explicit exclusions
|
|
44
|
+
|
|
45
|
+
- Posting, replying, liking, following, messaging, account settings, or any other remote mutation.
|
|
46
|
+
- Credential discovery, password guessing, session theft, or bypassing access controls.
|
|
47
|
+
- Private/protected content access.
|
|
48
|
+
- Cloud storage, hosted queues, telemetry, global agent memory, or an always-on daemon.
|
|
49
|
+
- Real credentials in source, tests, fixtures, logs, or harness state.
|
|
50
|
+
|
|
51
|
+
## Data and trust
|
|
52
|
+
|
|
53
|
+
- Data classes: public profile/post/relationship records; caller-owned session secrets; local operational metadata.
|
|
54
|
+
- Authentication: caller supplies browser-session cookies or a caller-owned credential source.
|
|
55
|
+
- Authorization: caller is responsible for account ownership and platform authorization; the client performs read-only requests.
|
|
56
|
+
- Tenancy: single local project instance; account rows are isolated by stable username/token fingerprint.
|
|
57
|
+
- Destructive actions: no remote destructive actions; local state deletion is explicit and scoped to the configured database.
|
|
58
|
+
- Privacy/compliance: minimize collected fields, avoid raw payload persistence unless requested, and follow applicable platform terms and law.
|
|
59
|
+
|
|
60
|
+
## Runtime and operations
|
|
61
|
+
|
|
62
|
+
- Surfaces: TypeScript library and command-line interface.
|
|
63
|
+
- Platforms: Node.js 22.5+ on macOS, Linux, and Windows where built-in SQLite is available.
|
|
64
|
+
- Local/offline/cloud: local-first; network is required only for live collection and optional manifest refresh.
|
|
65
|
+
- Scale and latency: bounded by configured concurrency, per-account daily limits, and platform responses.
|
|
66
|
+
- Availability/recovery: restart-safe SQLite state, cooldowns, cursor checkpoints, and deterministic output files.
|
|
67
|
+
- Cost boundary: no service dependency; caller controls network/proxy costs.
|
|
68
|
+
- Integrations: X web GraphQL endpoints, HTTP proxies, filesystem outputs, and environment variables.
|
|
69
|
+
|
|
70
|
+
## Acceptance criteria
|
|
71
|
+
|
|
72
|
+
- [x] `npm run build` passes with strict compiler options and no implicit `any`.
|
|
73
|
+
- [x] All deterministic behavioral areas are covered: config, loaders, query construction, persistence, pooling, cooldowns, manifest, transport, parsing, runners, outputs, CLI, and client routing.
|
|
74
|
+
- [x] The compiled CLI help and package smoke check run without credentials.
|
|
75
|
+
- [x] Live tests are opt-in, use caller-supplied secrets only, perform read-only requests, and do not write secrets to the repository.
|
|
76
|
+
- [x] A profile lookup, bounded search, profile timeline, single-post lookup, and all relationship operations complete with a valid authorized session in the opt-in live suite.
|
|
77
|
+
- [x] Harness structural validation and context-budget evaluation pass.
|
|
78
|
+
- [x] A fresh agent can identify the current work and next action from `.harness/state/` without chat history.
|
|
79
|
+
|
|
80
|
+
## Open decisions
|
|
81
|
+
|
|
82
|
+
- The built-in Node SQLite API is the first-release persistence adapter; a portable driver can be added only if supported-runtime evidence requires it.
|
|
83
|
+
- Async methods are the canonical library surface. A blocking synchronous wrapper is intentionally excluded because it would compromise Node event-loop safety.
|
|
84
|
+
|
|
85
|
+
## Immediate next action
|
|
86
|
+
|
|
87
|
+
Keep the bundled manifest current and use the opt-in live suite after GraphQL protocol changes.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Security and data boundary
|
|
2
|
+
|
|
3
|
+
## Secret handling
|
|
4
|
+
|
|
5
|
+
- Session tokens, CSRF values, passwords, email passwords, and OTP seeds are caller-owned secrets.
|
|
6
|
+
- They may be read from process environment, caller-provided files, or in-memory arguments only.
|
|
7
|
+
- They must not appear in Git, test fixtures, JSON snapshots, logs, CLI output, harness state, or handoffs.
|
|
8
|
+
- Diagnostics may include a stable non-reversible fingerprint and a reason code, never the secret value.
|
|
9
|
+
|
|
10
|
+
## Network boundary
|
|
11
|
+
|
|
12
|
+
- The client sends only read-oriented GraphQL query requests over GET or POST and an optional home-page bootstrap request.
|
|
13
|
+
- The client does not expose mutation operations.
|
|
14
|
+
- HTTP, HTTPS, and SOCKS5 proxies are normalized and passed to the HTTP adapter. Health checks carry
|
|
15
|
+
no session cookies, and proxy credentials are redacted from inspection and diagnostics.
|
|
16
|
+
- External payloads are parsed as `unknown` and narrowed before use.
|
|
17
|
+
|
|
18
|
+
## Local state
|
|
19
|
+
|
|
20
|
+
- SQLite is scoped to the configured path and can be deleted by the caller.
|
|
21
|
+
- Raw response payloads are returned only when the caller requests them; operational state stores compact metadata.
|
|
22
|
+
- Output paths are caller-controlled but must remain explicit; no recursive deletion is performed by the package.
|
|
23
|
+
|
|
24
|
+
## Verification
|
|
25
|
+
|
|
26
|
+
The harness scans durable project state for common secret patterns. Live tests use process environment
|
|
27
|
+
variables and are skipped by default.
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xtrawl",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scrape public X posts, profiles, followers, and following",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"DOCUMENTATION.md",
|
|
13
|
+
"docs"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/ensp1re/xtrawl.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/ensp1re/xtrawl#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/ensp1re/xtrawl/issues"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"x",
|
|
25
|
+
"twitter",
|
|
26
|
+
"scraper",
|
|
27
|
+
"crawler",
|
|
28
|
+
"typescript"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22.5.0"
|
|
32
|
+
},
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js",
|
|
37
|
+
"default": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./cli": {
|
|
40
|
+
"types": "./dist/cli/main.d.ts",
|
|
41
|
+
"import": "./dist/cli/main.js",
|
|
42
|
+
"default": "./dist/cli/main.js"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
46
|
+
"bin": {
|
|
47
|
+
"xtrawl": "./dist/cli/main.js"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsc -p tsconfig.json",
|
|
51
|
+
"clean": "node scripts/clean.mjs",
|
|
52
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.mjs\"",
|
|
53
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.mjs\"",
|
|
54
|
+
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
55
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --runInBand",
|
|
56
|
+
"test:integration": "RUN_LIVE_TESTS=1 NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --runInBand tests/integration",
|
|
57
|
+
"check": "npm run format:check && npm run lint && npm run build && npm test -- --runInBand",
|
|
58
|
+
"cli": "node dist/cli/main.js",
|
|
59
|
+
"context": "node scripts/harness/context.mjs",
|
|
60
|
+
"verify": "npm run format:check && npm run lint && npm run build && npm test -- --runInBand && npm run package:check && npm run harness:validate && npm run harness:budget",
|
|
61
|
+
"package:check": "node scripts/package-check.mjs",
|
|
62
|
+
"harness:validate": "python3 scripts/harness/validate.py",
|
|
63
|
+
"harness:budget": "python3 scripts/harness/budget.py",
|
|
64
|
+
"prepack": "npm run build",
|
|
65
|
+
"prepublishOnly": "npm run verify",
|
|
66
|
+
"prepare": "husky"
|
|
67
|
+
},
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"fetch-socks": "^1.3.3",
|
|
73
|
+
"undici": "^7.22.0",
|
|
74
|
+
"x-client-transaction-id": "^0.3.1"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@eslint/js": "^10.0.1",
|
|
78
|
+
"@types/jest": "^29.5.14",
|
|
79
|
+
"@types/node": "^25.2.3",
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "^8.62.1",
|
|
81
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
82
|
+
"eslint": "^10.6.0",
|
|
83
|
+
"husky": "^9.1.7",
|
|
84
|
+
"jest": "^29.7.0",
|
|
85
|
+
"prettier": "^3.9.4",
|
|
86
|
+
"ts-jest": "^29.3.4",
|
|
87
|
+
"typescript": "^5.9.3"
|
|
88
|
+
}
|
|
89
|
+
}
|