@readme/httpsnippet 7.0.1 → 7.0.2
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/dist/chunk-BCCGHMCJ.mjs +18 -0
- package/dist/chunk-BCCGHMCJ.mjs.map +1 -0
- package/dist/chunk-UEOS42PC.mjs +63 -0
- package/dist/chunk-UEOS42PC.mjs.map +1 -0
- package/dist/{chunk-XPUGYZ4Y.mjs → chunk-WJGIOTIP.mjs} +2 -61
- package/dist/chunk-WJGIOTIP.mjs.map +1 -0
- package/dist/helpers/code-builder.d.mts +51 -0
- package/dist/helpers/code-builder.d.ts +51 -0
- package/dist/helpers/code-builder.js +65 -0
- package/dist/helpers/code-builder.js.map +1 -0
- package/dist/helpers/code-builder.mjs +3 -0
- package/dist/helpers/code-builder.mjs.map +1 -0
- package/dist/helpers/reducer.d.mts +7 -0
- package/dist/helpers/reducer.d.ts +7 -0
- package/dist/helpers/reducer.js +20 -0
- package/dist/helpers/reducer.js.map +1 -0
- package/dist/helpers/reducer.mjs +3 -0
- package/dist/helpers/reducer.mjs.map +1 -0
- package/dist/{index-acc66e3d.d.ts → index-27be831e.d.ts} +2 -15
- package/dist/index-e612cd58.d.ts +154 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +4 -17
- package/dist/index.mjs.map +1 -1
- package/dist/targets/targets.d.mts +3 -1
- package/dist/targets/targets.d.ts +3 -1
- package/dist/targets/targets.mjs +2 -1
- package/package.json +1 -1
- package/dist/chunk-XPUGYZ4Y.mjs.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type PostProcessor = (unreplacedCode: string) => string;
|
|
2
|
+
interface CodeBuilderOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Desired indentation character for aggregated lines of code
|
|
5
|
+
* @default ''
|
|
6
|
+
*/
|
|
7
|
+
indent?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Desired character to join each line of code
|
|
10
|
+
* @default \n
|
|
11
|
+
*/
|
|
12
|
+
join?: string;
|
|
13
|
+
}
|
|
14
|
+
declare class CodeBuilder {
|
|
15
|
+
postProcessors: PostProcessor[];
|
|
16
|
+
code: string[];
|
|
17
|
+
indentationCharacter: string;
|
|
18
|
+
lineJoin: string;
|
|
19
|
+
/**
|
|
20
|
+
* Helper object to format and aggragate lines of code.
|
|
21
|
+
* Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet.
|
|
22
|
+
*/
|
|
23
|
+
constructor({ indent, join }?: CodeBuilderOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Add given indentation level to given line of code
|
|
26
|
+
*/
|
|
27
|
+
indentLine: (line: string, indentationLevel?: number) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Add the line at the beginning of the current lines
|
|
30
|
+
*/
|
|
31
|
+
unshift: (line: string, indentationLevel?: number) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Add the line at the end of the current lines
|
|
34
|
+
*/
|
|
35
|
+
push: (line: string, indentationLevel?: number) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Add an empty line at the end of current lines
|
|
38
|
+
*/
|
|
39
|
+
blank: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added
|
|
42
|
+
*/
|
|
43
|
+
join: () => string;
|
|
44
|
+
/**
|
|
45
|
+
* Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step.
|
|
46
|
+
* To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on.
|
|
47
|
+
*/
|
|
48
|
+
addPostProcessor: (postProcessor: PostProcessor) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { CodeBuilder, CodeBuilderOptions, PostProcessor };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type PostProcessor = (unreplacedCode: string) => string;
|
|
2
|
+
interface CodeBuilderOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Desired indentation character for aggregated lines of code
|
|
5
|
+
* @default ''
|
|
6
|
+
*/
|
|
7
|
+
indent?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Desired character to join each line of code
|
|
10
|
+
* @default \n
|
|
11
|
+
*/
|
|
12
|
+
join?: string;
|
|
13
|
+
}
|
|
14
|
+
declare class CodeBuilder {
|
|
15
|
+
postProcessors: PostProcessor[];
|
|
16
|
+
code: string[];
|
|
17
|
+
indentationCharacter: string;
|
|
18
|
+
lineJoin: string;
|
|
19
|
+
/**
|
|
20
|
+
* Helper object to format and aggragate lines of code.
|
|
21
|
+
* Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet.
|
|
22
|
+
*/
|
|
23
|
+
constructor({ indent, join }?: CodeBuilderOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Add given indentation level to given line of code
|
|
26
|
+
*/
|
|
27
|
+
indentLine: (line: string, indentationLevel?: number) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Add the line at the beginning of the current lines
|
|
30
|
+
*/
|
|
31
|
+
unshift: (line: string, indentationLevel?: number) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Add the line at the end of the current lines
|
|
34
|
+
*/
|
|
35
|
+
push: (line: string, indentationLevel?: number) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Add an empty line at the end of current lines
|
|
38
|
+
*/
|
|
39
|
+
blank: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added
|
|
42
|
+
*/
|
|
43
|
+
join: () => string;
|
|
44
|
+
/**
|
|
45
|
+
* Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step.
|
|
46
|
+
* To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on.
|
|
47
|
+
*/
|
|
48
|
+
addPostProcessor: (postProcessor: PostProcessor) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { CodeBuilder, CodeBuilderOptions, PostProcessor };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/helpers/code-builder.ts
|
|
4
|
+
var DEFAULT_INDENTATION_CHARACTER = "";
|
|
5
|
+
var DEFAULT_LINE_JOIN = "\n";
|
|
6
|
+
var CodeBuilder = class {
|
|
7
|
+
/**
|
|
8
|
+
* Helper object to format and aggragate lines of code.
|
|
9
|
+
* Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet.
|
|
10
|
+
*/
|
|
11
|
+
constructor({ indent, join } = {}) {
|
|
12
|
+
this.postProcessors = [];
|
|
13
|
+
this.code = [];
|
|
14
|
+
this.indentationCharacter = DEFAULT_INDENTATION_CHARACTER;
|
|
15
|
+
this.lineJoin = DEFAULT_LINE_JOIN;
|
|
16
|
+
/**
|
|
17
|
+
* Add given indentation level to given line of code
|
|
18
|
+
*/
|
|
19
|
+
this.indentLine = (line, indentationLevel = 0) => {
|
|
20
|
+
const indent = this.indentationCharacter.repeat(indentationLevel);
|
|
21
|
+
return `${indent}${line}`;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Add the line at the beginning of the current lines
|
|
25
|
+
*/
|
|
26
|
+
this.unshift = (line, indentationLevel) => {
|
|
27
|
+
const newLine = this.indentLine(line, indentationLevel);
|
|
28
|
+
this.code.unshift(newLine);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Add the line at the end of the current lines
|
|
32
|
+
*/
|
|
33
|
+
this.push = (line, indentationLevel) => {
|
|
34
|
+
const newLine = this.indentLine(line, indentationLevel);
|
|
35
|
+
this.code.push(newLine);
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Add an empty line at the end of current lines
|
|
39
|
+
*/
|
|
40
|
+
this.blank = () => {
|
|
41
|
+
this.code.push("");
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added
|
|
45
|
+
*/
|
|
46
|
+
this.join = () => {
|
|
47
|
+
const unreplacedCode = this.code.join(this.lineJoin);
|
|
48
|
+
const replacedOutput = this.postProcessors.reduce((accumulator, replacer) => replacer(accumulator), unreplacedCode);
|
|
49
|
+
return replacedOutput;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step.
|
|
53
|
+
* To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on.
|
|
54
|
+
*/
|
|
55
|
+
this.addPostProcessor = (postProcessor) => {
|
|
56
|
+
this.postProcessors = [...this.postProcessors, postProcessor];
|
|
57
|
+
};
|
|
58
|
+
this.indentationCharacter = indent || DEFAULT_INDENTATION_CHARACTER;
|
|
59
|
+
this.lineJoin = join ?? DEFAULT_LINE_JOIN;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.CodeBuilder = CodeBuilder;
|
|
64
|
+
//# sourceMappingURL=out.js.map
|
|
65
|
+
//# sourceMappingURL=code-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/code-builder.ts"],"names":[],"mappings":";AAAA,IAAM,gCAAgC;AACtC,IAAM,oBAAoB;AAkBnB,IAAM,cAAN,MAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAavB,YAAY,EAAE,QAAQ,KAAK,IAAwB,CAAC,GAAG;AAZvD,0BAAkC,CAAC;AAEnC,gBAAiB,CAAC;AAElB,gCAA+B;AAE/B,oBAAW;AAcX;AAAA;AAAA;AAAA,sBAAa,CAAC,MAAc,mBAAmB,MAAM;AACnD,YAAM,SAAS,KAAK,qBAAqB,OAAO,gBAAgB;AAChE,aAAO,GAAG,MAAM,GAAG,IAAI;AAAA,IACzB;AAKA;AAAA;AAAA;AAAA,mBAAU,CAAC,MAAc,qBAA8B;AACrD,YAAM,UAAU,KAAK,WAAW,MAAM,gBAAgB;AACtD,WAAK,KAAK,QAAQ,OAAO;AAAA,IAC3B;AAKA;AAAA;AAAA;AAAA,gBAAO,CAAC,MAAc,qBAA8B;AAClD,YAAM,UAAU,KAAK,WAAW,MAAM,gBAAgB;AACtD,WAAK,KAAK,KAAK,OAAO;AAAA,IACxB;AAKA;AAAA;AAAA;AAAA,iBAAQ,MAAM;AACZ,WAAK,KAAK,KAAK,EAAE;AAAA,IACnB;AAKA;AAAA;AAAA;AAAA,gBAAO,MAAM;AACX,YAAM,iBAAiB,KAAK,KAAK,KAAK,KAAK,QAAQ;AACnD,YAAM,iBAAiB,KAAK,eAAe,OAAO,CAAC,aAAa,aAAa,SAAS,WAAW,GAAG,cAAc;AAClH,aAAO;AAAA,IACT;AAMA;AAAA;AAAA;AAAA;AAAA,4BAAmB,CAAC,kBAAiC;AACnD,WAAK,iBAAiB,CAAC,GAAG,KAAK,gBAAgB,aAAa;AAAA,IAC9D;AAlDE,SAAK,uBAAuB,UAAU;AACtC,SAAK,WAAW,QAAQ;AAAA,EAC1B;AAiDF","sourcesContent":["const DEFAULT_INDENTATION_CHARACTER = '';\nconst DEFAULT_LINE_JOIN = '\\n';\n\nexport type PostProcessor = (unreplacedCode: string) => string;\n\nexport interface CodeBuilderOptions {\n /**\n * Desired indentation character for aggregated lines of code\n * @default ''\n */\n indent?: string;\n\n /**\n * Desired character to join each line of code\n * @default \\n\n */\n join?: string;\n}\n\nexport class CodeBuilder {\n postProcessors: PostProcessor[] = [];\n\n code: string[] = [];\n\n indentationCharacter: string = DEFAULT_INDENTATION_CHARACTER;\n\n lineJoin = DEFAULT_LINE_JOIN;\n\n /**\n * Helper object to format and aggragate lines of code.\n * Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet.\n */\n constructor({ indent, join }: CodeBuilderOptions = {}) {\n this.indentationCharacter = indent || DEFAULT_INDENTATION_CHARACTER;\n this.lineJoin = join ?? DEFAULT_LINE_JOIN;\n }\n\n /**\n * Add given indentation level to given line of code\n */\n indentLine = (line: string, indentationLevel = 0) => {\n const indent = this.indentationCharacter.repeat(indentationLevel);\n return `${indent}${line}`;\n };\n\n /**\n * Add the line at the beginning of the current lines\n */\n unshift = (line: string, indentationLevel?: number) => {\n const newLine = this.indentLine(line, indentationLevel);\n this.code.unshift(newLine);\n };\n\n /**\n * Add the line at the end of the current lines\n */\n push = (line: string, indentationLevel?: number) => {\n const newLine = this.indentLine(line, indentationLevel);\n this.code.push(newLine);\n };\n\n /**\n * Add an empty line at the end of current lines\n */\n blank = () => {\n this.code.push('');\n };\n\n /**\n * Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added\n */\n join = () => {\n const unreplacedCode = this.code.join(this.lineJoin);\n const replacedOutput = this.postProcessors.reduce((accumulator, replacer) => replacer(accumulator), unreplacedCode);\n return replacedOutput;\n };\n\n /**\n * Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step.\n * To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on.\n */\n addPostProcessor = (postProcessor: PostProcessor) => {\n this.postProcessors = [...this.postProcessors, postProcessor];\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/helpers/reducer.ts
|
|
4
|
+
var reducer = (accumulator, pair) => {
|
|
5
|
+
const currentValue = accumulator[pair.name];
|
|
6
|
+
if (currentValue === void 0) {
|
|
7
|
+
accumulator[pair.name] = pair.value;
|
|
8
|
+
return accumulator;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(currentValue)) {
|
|
11
|
+
currentValue.push(pair.value);
|
|
12
|
+
return accumulator;
|
|
13
|
+
}
|
|
14
|
+
accumulator[pair.name] = [currentValue, pair.value];
|
|
15
|
+
return accumulator;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.reducer = reducer;
|
|
19
|
+
//# sourceMappingURL=out.js.map
|
|
20
|
+
//# sourceMappingURL=reducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/reducer.ts"],"names":[],"mappings":";AAEO,IAAM,UAAU,CAA4C,aAAkC,SAAY;AAC/G,QAAM,eAAe,YAAY,KAAK,IAAI;AAC1C,MAAI,iBAAiB,QAAW;AAC9B,gBAAY,KAAK,IAAI,IAAI,KAAK;AAC9B,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,QAAQ,YAAY,GAAG;AAC/B,iBAAa,KAAK,KAAK,KAAK;AAC5B,WAAO;AAAA,EACT;AAGA,cAAY,KAAK,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK;AAClD,SAAO;AACT","sourcesContent":["export type ReducedHelperObject = Record<string, string[] | string>;\n\nexport const reducer = <T extends { name: string; value: string }>(accumulator: ReducedHelperObject, pair: T) => {\n const currentValue = accumulator[pair.name];\n if (currentValue === undefined) {\n accumulator[pair.name] = pair.value;\n return accumulator;\n }\n\n // If we already have it as array just push the value\n if (Array.isArray(currentValue)) {\n currentValue.push(pair.value);\n return accumulator;\n }\n\n // convert to array since now we have more than one value for this key\n accumulator[pair.name] = [currentValue, pair.value];\n return accumulator;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
import * as har_format from 'har-format';
|
|
2
2
|
import { Request as Request$1, PostDataCommon, Param } from 'har-format';
|
|
3
|
+
import { ReducedHelperObject } from './helpers/reducer.mjs';
|
|
3
4
|
import { UrlWithParsedQuery } from 'node:url';
|
|
5
|
+
import { CodeBuilderOptions } from './helpers/code-builder.mjs';
|
|
4
6
|
import { Merge } from 'type-fest';
|
|
5
7
|
|
|
6
|
-
type ReducedHelperObject = Record<string, string[] | string>;
|
|
7
|
-
|
|
8
|
-
interface CodeBuilderOptions {
|
|
9
|
-
/**
|
|
10
|
-
* Desired indentation character for aggregated lines of code
|
|
11
|
-
* @default ''
|
|
12
|
-
*/
|
|
13
|
-
indent?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Desired character to join each line of code
|
|
16
|
-
* @default \n
|
|
17
|
-
*/
|
|
18
|
-
join?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
8
|
type TargetId = keyof typeof targets;
|
|
22
9
|
type ClientId = string;
|
|
23
10
|
interface ClientInfo {
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import * as har_format from 'har-format';
|
|
2
|
+
import { Request as Request$1, PostDataCommon, Param } from 'har-format';
|
|
3
|
+
import { ReducedHelperObject } from './helpers/reducer.js';
|
|
4
|
+
import { UrlWithParsedQuery } from 'node:url';
|
|
5
|
+
import { CodeBuilderOptions } from './helpers/code-builder.js';
|
|
6
|
+
import { Merge } from 'type-fest';
|
|
7
|
+
|
|
8
|
+
type TargetId = keyof typeof targets;
|
|
9
|
+
type ClientId = string;
|
|
10
|
+
interface ClientInfo {
|
|
11
|
+
description: string;
|
|
12
|
+
key: ClientId;
|
|
13
|
+
link: string;
|
|
14
|
+
title: string;
|
|
15
|
+
}
|
|
16
|
+
type Converter<T extends Record<string, any>> = (request: Request, options?: Merge<CodeBuilderOptions, T>) => string;
|
|
17
|
+
interface Client<T extends Record<string, any> = Record<string, any>> {
|
|
18
|
+
convert: Converter<T>;
|
|
19
|
+
info: ClientInfo;
|
|
20
|
+
}
|
|
21
|
+
type Extension = `.${string}` | null;
|
|
22
|
+
interface TargetInfo {
|
|
23
|
+
cli?: string;
|
|
24
|
+
default: string;
|
|
25
|
+
extname: Extension;
|
|
26
|
+
key: TargetId;
|
|
27
|
+
title: string;
|
|
28
|
+
}
|
|
29
|
+
interface Target {
|
|
30
|
+
clientsById: Record<ClientId, Client>;
|
|
31
|
+
info: TargetInfo;
|
|
32
|
+
}
|
|
33
|
+
declare const targets: {
|
|
34
|
+
c: Target;
|
|
35
|
+
clojure: Target;
|
|
36
|
+
csharp: Target;
|
|
37
|
+
go: Target;
|
|
38
|
+
http: Target;
|
|
39
|
+
java: Target;
|
|
40
|
+
javascript: Target;
|
|
41
|
+
json: Target;
|
|
42
|
+
kotlin: Target;
|
|
43
|
+
node: Target;
|
|
44
|
+
objc: Target;
|
|
45
|
+
ocaml: Target;
|
|
46
|
+
php: Target;
|
|
47
|
+
powershell: Target;
|
|
48
|
+
python: Target;
|
|
49
|
+
r: Target;
|
|
50
|
+
ruby: Target;
|
|
51
|
+
shell: Target;
|
|
52
|
+
swift: Target;
|
|
53
|
+
};
|
|
54
|
+
declare const isTarget: (target: Target) => target is Target;
|
|
55
|
+
declare const addTarget: (target: Target) => void;
|
|
56
|
+
declare const isClient: (client: Client) => client is Client<Record<string, any>>;
|
|
57
|
+
declare const addTargetClient: (targetId: TargetId, client: Client) => void;
|
|
58
|
+
|
|
59
|
+
interface AvailableTarget extends TargetInfo {
|
|
60
|
+
clients: ClientInfo[];
|
|
61
|
+
}
|
|
62
|
+
declare const availableTargets: () => AvailableTarget[];
|
|
63
|
+
declare const extname: (targetId: TargetId) => "" | `.${string}`;
|
|
64
|
+
|
|
65
|
+
/** is this wrong? yes. according to the spec (http://www.softwareishard.com/blog/har-12-spec/#postData) it's technically wrong since `params` and `text` are (by the spec) mutually exclusive. However, in practice, this is not what is often the case.
|
|
66
|
+
*
|
|
67
|
+
* In general, this library takes a _descriptive_ rather than _perscriptive_ approach (see https://amyrey.web.unc.edu/classes/ling-101-online/tutorials/understanding-prescriptive-vs-descriptive-grammar/).
|
|
68
|
+
*
|
|
69
|
+
* Then, in addition to that, it really adds to complexity with TypeScript (TypeScript takes this constraint very very seriously) in a way that's not actually super useful. So, we treat this object as though it could have both or either of `params` and/or `text`.
|
|
70
|
+
*/
|
|
71
|
+
type PostDataBase = PostDataCommon & {
|
|
72
|
+
params?: Param[];
|
|
73
|
+
text?: string;
|
|
74
|
+
};
|
|
75
|
+
type HarRequest = Omit<Request$1, 'postData'> & {
|
|
76
|
+
postData: PostDataBase;
|
|
77
|
+
};
|
|
78
|
+
interface RequestExtras {
|
|
79
|
+
allHeaders: ReducedHelperObject;
|
|
80
|
+
cookiesObj: ReducedHelperObject;
|
|
81
|
+
fullUrl: string;
|
|
82
|
+
headersObj: ReducedHelperObject;
|
|
83
|
+
postData: PostDataBase & {
|
|
84
|
+
boundary?: string;
|
|
85
|
+
jsonObj?: ReducedHelperObject;
|
|
86
|
+
paramsObj?: ReducedHelperObject;
|
|
87
|
+
};
|
|
88
|
+
queryObj: ReducedHelperObject;
|
|
89
|
+
uriObj: UrlWithParsedQuery;
|
|
90
|
+
}
|
|
91
|
+
type Request = HarRequest & RequestExtras;
|
|
92
|
+
interface Entry {
|
|
93
|
+
request: Partial<HarRequest>;
|
|
94
|
+
}
|
|
95
|
+
interface HarEntry {
|
|
96
|
+
log: {
|
|
97
|
+
creator: {
|
|
98
|
+
name: string;
|
|
99
|
+
version: string;
|
|
100
|
+
};
|
|
101
|
+
entries: Entry[];
|
|
102
|
+
version: string;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
interface HTTPSnippetOptions {
|
|
106
|
+
harIsAlreadyEncoded?: boolean;
|
|
107
|
+
}
|
|
108
|
+
declare class HTTPSnippet {
|
|
109
|
+
requests: Request[];
|
|
110
|
+
constructor(input: HarEntry | HarRequest, opts?: HTTPSnippetOptions);
|
|
111
|
+
prepare: (harRequest: HarRequest, options: HTTPSnippetOptions) => {
|
|
112
|
+
allHeaders: {
|
|
113
|
+
[x: string]: string | string[];
|
|
114
|
+
};
|
|
115
|
+
fullUrl: string;
|
|
116
|
+
url: string;
|
|
117
|
+
uriObj: {
|
|
118
|
+
query: ReducedHelperObject;
|
|
119
|
+
search: string;
|
|
120
|
+
path: string | null;
|
|
121
|
+
auth: string | null;
|
|
122
|
+
hash: string | null;
|
|
123
|
+
host: string | null;
|
|
124
|
+
hostname: string | null;
|
|
125
|
+
href: string;
|
|
126
|
+
pathname: string | null;
|
|
127
|
+
protocol: string | null;
|
|
128
|
+
slashes: boolean | null;
|
|
129
|
+
port: string | null;
|
|
130
|
+
};
|
|
131
|
+
method: string;
|
|
132
|
+
httpVersion: string;
|
|
133
|
+
cookies: har_format.Cookie[];
|
|
134
|
+
headers: har_format.Header[];
|
|
135
|
+
queryString: har_format.QueryString[];
|
|
136
|
+
headersSize: number;
|
|
137
|
+
bodySize: number;
|
|
138
|
+
comment?: string | undefined;
|
|
139
|
+
postData: PostDataCommon & {
|
|
140
|
+
params?: Param[] | undefined;
|
|
141
|
+
text?: string | undefined;
|
|
142
|
+
} & {
|
|
143
|
+
boundary?: string | undefined;
|
|
144
|
+
jsonObj?: ReducedHelperObject | undefined;
|
|
145
|
+
paramsObj?: ReducedHelperObject | undefined;
|
|
146
|
+
};
|
|
147
|
+
cookiesObj: ReducedHelperObject;
|
|
148
|
+
headersObj: ReducedHelperObject;
|
|
149
|
+
queryObj: ReducedHelperObject;
|
|
150
|
+
};
|
|
151
|
+
convert: (targetId: TargetId, clientId?: ClientId, options?: any) => string | false | string[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { ClientId as C, Extension as E, HarRequest as H, RequestExtras as R, TargetId as T, ClientInfo as a, Converter as b, Client as c, TargetInfo as d, Target as e, addTarget as f, isClient as g, addTargetClient as h, isTarget as i, Request as j, HTTPSnippetOptions as k, HTTPSnippet as l, availableTargets as m, extname as n, targets as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import 'har-format';
|
|
2
|
-
|
|
2
|
+
import './helpers/reducer.mjs';
|
|
3
|
+
export { l as HTTPSnippet, k as HTTPSnippetOptions, H as HarRequest, j as Request, R as RequestExtras, f as addTarget, h as addTargetClient, m as availableTargets, n as extname } from './index-27be831e.js';
|
|
3
4
|
import 'node:url';
|
|
5
|
+
import './helpers/code-builder.mjs';
|
|
4
6
|
import 'type-fest';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import 'har-format';
|
|
2
|
-
|
|
2
|
+
import './helpers/reducer.js';
|
|
3
|
+
export { l as HTTPSnippet, k as HTTPSnippetOptions, H as HarRequest, j as Request, R as RequestExtras, f as addTarget, h as addTargetClient, m as availableTargets, n as extname } from './index-e612cd58.js';
|
|
3
4
|
import 'node:url';
|
|
5
|
+
import './helpers/code-builder.js';
|
|
4
6
|
import 'type-fest';
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { reducer } from './chunk-BCCGHMCJ.mjs';
|
|
2
|
+
import { targets, getHeaderName } from './chunk-WJGIOTIP.mjs';
|
|
3
|
+
export { addTarget, addTargetClient } from './chunk-WJGIOTIP.mjs';
|
|
4
|
+
import './chunk-UEOS42PC.mjs';
|
|
3
5
|
import { parse, format } from 'url';
|
|
4
6
|
import { map } from 'event-stream';
|
|
5
7
|
import FormData from 'form-data';
|
|
@@ -34,21 +36,6 @@ var formDataIterator = function* (form, boundary) {
|
|
|
34
36
|
yield getFooter(boundary);
|
|
35
37
|
};
|
|
36
38
|
|
|
37
|
-
// src/helpers/reducer.ts
|
|
38
|
-
var reducer = (accumulator, pair) => {
|
|
39
|
-
const currentValue = accumulator[pair.name];
|
|
40
|
-
if (currentValue === void 0) {
|
|
41
|
-
accumulator[pair.name] = pair.value;
|
|
42
|
-
return accumulator;
|
|
43
|
-
}
|
|
44
|
-
if (Array.isArray(currentValue)) {
|
|
45
|
-
currentValue.push(pair.value);
|
|
46
|
-
return accumulator;
|
|
47
|
-
}
|
|
48
|
-
accumulator[pair.name] = [currentValue, pair.value];
|
|
49
|
-
return accumulator;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
39
|
// src/helpers/utils.ts
|
|
53
40
|
var availableTargets = () => Object.keys(targets).map((targetId) => ({
|
|
54
41
|
...targets[targetId].info,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/helpers/form-data.ts","../src/helpers/reducer.ts","../src/helpers/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReducedHelperObject } from './helpers/reducer';\nimport type { ClientId, TargetId } from './targets/targets';\nimport type { Param, PostDataCommon, Request as NpmHarRequest } from 'har-format';\nimport type { UrlWithParsedQuery } from 'node:url';\n\nimport { format as urlFormat, parse as urlParse } from 'node:url';\n\nimport { map as eventStreamMap } from 'event-stream';\nimport FormData from 'form-data';\nimport { stringify as queryStringify } from 'qs';\n\nimport { formDataIterator, isBlob } from './helpers/form-data';\nimport { getHeaderName } from './helpers/headers';\nimport { reducer } from './helpers/reducer';\nimport { targets } from './targets/targets';\n\nexport { availableTargets, extname } from './helpers/utils';\nexport { addTarget, addTargetClient } from './targets/targets';\n\n/** is this wrong? yes. according to the spec (http://www.softwareishard.com/blog/har-12-spec/#postData) it's technically wrong since `params` and `text` are (by the spec) mutually exclusive. However, in practice, this is not what is often the case.\n *\n * In general, this library takes a _descriptive_ rather than _perscriptive_ approach (see https://amyrey.web.unc.edu/classes/ling-101-online/tutorials/understanding-prescriptive-vs-descriptive-grammar/).\n *\n * Then, in addition to that, it really adds to complexity with TypeScript (TypeScript takes this constraint very very seriously) in a way that's not actually super useful. So, we treat this object as though it could have both or either of `params` and/or `text`.\n */\ntype PostDataBase = PostDataCommon & {\n params?: Param[];\n text?: string;\n};\n\nexport type HarRequest = Omit<NpmHarRequest, 'postData'> & { postData: PostDataBase };\n\nexport interface RequestExtras {\n allHeaders: ReducedHelperObject;\n cookiesObj: ReducedHelperObject;\n fullUrl: string;\n headersObj: ReducedHelperObject;\n postData: PostDataBase & {\n boundary?: string;\n jsonObj?: ReducedHelperObject;\n paramsObj?: ReducedHelperObject;\n };\n queryObj: ReducedHelperObject;\n uriObj: UrlWithParsedQuery;\n}\n\nexport type Request = HarRequest & RequestExtras;\n\ninterface Entry {\n request: Partial<HarRequest>;\n}\n\ninterface HarEntry {\n log: {\n creator: {\n name: string;\n version: string;\n };\n entries: Entry[];\n version: string;\n };\n}\n\nexport interface HTTPSnippetOptions {\n harIsAlreadyEncoded?: boolean;\n}\n\nconst isHarEntry = (value: any): value is HarEntry =>\n typeof value === 'object' &&\n 'log' in value &&\n typeof value.log === 'object' &&\n 'entries' in value.log &&\n Array.isArray(value.log.entries);\n\nexport class HTTPSnippet {\n requests: Request[] = [];\n\n constructor(input: HarEntry | HarRequest, opts: HTTPSnippetOptions = {}) {\n let entries: Entry[] = [];\n\n const options = {\n harIsAlreadyEncoded: false,\n ...opts,\n };\n\n // prep the main container\n this.requests = [];\n\n // is it har?\n if (isHarEntry(input)) {\n entries = input.log.entries;\n } else {\n entries = [\n {\n request: input,\n },\n ];\n }\n\n entries.forEach(({ request }) => {\n // add optional properties to make validation successful\n const req = {\n bodySize: 0,\n headersSize: 0,\n headers: [],\n cookies: [],\n httpVersion: 'HTTP/1.1',\n queryString: [],\n postData: {\n mimeType: request.postData?.mimeType || 'application/octet-stream',\n },\n ...request,\n };\n\n // Per the HAR spec `mimeType` needs to always be present if we have a `postData` object.\n if (req.postData && !req.postData.mimeType) {\n req.postData.mimeType = 'application/octet-stream';\n }\n\n this.requests.push(this.prepare(req as HarRequest, options));\n });\n }\n\n prepare = (harRequest: HarRequest, options: HTTPSnippetOptions) => {\n const request: Request = {\n ...harRequest,\n fullUrl: '',\n uriObj: {} as UrlWithParsedQuery,\n queryObj: {},\n headersObj: {},\n cookiesObj: {},\n allHeaders: {},\n };\n\n // construct query objects\n if (request.queryString && request.queryString.length) {\n request.queryObj = request.queryString.reduce(reducer, {});\n }\n\n // construct headers objects\n if (request.headers && request.headers.length) {\n const http2VersionRegex = /^HTTP\\/2/;\n request.headersObj = request.headers.reduce((accumulator, { name, value }) => {\n const headerName = http2VersionRegex.exec(request.httpVersion) ? name.toLocaleLowerCase() : name;\n return {\n ...accumulator,\n [headerName]: value,\n };\n }, {});\n }\n\n // construct headers objects\n if (request.cookies && request.cookies.length) {\n request.cookiesObj = request.cookies.reduceRight(\n (accumulator, { name, value }) => ({\n ...accumulator,\n [name]: value,\n }),\n {},\n );\n }\n\n // construct Cookie header\n const cookies = request.cookies?.map(({ name, value }) => {\n if (options.harIsAlreadyEncoded) {\n return `${name}=${value}`;\n }\n\n return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n });\n\n if (cookies?.length) {\n request.allHeaders.cookie = cookies.join('; ');\n }\n\n switch (request.postData.mimeType) {\n case 'multipart/mixed':\n case 'multipart/related':\n case 'multipart/form-data':\n case 'multipart/alternative':\n // reset values\n request.postData.text = '';\n request.postData.mimeType = 'multipart/form-data';\n\n if (request.postData?.params) {\n const form = new FormData();\n\n // The `form-data` module returns one of two things: a native FormData object, or its own polyfill\n // Since the polyfill does not support the full API of the native FormData object, when this library is running in a browser environment it'll fail on two things:\n //\n // 1. The API for `form.append()` has three arguments and the third should only be present when the second is a\n // Blob or USVString.\n // 1. `FormData.pipe()` isn't a function.\n //\n // Since the native FormData object is iterable, we easily detect what version of `form-data` we're working with here to allow `multipart/form-data` requests to be compiled under both browser and Node environments.\n //\n // This hack is pretty awful but it's the only way we can use this library in the browser as if we code this against just the native FormData object, we can't polyfill that back into Node because Blob and File objects, which something like `formdata-polyfill` requires, don't exist there.\n // @ts-expect-error TODO\n const isNativeFormData = typeof form[Symbol.iterator] === 'function';\n\n // TODO: THIS ABSOLUTELY MUST BE REMOVED.\n // IT BREAKS SOME USE-CASES FOR MULTIPART FORMS THAT DEPEND ON BEING ABLE TO SET THE BOUNDARY.\n // easter egg\n const boundary = '---011000010111000001101001'; // this is binary for \"api\". yep.\n if (!isNativeFormData) {\n // @ts-expect-error THIS IS WRONG. VERY WRONG.\n form._boundary = boundary;\n }\n\n request.postData?.params.forEach(param => {\n const name = param.name;\n const value = param.value || '';\n const filename = param.fileName || null;\n\n if (isNativeFormData) {\n if (isBlob(value)) {\n // @ts-expect-error TODO\n form.append(name, value, filename);\n } else {\n form.append(name, value);\n }\n } else {\n form.append(name, value, {\n // @ts-expect-error TODO\n filename,\n // @ts-expect-error TODO\n contentType: param.contentType || null,\n });\n }\n });\n\n if (isNativeFormData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const data of formDataIterator(form, boundary)) {\n request.postData.text += data;\n }\n } else {\n form.pipe(\n // @ts-expect-error TODO\n eventStreamMap(data => {\n request.postData.text += data;\n }),\n );\n }\n\n request.postData.boundary = boundary;\n\n // Since headers are case-sensitive we need to see if there's an existing `Content-Type` header that we can override.\n const contentTypeHeader = getHeaderName(request.headersObj, 'content-type') || 'content-type';\n\n request.headersObj[contentTypeHeader] = `multipart/form-data; boundary=${boundary}`;\n }\n break;\n\n case 'application/x-www-form-urlencoded':\n if (!request.postData.params) {\n request.postData.text = '';\n } else {\n // @ts-expect-error the `har-format` types make this challenging\n request.postData.paramsObj = request.postData.params.reduce(reducer, {});\n\n // always overwrite\n request.postData.text = queryStringify(request.postData.paramsObj);\n }\n break;\n\n case 'text/json':\n case 'text/x-json':\n case 'application/json':\n case 'application/x-json':\n request.postData.mimeType = 'application/json';\n\n if (request.postData.text) {\n try {\n request.postData.jsonObj = JSON.parse(request.postData.text);\n } catch (e) {\n // force back to `text/plain` if headers have proper content-type value, then this should also work\n request.postData.mimeType = 'text/plain';\n }\n }\n break;\n }\n\n // create allHeaders object\n const allHeaders = {\n ...request.allHeaders,\n ...request.headersObj,\n };\n\n const urlWithParsedQuery = urlParse(request.url, true, true); //?\n\n // query string key/value pairs in with literal querystrings containd within the url\n request.queryObj = {\n ...request.queryObj,\n ...(urlWithParsedQuery.query as ReducedHelperObject),\n }; //?\n\n // reset uriObj values for a clean url\n let search;\n if (options.harIsAlreadyEncoded) {\n search = queryStringify(request.queryObj, {\n encode: false,\n indices: false,\n });\n } else {\n search = queryStringify(request.queryObj, {\n indices: false,\n });\n }\n\n const uriObj = {\n ...urlWithParsedQuery,\n query: request.queryObj,\n search,\n path: search ? `${urlWithParsedQuery.pathname}?${search}` : urlWithParsedQuery.pathname,\n };\n\n // keep the base url clean of queryString\n const url = urlFormat({\n ...urlWithParsedQuery,\n query: null,\n search: null,\n }); //?\n\n const fullUrl = urlFormat({\n ...urlWithParsedQuery,\n ...uriObj,\n }); //?\n\n return {\n ...request,\n allHeaders,\n fullUrl,\n url,\n uriObj,\n };\n };\n\n convert = (targetId: TargetId, clientId?: ClientId, options?: any) => {\n if (!options && clientId) {\n options = clientId;\n }\n\n const target = targets[targetId];\n if (!target) {\n return false;\n }\n\n const { convert } = target.clientsById[clientId || target.info.default];\n const results = this.requests.map(request => convert(request, options));\n return results.length === 1 ? results[0] : results;\n };\n}\n","/**\n * @license https://raw.githubusercontent.com/node-fetch/node-fetch/master/LICENSE.md\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 - 2020 Node Fetch Team\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * Extracted from https://github.com/node-fetch/node-fetch/blob/64c5c296a0250b852010746c76144cb9e14698d9/src/utils/form-data.js\n */\n\nimport type FormData from 'form-data';\n\nconst carriage = '\\r\\n';\nconst dashes = '-'.repeat(2);\n\nconst NAME = Symbol.toStringTag;\n\nexport const isBlob = (object: any) =>\n typeof object === 'object' &&\n typeof object.arrayBuffer === 'function' &&\n typeof object.type === 'string' &&\n typeof object.stream === 'function' &&\n typeof object.constructor === 'function' &&\n /^(Blob|File)$/.test(object[NAME]);\n\nconst getFooter = (boundary: string) => `${dashes}${boundary}${dashes}${carriage.repeat(2)}`;\n\nconst getHeader = (boundary: string, name: string, field: { name: string; type: string }) => {\n let header = '';\n\n header += `${dashes}${boundary}${carriage}`;\n header += `Content-Disposition: form-data; name=\"${name}\"`;\n\n if (isBlob(field)) {\n header += `; filename=\"${field.name}\"${carriage}`;\n header += `Content-Type: ${field.type || 'application/octet-stream'}`;\n }\n\n return `${header}${carriage.repeat(2)}`;\n};\n\nexport const formDataIterator = function* (form: FormData, boundary: string) {\n // @ts-expect-error not sure how this ever worked\n // eslint-disable-next-line no-restricted-syntax\n for (const [name, value] of form) {\n yield getHeader(boundary, name, value);\n\n if (isBlob(value)) {\n yield* value.stream();\n } else {\n yield value;\n }\n\n yield carriage;\n }\n\n yield getFooter(boundary);\n};\n","export type ReducedHelperObject = Record<string, string[] | string>;\n\nexport const reducer = <T extends { name: string; value: string }>(accumulator: ReducedHelperObject, pair: T) => {\n const currentValue = accumulator[pair.name];\n if (currentValue === undefined) {\n accumulator[pair.name] = pair.value;\n return accumulator;\n }\n\n // If we already have it as array just push the value\n if (Array.isArray(currentValue)) {\n currentValue.push(pair.value);\n return accumulator;\n }\n\n // convert to array since now we have more than one value for this key\n accumulator[pair.name] = [currentValue, pair.value];\n return accumulator;\n};\n","import type { ClientInfo, TargetId, TargetInfo } from '../targets/targets';\n\nimport { targets } from '../targets/targets';\n\nexport interface AvailableTarget extends TargetInfo {\n clients: ClientInfo[];\n}\n\nexport const availableTargets = () =>\n Object.keys(targets).map<AvailableTarget>(targetId => ({\n ...targets[targetId as TargetId].info,\n clients: Object.keys(targets[targetId as TargetId].clientsById).map(\n clientId => targets[targetId as TargetId].clientsById[clientId].info,\n ),\n }));\n\nexport const extname = (targetId: TargetId) => targets[targetId]?.info.extname || '';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/helpers/form-data.ts","../src/helpers/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReducedHelperObject } from './helpers/reducer';\nimport type { ClientId, TargetId } from './targets/targets';\nimport type { Param, PostDataCommon, Request as NpmHarRequest } from 'har-format';\nimport type { UrlWithParsedQuery } from 'node:url';\n\nimport { format as urlFormat, parse as urlParse } from 'node:url';\n\nimport { map as eventStreamMap } from 'event-stream';\nimport FormData from 'form-data';\nimport { stringify as queryStringify } from 'qs';\n\nimport { formDataIterator, isBlob } from './helpers/form-data';\nimport { getHeaderName } from './helpers/headers';\nimport { reducer } from './helpers/reducer';\nimport { targets } from './targets/targets';\n\nexport { availableTargets, extname } from './helpers/utils';\nexport { addTarget, addTargetClient } from './targets/targets';\n\n/** is this wrong? yes. according to the spec (http://www.softwareishard.com/blog/har-12-spec/#postData) it's technically wrong since `params` and `text` are (by the spec) mutually exclusive. However, in practice, this is not what is often the case.\n *\n * In general, this library takes a _descriptive_ rather than _perscriptive_ approach (see https://amyrey.web.unc.edu/classes/ling-101-online/tutorials/understanding-prescriptive-vs-descriptive-grammar/).\n *\n * Then, in addition to that, it really adds to complexity with TypeScript (TypeScript takes this constraint very very seriously) in a way that's not actually super useful. So, we treat this object as though it could have both or either of `params` and/or `text`.\n */\ntype PostDataBase = PostDataCommon & {\n params?: Param[];\n text?: string;\n};\n\nexport type HarRequest = Omit<NpmHarRequest, 'postData'> & { postData: PostDataBase };\n\nexport interface RequestExtras {\n allHeaders: ReducedHelperObject;\n cookiesObj: ReducedHelperObject;\n fullUrl: string;\n headersObj: ReducedHelperObject;\n postData: PostDataBase & {\n boundary?: string;\n jsonObj?: ReducedHelperObject;\n paramsObj?: ReducedHelperObject;\n };\n queryObj: ReducedHelperObject;\n uriObj: UrlWithParsedQuery;\n}\n\nexport type Request = HarRequest & RequestExtras;\n\ninterface Entry {\n request: Partial<HarRequest>;\n}\n\ninterface HarEntry {\n log: {\n creator: {\n name: string;\n version: string;\n };\n entries: Entry[];\n version: string;\n };\n}\n\nexport interface HTTPSnippetOptions {\n harIsAlreadyEncoded?: boolean;\n}\n\nconst isHarEntry = (value: any): value is HarEntry =>\n typeof value === 'object' &&\n 'log' in value &&\n typeof value.log === 'object' &&\n 'entries' in value.log &&\n Array.isArray(value.log.entries);\n\nexport class HTTPSnippet {\n requests: Request[] = [];\n\n constructor(input: HarEntry | HarRequest, opts: HTTPSnippetOptions = {}) {\n let entries: Entry[] = [];\n\n const options = {\n harIsAlreadyEncoded: false,\n ...opts,\n };\n\n // prep the main container\n this.requests = [];\n\n // is it har?\n if (isHarEntry(input)) {\n entries = input.log.entries;\n } else {\n entries = [\n {\n request: input,\n },\n ];\n }\n\n entries.forEach(({ request }) => {\n // add optional properties to make validation successful\n const req = {\n bodySize: 0,\n headersSize: 0,\n headers: [],\n cookies: [],\n httpVersion: 'HTTP/1.1',\n queryString: [],\n postData: {\n mimeType: request.postData?.mimeType || 'application/octet-stream',\n },\n ...request,\n };\n\n // Per the HAR spec `mimeType` needs to always be present if we have a `postData` object.\n if (req.postData && !req.postData.mimeType) {\n req.postData.mimeType = 'application/octet-stream';\n }\n\n this.requests.push(this.prepare(req as HarRequest, options));\n });\n }\n\n prepare = (harRequest: HarRequest, options: HTTPSnippetOptions) => {\n const request: Request = {\n ...harRequest,\n fullUrl: '',\n uriObj: {} as UrlWithParsedQuery,\n queryObj: {},\n headersObj: {},\n cookiesObj: {},\n allHeaders: {},\n };\n\n // construct query objects\n if (request.queryString && request.queryString.length) {\n request.queryObj = request.queryString.reduce(reducer, {});\n }\n\n // construct headers objects\n if (request.headers && request.headers.length) {\n const http2VersionRegex = /^HTTP\\/2/;\n request.headersObj = request.headers.reduce((accumulator, { name, value }) => {\n const headerName = http2VersionRegex.exec(request.httpVersion) ? name.toLocaleLowerCase() : name;\n return {\n ...accumulator,\n [headerName]: value,\n };\n }, {});\n }\n\n // construct headers objects\n if (request.cookies && request.cookies.length) {\n request.cookiesObj = request.cookies.reduceRight(\n (accumulator, { name, value }) => ({\n ...accumulator,\n [name]: value,\n }),\n {},\n );\n }\n\n // construct Cookie header\n const cookies = request.cookies?.map(({ name, value }) => {\n if (options.harIsAlreadyEncoded) {\n return `${name}=${value}`;\n }\n\n return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n });\n\n if (cookies?.length) {\n request.allHeaders.cookie = cookies.join('; ');\n }\n\n switch (request.postData.mimeType) {\n case 'multipart/mixed':\n case 'multipart/related':\n case 'multipart/form-data':\n case 'multipart/alternative':\n // reset values\n request.postData.text = '';\n request.postData.mimeType = 'multipart/form-data';\n\n if (request.postData?.params) {\n const form = new FormData();\n\n // The `form-data` module returns one of two things: a native FormData object, or its own polyfill\n // Since the polyfill does not support the full API of the native FormData object, when this library is running in a browser environment it'll fail on two things:\n //\n // 1. The API for `form.append()` has three arguments and the third should only be present when the second is a\n // Blob or USVString.\n // 1. `FormData.pipe()` isn't a function.\n //\n // Since the native FormData object is iterable, we easily detect what version of `form-data` we're working with here to allow `multipart/form-data` requests to be compiled under both browser and Node environments.\n //\n // This hack is pretty awful but it's the only way we can use this library in the browser as if we code this against just the native FormData object, we can't polyfill that back into Node because Blob and File objects, which something like `formdata-polyfill` requires, don't exist there.\n // @ts-expect-error TODO\n const isNativeFormData = typeof form[Symbol.iterator] === 'function';\n\n // TODO: THIS ABSOLUTELY MUST BE REMOVED.\n // IT BREAKS SOME USE-CASES FOR MULTIPART FORMS THAT DEPEND ON BEING ABLE TO SET THE BOUNDARY.\n // easter egg\n const boundary = '---011000010111000001101001'; // this is binary for \"api\". yep.\n if (!isNativeFormData) {\n // @ts-expect-error THIS IS WRONG. VERY WRONG.\n form._boundary = boundary;\n }\n\n request.postData?.params.forEach(param => {\n const name = param.name;\n const value = param.value || '';\n const filename = param.fileName || null;\n\n if (isNativeFormData) {\n if (isBlob(value)) {\n // @ts-expect-error TODO\n form.append(name, value, filename);\n } else {\n form.append(name, value);\n }\n } else {\n form.append(name, value, {\n // @ts-expect-error TODO\n filename,\n // @ts-expect-error TODO\n contentType: param.contentType || null,\n });\n }\n });\n\n if (isNativeFormData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const data of formDataIterator(form, boundary)) {\n request.postData.text += data;\n }\n } else {\n form.pipe(\n // @ts-expect-error TODO\n eventStreamMap(data => {\n request.postData.text += data;\n }),\n );\n }\n\n request.postData.boundary = boundary;\n\n // Since headers are case-sensitive we need to see if there's an existing `Content-Type` header that we can override.\n const contentTypeHeader = getHeaderName(request.headersObj, 'content-type') || 'content-type';\n\n request.headersObj[contentTypeHeader] = `multipart/form-data; boundary=${boundary}`;\n }\n break;\n\n case 'application/x-www-form-urlencoded':\n if (!request.postData.params) {\n request.postData.text = '';\n } else {\n // @ts-expect-error the `har-format` types make this challenging\n request.postData.paramsObj = request.postData.params.reduce(reducer, {});\n\n // always overwrite\n request.postData.text = queryStringify(request.postData.paramsObj);\n }\n break;\n\n case 'text/json':\n case 'text/x-json':\n case 'application/json':\n case 'application/x-json':\n request.postData.mimeType = 'application/json';\n\n if (request.postData.text) {\n try {\n request.postData.jsonObj = JSON.parse(request.postData.text);\n } catch (e) {\n // force back to `text/plain` if headers have proper content-type value, then this should also work\n request.postData.mimeType = 'text/plain';\n }\n }\n break;\n }\n\n // create allHeaders object\n const allHeaders = {\n ...request.allHeaders,\n ...request.headersObj,\n };\n\n const urlWithParsedQuery = urlParse(request.url, true, true); //?\n\n // query string key/value pairs in with literal querystrings containd within the url\n request.queryObj = {\n ...request.queryObj,\n ...(urlWithParsedQuery.query as ReducedHelperObject),\n }; //?\n\n // reset uriObj values for a clean url\n let search;\n if (options.harIsAlreadyEncoded) {\n search = queryStringify(request.queryObj, {\n encode: false,\n indices: false,\n });\n } else {\n search = queryStringify(request.queryObj, {\n indices: false,\n });\n }\n\n const uriObj = {\n ...urlWithParsedQuery,\n query: request.queryObj,\n search,\n path: search ? `${urlWithParsedQuery.pathname}?${search}` : urlWithParsedQuery.pathname,\n };\n\n // keep the base url clean of queryString\n const url = urlFormat({\n ...urlWithParsedQuery,\n query: null,\n search: null,\n }); //?\n\n const fullUrl = urlFormat({\n ...urlWithParsedQuery,\n ...uriObj,\n }); //?\n\n return {\n ...request,\n allHeaders,\n fullUrl,\n url,\n uriObj,\n };\n };\n\n convert = (targetId: TargetId, clientId?: ClientId, options?: any) => {\n if (!options && clientId) {\n options = clientId;\n }\n\n const target = targets[targetId];\n if (!target) {\n return false;\n }\n\n const { convert } = target.clientsById[clientId || target.info.default];\n const results = this.requests.map(request => convert(request, options));\n return results.length === 1 ? results[0] : results;\n };\n}\n","/**\n * @license https://raw.githubusercontent.com/node-fetch/node-fetch/master/LICENSE.md\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 - 2020 Node Fetch Team\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * Extracted from https://github.com/node-fetch/node-fetch/blob/64c5c296a0250b852010746c76144cb9e14698d9/src/utils/form-data.js\n */\n\nimport type FormData from 'form-data';\n\nconst carriage = '\\r\\n';\nconst dashes = '-'.repeat(2);\n\nconst NAME = Symbol.toStringTag;\n\nexport const isBlob = (object: any) =>\n typeof object === 'object' &&\n typeof object.arrayBuffer === 'function' &&\n typeof object.type === 'string' &&\n typeof object.stream === 'function' &&\n typeof object.constructor === 'function' &&\n /^(Blob|File)$/.test(object[NAME]);\n\nconst getFooter = (boundary: string) => `${dashes}${boundary}${dashes}${carriage.repeat(2)}`;\n\nconst getHeader = (boundary: string, name: string, field: { name: string; type: string }) => {\n let header = '';\n\n header += `${dashes}${boundary}${carriage}`;\n header += `Content-Disposition: form-data; name=\"${name}\"`;\n\n if (isBlob(field)) {\n header += `; filename=\"${field.name}\"${carriage}`;\n header += `Content-Type: ${field.type || 'application/octet-stream'}`;\n }\n\n return `${header}${carriage.repeat(2)}`;\n};\n\nexport const formDataIterator = function* (form: FormData, boundary: string) {\n // @ts-expect-error not sure how this ever worked\n // eslint-disable-next-line no-restricted-syntax\n for (const [name, value] of form) {\n yield getHeader(boundary, name, value);\n\n if (isBlob(value)) {\n yield* value.stream();\n } else {\n yield value;\n }\n\n yield carriage;\n }\n\n yield getFooter(boundary);\n};\n","import type { ClientInfo, TargetId, TargetInfo } from '../targets/targets';\n\nimport { targets } from '../targets/targets';\n\nexport interface AvailableTarget extends TargetInfo {\n clients: ClientInfo[];\n}\n\nexport const availableTargets = () =>\n Object.keys(targets).map<AvailableTarget>(targetId => ({\n ...targets[targetId as TargetId].info,\n clients: Object.keys(targets[targetId as TargetId].clientsById).map(\n clientId => targets[targetId as TargetId].clientsById[clientId].info,\n ),\n }));\n\nexport const extname = (targetId: TargetId) => targets[targetId]?.info.extname || '';\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { c as Client, C as ClientId, a as ClientInfo, b as Converter, E as Extension, e as Target, T as TargetId, d as TargetInfo, f as addTarget, h as addTargetClient, g as isClient, i as isTarget, t as targets } from '../index-
|
|
1
|
+
export { c as Client, C as ClientId, a as ClientInfo, b as Converter, E as Extension, e as Target, T as TargetId, d as TargetInfo, f as addTarget, h as addTargetClient, g as isClient, i as isTarget, t as targets } from '../index-27be831e.js';
|
|
2
|
+
import '../helpers/code-builder.mjs';
|
|
2
3
|
import 'type-fest';
|
|
3
4
|
import 'har-format';
|
|
5
|
+
import '../helpers/reducer.mjs';
|
|
4
6
|
import 'node:url';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { c as Client, C as ClientId, a as ClientInfo, b as Converter, E as Extension, e as Target, T as TargetId, d as TargetInfo, f as addTarget, h as addTargetClient, g as isClient, i as isTarget, t as targets } from '../index-
|
|
1
|
+
export { c as Client, C as ClientId, a as ClientInfo, b as Converter, E as Extension, e as Target, T as TargetId, d as TargetInfo, f as addTarget, h as addTargetClient, g as isClient, i as isTarget, t as targets } from '../index-e612cd58.js';
|
|
2
|
+
import '../helpers/code-builder.js';
|
|
2
3
|
import 'type-fest';
|
|
3
4
|
import 'har-format';
|
|
5
|
+
import '../helpers/reducer.js';
|
|
4
6
|
import 'node:url';
|
package/dist/targets/targets.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { addTarget, addTargetClient, isClient, isTarget, targets } from '../chunk-
|
|
1
|
+
export { addTarget, addTargetClient, isClient, isTarget, targets } from '../chunk-WJGIOTIP.mjs';
|
|
2
|
+
import '../chunk-UEOS42PC.mjs';
|
|
2
3
|
//# sourceMappingURL=out.js.map
|
|
3
4
|
//# sourceMappingURL=targets.mjs.map
|