@t-req/core 0.1.0 → 0.2.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/README.md +158 -15
- package/dist/client.d.ts +0 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/config/engine-options.d.ts +48 -0
- package/dist/config/engine-options.d.ts.map +1 -0
- package/dist/config/index.d.ts +7 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -2
- package/dist/config/index.js.map +10 -5
- package/dist/config/jsonc.d.ts +18 -0
- package/dist/config/jsonc.d.ts.map +1 -0
- package/dist/config/load.d.ts +13 -2
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/merge.d.ts +31 -5
- package/dist/config/merge.d.ts.map +1 -1
- package/dist/config/resolve.d.ts +59 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/substitution.d.ts +25 -0
- package/dist/config/substitution.d.ts.map +1 -0
- package/dist/config/types.d.ts +60 -6
- package/dist/config/types.d.ts.map +1 -1
- package/dist/cookies/persistence.d.ts +48 -0
- package/dist/cookies/persistence.d.ts.map +1 -0
- package/dist/cookies/persistence.js +4 -0
- package/dist/cookies/persistence.js.map +10 -0
- package/dist/cookies.js +5 -5
- package/dist/cookies.js.map +2 -2
- package/dist/engine/engine.d.ts +0 -4
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/index.js +4 -4
- package/dist/engine/index.js.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +8 -6
- package/dist/interpolate.d.ts.map +1 -1
- package/dist/resolver/command.d.ts +19 -0
- package/dist/resolver/command.d.ts.map +1 -0
- package/dist/resolver/index.d.ts +2 -0
- package/dist/resolver/index.d.ts.map +1 -0
- package/dist/resolver/index.js +5 -0
- package/dist/resolver/index.js.map +10 -0
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/index.js.map +2 -2
- package/dist/server-client.d.ts +50 -0
- package/dist/server-client.d.ts.map +1 -0
- package/dist/server-metadata.d.ts +13 -0
- package/dist/server-metadata.d.ts.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -4
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ResolvedProjectConfig, TreqConfigInput } from './types';
|
|
2
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
3
|
+
export declare const DEFAULT_FOLLOW_REDIRECTS = true;
|
|
4
|
+
export declare const DEFAULT_VALIDATE_SSL = true;
|
|
5
|
+
export type ConfigOverrideLayer = {
|
|
6
|
+
/**
|
|
7
|
+
* A human-friendly layer name for introspection (e.g. "env", "cli", "session", "request").
|
|
8
|
+
*/
|
|
9
|
+
name: string;
|
|
10
|
+
overrides: Partial<TreqConfigInput>;
|
|
11
|
+
};
|
|
12
|
+
export type ResolveProjectConfigOptions = {
|
|
13
|
+
/**
|
|
14
|
+
* Directory to start searching for config from.
|
|
15
|
+
*/
|
|
16
|
+
startDir: string;
|
|
17
|
+
/**
|
|
18
|
+
* Stop searching at this directory (e.g., workspace root).
|
|
19
|
+
* Prevents accidentally picking a parent config outside the intended workspace.
|
|
20
|
+
*/
|
|
21
|
+
stopDir?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Profile to apply.
|
|
24
|
+
*/
|
|
25
|
+
profile?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Named override layers to apply, in-order, after profile.
|
|
28
|
+
* Each layer is merged with "last wins" semantics.
|
|
29
|
+
*/
|
|
30
|
+
overrideLayers?: ConfigOverrideLayer[];
|
|
31
|
+
/**
|
|
32
|
+
* Overrides to apply (from CLI flags, environment files, etc.).
|
|
33
|
+
* Applied after profile.
|
|
34
|
+
*/
|
|
35
|
+
overrides?: Partial<TreqConfigInput>;
|
|
36
|
+
/**
|
|
37
|
+
* Layer name recorded in metadata for the `overrides` option.
|
|
38
|
+
* Defaults to "overrides".
|
|
39
|
+
*/
|
|
40
|
+
overridesLayerName?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Resolve project configuration - the single source of truth for both CLI and server.
|
|
44
|
+
*
|
|
45
|
+
* This function:
|
|
46
|
+
* 1. Discovers config file (treq.jsonc, treq.json, treq.config.ts, etc.)
|
|
47
|
+
* 2. Parses the config
|
|
48
|
+
* 3. Applies substitutions ({env:}, {file:})
|
|
49
|
+
* 4. Applies profile overlay
|
|
50
|
+
* 5. Applies overrides (CLI flags, etc.)
|
|
51
|
+
* 6. Compiles resolvers (CommandResolverDef → Resolver wrapper)
|
|
52
|
+
* 7. Resolves cookies and defaults
|
|
53
|
+
* 8. Returns { config: ResolvedConfig, meta: ConfigMeta }
|
|
54
|
+
*
|
|
55
|
+
* @param options - Configuration options
|
|
56
|
+
* @returns ResolvedProjectConfig with config and metadata
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveProjectConfig(options: ResolveProjectConfigOptions): Promise<ResolvedProjectConfig>;
|
|
59
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAMV,qBAAqB,EACrB,eAAe,EAChB,MAAM,SAAS,CAAC;AAMjB,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAMzC,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAErC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAmIF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAqGhC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type SubstitutionOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Directory containing the config file (for relative path resolution)
|
|
4
|
+
*/
|
|
5
|
+
configDir: string;
|
|
6
|
+
/**
|
|
7
|
+
* Workspace root for security scoping
|
|
8
|
+
*/
|
|
9
|
+
workspaceRoot: string;
|
|
10
|
+
/**
|
|
11
|
+
* Allow file reads outside workspace (e.g., ~/.treq/token)
|
|
12
|
+
* Default: false
|
|
13
|
+
*/
|
|
14
|
+
allowExternalFiles?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Apply substitutions to all string values in an object/array.
|
|
18
|
+
* Only substitutes within string values, not keys.
|
|
19
|
+
*
|
|
20
|
+
* @param obj - The object to process
|
|
21
|
+
* @param options - Substitution options
|
|
22
|
+
* @returns A new object with substitutions applied
|
|
23
|
+
*/
|
|
24
|
+
export declare function applySubstitutions(obj: unknown, options: SubstitutionOptions): unknown;
|
|
25
|
+
//# sourceMappingURL=substitution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substitution.d.ts","sourceRoot":"","sources":["../../src/config/substitution.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AA4HF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAwBtF"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -6,17 +6,71 @@ export type TreqDefaults = {
|
|
|
6
6
|
proxy?: string;
|
|
7
7
|
headers?: Record<string, string>;
|
|
8
8
|
};
|
|
9
|
-
export type
|
|
9
|
+
export type ResolvedDefaults = {
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
followRedirects: boolean;
|
|
12
|
+
validateSSL: boolean;
|
|
13
|
+
proxy?: string;
|
|
14
|
+
headers: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
export type CookiesConfig = {
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
jarPath?: string;
|
|
19
|
+
};
|
|
20
|
+
export type ResolvedCookiesConfig = {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
jarPath?: string;
|
|
23
|
+
mode: 'disabled' | 'memory' | 'persistent';
|
|
24
|
+
};
|
|
25
|
+
export type SecurityConfig = {
|
|
26
|
+
allowExternalFiles?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type CommandResolverDef = {
|
|
29
|
+
type: 'command';
|
|
30
|
+
command: string[];
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
};
|
|
33
|
+
export type TreqProfileInput = {
|
|
10
34
|
variables?: Record<string, unknown>;
|
|
11
|
-
resolvers?: Record<string, Resolver>;
|
|
12
35
|
defaults?: TreqDefaults;
|
|
13
|
-
cookies?:
|
|
14
|
-
|
|
15
|
-
|
|
36
|
+
cookies?: CookiesConfig;
|
|
37
|
+
resolvers?: Record<string, Resolver | CommandResolverDef>;
|
|
38
|
+
};
|
|
39
|
+
export type TreqConfigInput = {
|
|
40
|
+
variables?: Record<string, unknown>;
|
|
41
|
+
defaults?: TreqDefaults;
|
|
42
|
+
cookies?: CookiesConfig;
|
|
43
|
+
resolvers?: Record<string, Resolver | CommandResolverDef>;
|
|
44
|
+
profiles?: Record<string, TreqProfileInput>;
|
|
45
|
+
security?: SecurityConfig;
|
|
46
|
+
};
|
|
47
|
+
export type ResolvedConfig = {
|
|
48
|
+
projectRoot: string;
|
|
49
|
+
variables: Record<string, unknown>;
|
|
50
|
+
defaults: ResolvedDefaults;
|
|
51
|
+
cookies: ResolvedCookiesConfig;
|
|
52
|
+
resolvers: Record<string, Resolver>;
|
|
53
|
+
security: {
|
|
54
|
+
allowExternalFiles: boolean;
|
|
16
55
|
};
|
|
17
56
|
};
|
|
57
|
+
export type ConfigFormat = 'jsonc' | 'json' | 'ts' | 'js' | 'mjs';
|
|
58
|
+
export type ConfigMeta = {
|
|
59
|
+
configPath?: string;
|
|
60
|
+
projectRoot: string;
|
|
61
|
+
format?: ConfigFormat;
|
|
62
|
+
profile?: string;
|
|
63
|
+
layersApplied: string[];
|
|
64
|
+
warnings: string[];
|
|
65
|
+
};
|
|
18
66
|
export type LoadedConfig = {
|
|
19
67
|
path?: string;
|
|
20
|
-
config:
|
|
68
|
+
config: TreqConfigInput;
|
|
69
|
+
format?: ConfigFormat;
|
|
70
|
+
};
|
|
71
|
+
export type ResolvedProjectConfig = {
|
|
72
|
+
config: ResolvedConfig;
|
|
73
|
+
meta: ConfigMeta;
|
|
21
74
|
};
|
|
75
|
+
export type TreqConfig = TreqConfigInput;
|
|
22
76
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { CookieJar } from '../cookies';
|
|
2
|
+
export type CookieJarData = {
|
|
3
|
+
version: number;
|
|
4
|
+
cookies: Array<{
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
domain: string;
|
|
8
|
+
path: string;
|
|
9
|
+
expires?: string;
|
|
10
|
+
secure?: boolean;
|
|
11
|
+
httpOnly?: boolean;
|
|
12
|
+
sameSite?: string;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
export type CookieJarManager = {
|
|
16
|
+
load(): CookieJarData | null;
|
|
17
|
+
save(jar: CookieJar): void;
|
|
18
|
+
withLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Load cookie jar data from a file.
|
|
22
|
+
* Returns null if the file doesn't exist.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadCookieJarData(jarPath: string): CookieJarData | null;
|
|
25
|
+
/**
|
|
26
|
+
* Save cookie jar data to a file.
|
|
27
|
+
* Uses atomic write (write to temp file, then rename).
|
|
28
|
+
*/
|
|
29
|
+
export declare function saveCookieJarData(jarPath: string, data: CookieJarData): void;
|
|
30
|
+
/**
|
|
31
|
+
* Convert CookieJar to serializable data.
|
|
32
|
+
*/
|
|
33
|
+
export declare function cookieJarToData(jar: CookieJar): CookieJarData;
|
|
34
|
+
/**
|
|
35
|
+
* Create a cookie jar manager for a specific jar path.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createCookieJarManager(jarPath: string): CookieJarManager;
|
|
38
|
+
/**
|
|
39
|
+
* Schedule a debounced save of the cookie jar.
|
|
40
|
+
* Multiple saves within the debounce interval will be coalesced.
|
|
41
|
+
*/
|
|
42
|
+
export declare function scheduleCookieJarSave(jarPath: string, jar: CookieJar): void;
|
|
43
|
+
/**
|
|
44
|
+
* Flush all pending debounced saves immediately.
|
|
45
|
+
* Used for graceful shutdown.
|
|
46
|
+
*/
|
|
47
|
+
export declare function flushPendingCookieSaves(): Promise<void>;
|
|
48
|
+
//# sourceMappingURL=persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/cookies/persistence.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,IAAI,aAAa,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAC;AA8BF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAyBvE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CA4B5E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,aAAa,CA8B7D;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAexE;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAsB3E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7D"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{createRequire as R}from"node:module";var U=R(import.meta.url);import{existsSync as $,mkdirSync as V,readFileSync as B,renameSync as F,writeFileSync as N}from"node:fs";import*as Q from"node:path";var Z=new Map;async function A(G,z){let H=Q.resolve(G),q=Z.get(H)??Promise.resolve(),K,W=new Promise((O)=>{K=O}),Y=q.then(()=>W);Z.set(H,Y);try{return await q,await z()}finally{if(K?.(),Z.get(H)===Y)Z.delete(H)}}function _(G){let z=Q.resolve(G);if(!$(z))return null;try{let H=B(z,"utf-8"),q=JSON.parse(H);if(!q||typeof q!=="object")return null;if(!Array.isArray(q.cookies))return null;return q}catch{return null}}function I(G,z){let H=Q.resolve(G),q=Q.dirname(H);if(!$(q))V(q,{recursive:!0});let K=`${H}.tmp.${process.pid}`,W=JSON.stringify(z,null,2);try{N(K,W,"utf-8"),F(K,H)}catch(Y){try{if($(K))U("node:fs").unlinkSync(K)}catch{}throw Y}}function M(G){return{version:1,cookies:(G.toJSON()?.cookies??[]).map((q)=>{let K={key:q.key??"",value:q.value??"",domain:q.domain??"",path:q.path??"/"};if(q.expires)K.expires=q.expires;if(q.secure!==void 0)K.secure=q.secure;if(q.httpOnly!==void 0)K.httpOnly=q.httpOnly;if(q.sameSite)K.sameSite=q.sameSite;return K})}}function b(G){return{load(){return _(G)},save(z){let H=M(z);I(G,H)},async withLock(z){return A(G,z)}}}var g=250,X=new Map;function x(G,z){let H=Q.resolve(G),q=X.get(H);if(q)clearTimeout(q.timer);let K=setTimeout(()=>{X.delete(H),A(G,async()=>{try{let W=M(z);I(G,W)}catch{}return})},g);X.set(H,{timer:K,jarPath:G,jar:z})}async function C(){let G=Array.from(X.values());X.clear();for(let z of G)clearTimeout(z.timer);await Promise.all(G.map(async(z)=>{await A(z.jarPath,async()=>{let H=M(z.jar);I(z.jarPath,H);return})}))}export{x as scheduleCookieJarSave,I as saveCookieJarData,_ as loadCookieJarData,C as flushPendingCookieSaves,b as createCookieJarManager,M as cookieJarToData};
|
|
2
|
+
|
|
3
|
+
//# debugId=667AE437C373448C64756E2164756E21
|
|
4
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cookies/persistence.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport * as path from 'node:path';\nimport type { CookieJar } from '../cookies';\n\nexport type CookieJarData = {\n version: number;\n cookies: Array<{\n key: string;\n value: string;\n domain: string;\n path: string;\n expires?: string;\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: string;\n }>;\n};\n\nexport type CookieJarManager = {\n load(): CookieJarData | null;\n save(jar: CookieJar): void;\n withLock<T>(fn: () => Promise<T>): Promise<T>;\n};\n\nconst locks = new Map<string, Promise<void>>();\n\nasync function withLock<T>(jarPath: string, fn: () => Promise<T>): Promise<T> {\n const resolvedPath = path.resolve(jarPath);\n\n // Promise-chain mutex: each call appends to the tail, ensuring FIFO exclusivity.\n const prev = locks.get(resolvedPath) ?? Promise.resolve();\n\n let release: (() => void) | undefined;\n const current = new Promise<void>((r) => {\n release = r;\n });\n\n const tail = prev.then(() => current);\n locks.set(resolvedPath, tail);\n\n try {\n await prev;\n return await fn();\n } finally {\n release?.();\n // Only delete if nobody queued behind us.\n if (locks.get(resolvedPath) === tail) {\n locks.delete(resolvedPath);\n }\n }\n}\n\n/**\n * Load cookie jar data from a file.\n * Returns null if the file doesn't exist.\n */\nexport function loadCookieJarData(jarPath: string): CookieJarData | null {\n const resolvedPath = path.resolve(jarPath);\n\n if (!existsSync(resolvedPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(resolvedPath, 'utf-8');\n const data = JSON.parse(content) as CookieJarData;\n\n // Validate basic structure\n if (!data || typeof data !== 'object') {\n return null;\n }\n\n if (!Array.isArray(data.cookies)) {\n return null;\n }\n\n return data;\n } catch {\n // Invalid or corrupted file - return null to start fresh\n return null;\n }\n}\n\n/**\n * Save cookie jar data to a file.\n * Uses atomic write (write to temp file, then rename).\n */\nexport function saveCookieJarData(jarPath: string, data: CookieJarData): void {\n const resolvedPath = path.resolve(jarPath);\n\n // Ensure parent directory exists\n const dir = path.dirname(resolvedPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write to temp file first (atomic write)\n const tempPath = `${resolvedPath}.tmp.${process.pid}`;\n const content = JSON.stringify(data, null, 2);\n\n try {\n writeFileSync(tempPath, content, 'utf-8');\n renameSync(tempPath, resolvedPath);\n } catch (err) {\n // Clean up temp file on error\n try {\n if (existsSync(tempPath)) {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n require('node:fs').unlinkSync(tempPath);\n }\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n}\n\n/**\n * Convert CookieJar to serializable data.\n */\nexport function cookieJarToData(jar: CookieJar): CookieJarData {\n const serialized = jar.toJSON();\n const cookies = (serialized?.cookies ?? []) as Array<{\n key?: string;\n value?: string;\n domain?: string;\n path?: string;\n expires?: string;\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: string;\n }>;\n\n return {\n version: 1,\n cookies: cookies.map((c) => {\n const cookie: CookieJarData['cookies'][number] = {\n key: c.key ?? '',\n value: c.value ?? '',\n domain: c.domain ?? '',\n path: c.path ?? '/'\n };\n // Only include optional fields if defined\n if (c.expires) cookie.expires = c.expires;\n if (c.secure !== undefined) cookie.secure = c.secure;\n if (c.httpOnly !== undefined) cookie.httpOnly = c.httpOnly;\n if (c.sameSite) cookie.sameSite = c.sameSite;\n return cookie;\n })\n };\n}\n\n// ============================================================================\n// Cookie Jar Manager\n// ============================================================================\n\n/**\n * Create a cookie jar manager for a specific jar path.\n */\nexport function createCookieJarManager(jarPath: string): CookieJarManager {\n return {\n load(): CookieJarData | null {\n return loadCookieJarData(jarPath);\n },\n\n save(jar: CookieJar): void {\n const data = cookieJarToData(jar);\n saveCookieJarData(jarPath, data);\n },\n\n async withLock<T>(fn: () => Promise<T>): Promise<T> {\n return withLock(jarPath, fn);\n }\n };\n}\n\n// ============================================================================\n// Debounced Save\n// ============================================================================\n\nconst DEBOUNCE_INTERVAL_MS = 250;\n\ntype DebouncedSaveEntry = {\n timer: NodeJS.Timeout;\n jarPath: string;\n jar: CookieJar;\n};\n\nconst debouncedSaveEntries = new Map<string, DebouncedSaveEntry>();\n\n/**\n * Schedule a debounced save of the cookie jar.\n * Multiple saves within the debounce interval will be coalesced.\n */\nexport function scheduleCookieJarSave(jarPath: string, jar: CookieJar): void {\n const resolvedPath = path.resolve(jarPath);\n\n // Clear any existing timer\n const existing = debouncedSaveEntries.get(resolvedPath);\n if (existing) clearTimeout(existing.timer);\n\n // Schedule new save\n const timer = setTimeout(() => {\n debouncedSaveEntries.delete(resolvedPath);\n void withLock(jarPath, async () => {\n try {\n const data = cookieJarToData(jar);\n saveCookieJarData(jarPath, data);\n } catch {\n // Ignore save errors in debounced context\n }\n return;\n });\n }, DEBOUNCE_INTERVAL_MS);\n\n debouncedSaveEntries.set(resolvedPath, { timer, jarPath, jar });\n}\n\n/**\n * Flush all pending debounced saves immediately.\n * Used for graceful shutdown.\n */\nexport async function flushPendingCookieSaves(): Promise<void> {\n const entries = Array.from(debouncedSaveEntries.values());\n debouncedSaveEntries.clear();\n\n for (const entry of entries) {\n clearTimeout(entry.timer);\n }\n\n // Best-effort flush (keep going even if one fails).\n await Promise.all(\n entries.map(async (entry) => {\n await withLock(entry.jarPath, async () => {\n const data = cookieJarToData(entry.jar);\n saveCookieJarData(entry.jarPath, data);\n return;\n });\n })\n );\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "667AE437C373448C64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|