@etsoo/shared 1.1.84 → 1.1.85
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 +9 -0
- package/__tests__/ContentDisposition.ts +24 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/types/ContentDisposition.d.ts +22 -0
- package/lib/cjs/types/ContentDisposition.js +75 -0
- package/lib/mjs/index.d.ts +1 -0
- package/lib/mjs/index.js +1 -0
- package/lib/mjs/types/ContentDisposition.d.ts +22 -0
- package/lib/mjs/types/ContentDisposition.js +71 -0
- package/package.json +2 -7
- package/src/index.ts +1 -0
- package/src/types/ContentDisposition.ts +81 -0
package/README.md
CHANGED
|
@@ -32,6 +32,15 @@ $ yarn add @etsoo/shared
|
|
|
32
32
|
## storage
|
|
33
33
|
Storage interface and browser storage implementation
|
|
34
34
|
|
|
35
|
+
## ContentDisposition
|
|
36
|
+
Content disposition of HTTP
|
|
37
|
+
|
|
38
|
+
|Name|Description|
|
|
39
|
+
|---:|---|
|
|
40
|
+
|static parse|Parse header value|
|
|
41
|
+
|Methods||
|
|
42
|
+
|format|Format to standard output|
|
|
43
|
+
|
|
35
44
|
## EColor
|
|
36
45
|
Etsoo implmented Color
|
|
37
46
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ContentDisposition } from '../src/types/ContentDisposition';
|
|
2
|
+
|
|
3
|
+
test('Tests for parse', () => {
|
|
4
|
+
const cd1 = ContentDisposition.parse(
|
|
5
|
+
"attachment; filename=__PDF.pdf; filename*=UTF-8''%E6%B5%8B%E8%AF%95PDF.pdf"
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
const cd2 = ContentDisposition.parse(
|
|
9
|
+
`attachment; filename="__PDF.pdf"; filename*="UTF-8''%E6%B5%8B%E8%AF%95PDF.pdf"`
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
expect(cd1?.type).toBe(cd2?.type);
|
|
13
|
+
expect(cd1?.filename).toBe(cd2?.filename);
|
|
14
|
+
expect(cd1?.filename).toBe('测试PDF.pdf');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Tests for format', () => {
|
|
18
|
+
const cd1 = new ContentDisposition('form-data', 'a-b.jpg', 'file');
|
|
19
|
+
expect(cd1.format()).toBe(`form-data; name="file"; filename="a-b.jpg"`);
|
|
20
|
+
const cd2 = new ContentDisposition('attachment', '测试PDF.pdf');
|
|
21
|
+
expect(cd2.format()).toBe(
|
|
22
|
+
`attachment; filename="__PDF.pdf"; filename*="UTF-8''%E6%B5%8B%E8%AF%95PDF.pdf"`
|
|
23
|
+
);
|
|
24
|
+
});
|
package/lib/cjs/index.d.ts
CHANGED
package/lib/cjs/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types/ContentDisposition"), exports);
|
|
17
18
|
__exportStar(require("./types/DelayedExecutorType"), exports);
|
|
18
19
|
__exportStar(require("./types/EColor"), exports);
|
|
19
20
|
__exportStar(require("./types/EHistory"), exports);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content disposition of HTTP
|
|
3
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
4
|
+
*/
|
|
5
|
+
export declare class ContentDisposition {
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly filename: string;
|
|
8
|
+
readonly name?: string | undefined;
|
|
9
|
+
constructor(type: 'inline' | 'attachment', filename: string);
|
|
10
|
+
constructor(type: 'form-data', filename: string, name: string);
|
|
11
|
+
/**
|
|
12
|
+
* Format to standard output
|
|
13
|
+
* @returns Result
|
|
14
|
+
*/
|
|
15
|
+
format(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse header value
|
|
18
|
+
* @param header Content-Disposition header value
|
|
19
|
+
* @returns Object
|
|
20
|
+
*/
|
|
21
|
+
static parse(header: string | undefined | null): ContentDisposition | undefined;
|
|
22
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentDisposition = void 0;
|
|
4
|
+
const Utils_1 = require("../Utils");
|
|
5
|
+
/**
|
|
6
|
+
* Content disposition of HTTP
|
|
7
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
8
|
+
*/
|
|
9
|
+
class ContentDisposition {
|
|
10
|
+
constructor(type, filename, name) {
|
|
11
|
+
this.type = type;
|
|
12
|
+
this.filename = filename;
|
|
13
|
+
this.name = name;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Format to standard output
|
|
17
|
+
* @returns Result
|
|
18
|
+
*/
|
|
19
|
+
format() {
|
|
20
|
+
const items = [this.type];
|
|
21
|
+
if (this.name)
|
|
22
|
+
items.push(`name="${this.name}"`);
|
|
23
|
+
const filename1 = this.filename.replace(/[^a-zA-Z0-9\.-]/g, '_');
|
|
24
|
+
items.push(`filename="${filename1}"`);
|
|
25
|
+
if (filename1 != this.filename)
|
|
26
|
+
items.push(`filename*="UTF-8''${encodeURIComponent(this.filename)}"`);
|
|
27
|
+
return items.join('; ');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse header value
|
|
31
|
+
* @param header Content-Disposition header value
|
|
32
|
+
* @returns Object
|
|
33
|
+
*/
|
|
34
|
+
static parse(header) {
|
|
35
|
+
if (!header)
|
|
36
|
+
return undefined;
|
|
37
|
+
const parts = header.trim().split(/\s*;\s*/g);
|
|
38
|
+
const len = parts.length;
|
|
39
|
+
if (len < 2)
|
|
40
|
+
return undefined;
|
|
41
|
+
const type = parts[0];
|
|
42
|
+
let name;
|
|
43
|
+
let filename = '';
|
|
44
|
+
for (let i = 1; i < len; i++) {
|
|
45
|
+
const part = parts[i];
|
|
46
|
+
let [field, value] = part.split(/\s*=\s*/g);
|
|
47
|
+
// case-insensitive
|
|
48
|
+
field = field.toLowerCase();
|
|
49
|
+
// Remove quotes
|
|
50
|
+
value = Utils_1.Utils.trim(value, '"');
|
|
51
|
+
if (field === 'name') {
|
|
52
|
+
name = value;
|
|
53
|
+
}
|
|
54
|
+
else if (field === 'filename') {
|
|
55
|
+
if (filename === '')
|
|
56
|
+
filename = value;
|
|
57
|
+
}
|
|
58
|
+
else if (field === 'filename*') {
|
|
59
|
+
const pos = value.indexOf("''");
|
|
60
|
+
filename =
|
|
61
|
+
pos == -1
|
|
62
|
+
? value
|
|
63
|
+
: decodeURIComponent(value.substring(pos + 2));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (type === 'form-data') {
|
|
67
|
+
return new ContentDisposition(type, filename, name !== null && name !== void 0 ? name : 'file');
|
|
68
|
+
}
|
|
69
|
+
if (type === 'inline' || type === 'attachment') {
|
|
70
|
+
return new ContentDisposition(type, filename);
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.ContentDisposition = ContentDisposition;
|
package/lib/mjs/index.d.ts
CHANGED
package/lib/mjs/index.js
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content disposition of HTTP
|
|
3
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
4
|
+
*/
|
|
5
|
+
export declare class ContentDisposition {
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly filename: string;
|
|
8
|
+
readonly name?: string | undefined;
|
|
9
|
+
constructor(type: 'inline' | 'attachment', filename: string);
|
|
10
|
+
constructor(type: 'form-data', filename: string, name: string);
|
|
11
|
+
/**
|
|
12
|
+
* Format to standard output
|
|
13
|
+
* @returns Result
|
|
14
|
+
*/
|
|
15
|
+
format(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse header value
|
|
18
|
+
* @param header Content-Disposition header value
|
|
19
|
+
* @returns Object
|
|
20
|
+
*/
|
|
21
|
+
static parse(header: string | undefined | null): ContentDisposition | undefined;
|
|
22
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Utils } from '../Utils';
|
|
2
|
+
/**
|
|
3
|
+
* Content disposition of HTTP
|
|
4
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
5
|
+
*/
|
|
6
|
+
export class ContentDisposition {
|
|
7
|
+
constructor(type, filename, name) {
|
|
8
|
+
this.type = type;
|
|
9
|
+
this.filename = filename;
|
|
10
|
+
this.name = name;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Format to standard output
|
|
14
|
+
* @returns Result
|
|
15
|
+
*/
|
|
16
|
+
format() {
|
|
17
|
+
const items = [this.type];
|
|
18
|
+
if (this.name)
|
|
19
|
+
items.push(`name="${this.name}"`);
|
|
20
|
+
const filename1 = this.filename.replace(/[^a-zA-Z0-9\.-]/g, '_');
|
|
21
|
+
items.push(`filename="${filename1}"`);
|
|
22
|
+
if (filename1 != this.filename)
|
|
23
|
+
items.push(`filename*="UTF-8''${encodeURIComponent(this.filename)}"`);
|
|
24
|
+
return items.join('; ');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse header value
|
|
28
|
+
* @param header Content-Disposition header value
|
|
29
|
+
* @returns Object
|
|
30
|
+
*/
|
|
31
|
+
static parse(header) {
|
|
32
|
+
if (!header)
|
|
33
|
+
return undefined;
|
|
34
|
+
const parts = header.trim().split(/\s*;\s*/g);
|
|
35
|
+
const len = parts.length;
|
|
36
|
+
if (len < 2)
|
|
37
|
+
return undefined;
|
|
38
|
+
const type = parts[0];
|
|
39
|
+
let name;
|
|
40
|
+
let filename = '';
|
|
41
|
+
for (let i = 1; i < len; i++) {
|
|
42
|
+
const part = parts[i];
|
|
43
|
+
let [field, value] = part.split(/\s*=\s*/g);
|
|
44
|
+
// case-insensitive
|
|
45
|
+
field = field.toLowerCase();
|
|
46
|
+
// Remove quotes
|
|
47
|
+
value = Utils.trim(value, '"');
|
|
48
|
+
if (field === 'name') {
|
|
49
|
+
name = value;
|
|
50
|
+
}
|
|
51
|
+
else if (field === 'filename') {
|
|
52
|
+
if (filename === '')
|
|
53
|
+
filename = value;
|
|
54
|
+
}
|
|
55
|
+
else if (field === 'filename*') {
|
|
56
|
+
const pos = value.indexOf("''");
|
|
57
|
+
filename =
|
|
58
|
+
pos == -1
|
|
59
|
+
? value
|
|
60
|
+
: decodeURIComponent(value.substring(pos + 2));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (type === 'form-data') {
|
|
64
|
+
return new ContentDisposition(type, filename, name !== null && name !== void 0 ? name : 'file');
|
|
65
|
+
}
|
|
66
|
+
if (type === 'inline' || type === 'attachment') {
|
|
67
|
+
return new ContentDisposition(type, filename);
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/shared",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.85",
|
|
4
4
|
"description": "TypeScript shared utilities and functions",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -54,13 +54,8 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://github.com/ETSOO/Shared#readme",
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@types/jest": "^29.2.
|
|
57
|
+
"@types/jest": "^29.2.5",
|
|
58
58
|
"@types/lodash.isequal": "^4.5.6",
|
|
59
|
-
"@typescript-eslint/eslint-plugin": "^5.47.0",
|
|
60
|
-
"@typescript-eslint/parser": "^5.47.0",
|
|
61
|
-
"eslint": "^8.30.0",
|
|
62
|
-
"eslint-config-airbnb-base": "^15.0.0",
|
|
63
|
-
"eslint-plugin-import": "^2.26.0",
|
|
64
59
|
"jest": "^29.3.1",
|
|
65
60
|
"jest-environment-jsdom": "^29.3.1",
|
|
66
61
|
"ts-jest": "^29.0.3",
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Utils } from '../Utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Content disposition of HTTP
|
|
5
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
6
|
+
*/
|
|
7
|
+
export class ContentDisposition {
|
|
8
|
+
constructor(type: 'inline' | 'attachment', filename: string);
|
|
9
|
+
constructor(type: 'form-data', filename: string, name: string);
|
|
10
|
+
constructor(
|
|
11
|
+
public readonly type: string,
|
|
12
|
+
public readonly filename: string,
|
|
13
|
+
public readonly name?: string
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Format to standard output
|
|
18
|
+
* @returns Result
|
|
19
|
+
*/
|
|
20
|
+
format() {
|
|
21
|
+
const items = [this.type];
|
|
22
|
+
if (this.name) items.push(`name="${this.name}"`);
|
|
23
|
+
const filename1 = this.filename.replace(/[^a-zA-Z0-9\.-]/g, '_');
|
|
24
|
+
items.push(`filename="${filename1}"`);
|
|
25
|
+
if (filename1 != this.filename)
|
|
26
|
+
items.push(
|
|
27
|
+
`filename*="UTF-8''${encodeURIComponent(this.filename)}"`
|
|
28
|
+
);
|
|
29
|
+
return items.join('; ');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse header value
|
|
34
|
+
* @param header Content-Disposition header value
|
|
35
|
+
* @returns Object
|
|
36
|
+
*/
|
|
37
|
+
static parse(header: string | undefined | null) {
|
|
38
|
+
if (!header) return undefined;
|
|
39
|
+
|
|
40
|
+
const parts = header.trim().split(/\s*;\s*/g);
|
|
41
|
+
const len = parts.length;
|
|
42
|
+
if (len < 2) return undefined;
|
|
43
|
+
|
|
44
|
+
const type = parts[0];
|
|
45
|
+
let name: string | undefined;
|
|
46
|
+
let filename: string = '';
|
|
47
|
+
|
|
48
|
+
for (let i = 1; i < len; i++) {
|
|
49
|
+
const part = parts[i];
|
|
50
|
+
let [field, value] = part.split(/\s*=\s*/g);
|
|
51
|
+
|
|
52
|
+
// case-insensitive
|
|
53
|
+
field = field.toLowerCase();
|
|
54
|
+
|
|
55
|
+
// Remove quotes
|
|
56
|
+
value = Utils.trim(value, '"');
|
|
57
|
+
|
|
58
|
+
if (field === 'name') {
|
|
59
|
+
name = value;
|
|
60
|
+
} else if (field === 'filename') {
|
|
61
|
+
if (filename === '') filename = value;
|
|
62
|
+
} else if (field === 'filename*') {
|
|
63
|
+
const pos = value.indexOf("''");
|
|
64
|
+
filename =
|
|
65
|
+
pos == -1
|
|
66
|
+
? value
|
|
67
|
+
: decodeURIComponent(value.substring(pos + 2));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (type === 'form-data') {
|
|
72
|
+
return new ContentDisposition(type, filename, name ?? 'file');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (type === 'inline' || type === 'attachment') {
|
|
76
|
+
return new ContentDisposition(type, filename);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|