page2pdf_server 1.1.2 → 1.1.3
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 +4 -1
- package/package.json +4 -69
- package/src/index.ts +11 -18
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -15
- package/.github/ISSUE_TEMPLATE/refactoring.md +0 -15
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -18
- package/.github/stale.yml +0 -17
- package/.github/workflows/cd.yml +0 -75
- package/.github/workflows/ci.yml +0 -36
- package/.prettierrc +0 -8
- package/.vscode/settings.json +0 -3
- package/config/default.json +0 -10
- package/config/development.json +0 -3
- package/config/production.json +0 -3
- package/config/test.json +0 -3
- package/ecosystem.config.js +0 -41
- package/jest.config.js +0 -35
- package/nodemon.json +0 -6
- package/src/CSS/345/205/274/345/256/271/346/200/247.txt +0 -125
- package/src/__tests__/UrltoPdf/generatePdf.test.d.ts +0 -1
- package/src/__tests__/UrltoPdf/generatePdf.test.ts +0 -207
- package/src/__tests__/UrltoPdf/pdfSplit.test.d.ts +0 -1
- package/src/__tests__/UrltoPdf/pdfSplit.test.ts +0 -69
- package/src/__tests__/helpers/index.d.ts +0 -2
- package/src/__tests__/helpers/index.ts +0 -21
- package/src/__tests__/home.test.d.ts +0 -1
- package/src/__tests__/home.test.ts +0 -77
- package/src/app.ts +0 -49
- package/src/components/home/controller.ts +0 -32
- package/src/components/home/index.ts +0 -4
- package/src/components/home/pdfController.ts +0 -118
- package/src/components/home/services.ts +0 -31
- package/src/components/home/splitController.ts +0 -134
- package/src/components/home/validators.ts +0 -12
- package/src/configEnv/index.ts +0 -62
- package/src/db/home.ts +0 -14
- package/src/helpers/apiResponse.ts +0 -10
- package/src/helpers/dataSanitizers.ts +0 -33
- package/src/helpers/error/ApiError.ts +0 -25
- package/src/helpers/error/ForbiddenError.ts +0 -15
- package/src/helpers/error/NotFoundException.ts +0 -15
- package/src/helpers/error/TimeOutError.ts +0 -20
- package/src/helpers/error/UnauthorizedError.ts +0 -15
- package/src/helpers/error/ValidationError.ts +0 -20
- package/src/helpers/error/index.ts +0 -15
- package/src/helpers/index.ts +0 -2
- package/src/helpers/loggers.ts +0 -75
- package/src/middlewares/errorHandler.ts +0 -52
- package/src/new_tab1.mhtml +0 -722
- package/src/routes/index.ts +0 -22
- package/src/server.ts +0 -30
- package/src/testCSS.html +0 -241
- package/src/types/global.d.ts +0 -13
- package/src/types/request/home.ts +0 -3
- package/src/types/request/split.ts +0 -18
- package/src/types/response/AppInformation.ts +0 -9
- package/src/types/response/index.ts +0 -5
- package/src/utils/array.ts +0 -19
- package/src/utils/auth.ts +0 -12
- package/src/utils/crypt.ts +0 -25
- package/src/utils/filter.ts +0 -59
- package/src/utils/object.ts +0 -58
- package/src/utils/pdfgen.ts +0 -1045
- package/src/utils/url.ts +0 -54
- package/src//346/265/213/350/257/225.txt +0 -268
- package/test//346/211/223/345/215/260/346/234/215/345/212/241.http +0 -17
- package//346/226/207/344/271/246/346/211/223/345/215/260/350/275/254/346/215/242/345/231/250.bat +0 -2
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { SuperAgentTest } from "supertest";
|
|
2
|
-
import { OK } from "http-status/lib";
|
|
3
|
-
import { initAgent } from "../helpers/index";
|
|
4
|
-
|
|
5
|
-
//prettify真叼: 每个地方都给您报出 红色
|
|
6
|
-
const TIMEOUT = 260000; //设置超时,避免单步歇菜
|
|
7
|
-
let agent: SuperAgentTest;
|
|
8
|
-
|
|
9
|
-
beforeAll(async () => {
|
|
10
|
-
agent = await initAgent();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
/**替代: 浏览器postman等工具发送包后,后端服务器Debug模式运行单步调试模式已经没能使用了。只好改为jest来对付了。
|
|
14
|
-
后面的/${CONFIG.APP.VER} 就是加了/v1结尾的该服务工程的版本号;
|
|
15
|
-
* */
|
|
16
|
-
describe("[PDF] => Gen", () => {
|
|
17
|
-
describe("Post: '/api/pdf'", () => {
|
|
18
|
-
it(
|
|
19
|
-
"通用基本的",
|
|
20
|
-
async () => {
|
|
21
|
-
const response = await agent.post(`/api/pdf`).send({
|
|
22
|
-
name: "asjsak啊实打实",
|
|
23
|
-
lay: {
|
|
24
|
-
head: [
|
|
25
|
-
'<div style=\\"position: relative; width:100%; text-align:center; border-bottom: 1pt solid #eeeeee; margin: 3.5mm 0px 10px; font-size: 10pt\\"></span>',
|
|
26
|
-
'<div style=\\"position: absolute; width:100%; text-align: center; bottom: 5px;\\"><span class=title></div>',
|
|
27
|
-
'<div style=\\"position: absolute; text-align: right; bottom: 5px;right: 20px;\\">version: 1.0</div>',
|
|
28
|
-
"</div>",
|
|
29
|
-
],
|
|
30
|
-
foot: [
|
|
31
|
-
'<div style=\\"position: relative; width: 100%; text-align: left; border-top: 1pt solid #eeeeee; margin: 10px 0px 1.5mm; font-size: 8pt;\\">',
|
|
32
|
-
'<div style=\\"position: absolute; text-align: left; top: 5px;left: 60px;\\">YYYY-MM-DD</div>',
|
|
33
|
-
'<div style=\\"position: absolute; width: 100%; text-align: center; top: 5px;\\">©2022 ABCD</div>',
|
|
34
|
-
'<div style=\\"position: absolute; text-align: right;top: 5px;right: 20px;\\"> <span>${pageNumber}</span> / <span>${totalPages}</span></div>',
|
|
35
|
-
"</div>",
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
files: [
|
|
39
|
-
{
|
|
40
|
-
url: "testHtmlPrint.html",
|
|
41
|
-
out: "testHtmlPrint转",
|
|
42
|
-
headFrom: 4,
|
|
43
|
-
frNo: 0,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
url: "横页脚的.pdf",
|
|
47
|
-
displayHeaderFooter: true,
|
|
48
|
-
rightHand: true,
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
});
|
|
52
|
-
expect(response.status).toBe(OK);
|
|
53
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
54
|
-
},
|
|
55
|
-
TIMEOUT,
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
it(
|
|
59
|
-
"汇总阶段第二个url独立pdf输出",
|
|
60
|
-
async () => {
|
|
61
|
-
const response = await agent.post(`/api/pdf`).send({
|
|
62
|
-
name: "asjsak啊实打实",
|
|
63
|
-
lay: {
|
|
64
|
-
head: [
|
|
65
|
-
'<div style=\\"position: relative; width:100%; text-align:center; border-bottom: 1pt solid #eeeeee; margin: 3.5mm 0px 10px; font-size: 10pt\\"></span>',
|
|
66
|
-
'<div style=\\"position: absolute; width:100%; text-align: center; bottom: 5px;\\"><span class=title></div>',
|
|
67
|
-
'<div style=\\"position: absolute; text-align: right; bottom: 5px;right: 20px;\\">version: 1.0</div>',
|
|
68
|
-
"</div>",
|
|
69
|
-
],
|
|
70
|
-
foot: [
|
|
71
|
-
'<div style=\\"position: relative; width: 100%; text-align: left; border-top: 1pt solid #eeeeee; margin: 10px 0px 1.5mm; font-size: 8pt;\\">',
|
|
72
|
-
'<div style=\\"position: absolute; text-align: left; top: 5px;left: 60px;\\">YYYY-MM-DD</div>',
|
|
73
|
-
'<div style=\\"position: absolute; width: 100%; text-align: center; top: 5px;\\">©2022 ABCD</div>',
|
|
74
|
-
'<div style=\\"position: absolute; text-align: right;top: 5px;right: 20px;\\"> <span>${pageNumber}</span> / <span>${totalPages}</span></div>',
|
|
75
|
-
"</div>",
|
|
76
|
-
],
|
|
77
|
-
},
|
|
78
|
-
files: [
|
|
79
|
-
{
|
|
80
|
-
url: "testHtmlPrint.html",
|
|
81
|
-
out: "testHtmlPrint转",
|
|
82
|
-
lay: {
|
|
83
|
-
marginTop: 0.55,
|
|
84
|
-
marginBottom: 0.45,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
url: "横页脚的.pdf",
|
|
89
|
-
merge: false,
|
|
90
|
-
displayHeaderFooter: true,
|
|
91
|
-
rightHand: true,
|
|
92
|
-
lay: {
|
|
93
|
-
marginTop: 0.55,
|
|
94
|
-
marginBottom: 0.45,
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
});
|
|
99
|
-
expect(response.status).toBe(OK);
|
|
100
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
101
|
-
},
|
|
102
|
-
TIMEOUT,
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
it(
|
|
106
|
-
"双面打印的页码_总的",
|
|
107
|
-
async () => {
|
|
108
|
-
const response = await agent.post(`/api/pdf`).send({
|
|
109
|
-
name: "asjsak啊实打实",
|
|
110
|
-
lay: {
|
|
111
|
-
head: [
|
|
112
|
-
'<div style=\\"position: relative; width:100%; text-align:center; border-bottom: 1pt solid #eeeeee; margin: 3.5mm 0px 10px; font-size: 10pt\\"></span>',
|
|
113
|
-
'<div style=\\"position: absolute; width:100%; text-align: center; bottom: 5px;\\"><span id=\\"titlespan\\" class=title></div>',
|
|
114
|
-
'<div style=\\"-NOT_DISPLAY- position: absolute; text-align: right; bottom: 5px;right: 20px;\\">',
|
|
115
|
-
"<span>${pageNumber}</span> / <span>${totalPages}</span></div>",
|
|
116
|
-
"</div>",
|
|
117
|
-
],
|
|
118
|
-
foot: [
|
|
119
|
-
'<div style=\\"position: relative; width: 100%; text-align: left; border-top: 1pt solid #eeeeee; margin: 10px 0px 1.5mm; font-size: 8pt;\\">',
|
|
120
|
-
'<div style=\\"position: absolute; text-align: left; top: 5px;left: 60px;\\">YYYY-MM-DD</div>',
|
|
121
|
-
'<div style=\\"position: absolute; width: 100%; text-align: center; top: 5px;\\">©2022 ABCD</div>',
|
|
122
|
-
'<div style=\\"position: absolute; text-align: right;top: 5px;right: 20px;\\"> <span>${pageNumber}</span> / <span>${totalPages}</span></div>',
|
|
123
|
-
"</div>",
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
files: [
|
|
127
|
-
{
|
|
128
|
-
url: "testHtmlPrint.html",
|
|
129
|
-
out: "testHtmlPrint转",
|
|
130
|
-
headFrom: 4,
|
|
131
|
-
frNo: 5,
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
url: "横页脚的.pdf",
|
|
135
|
-
displayHeaderFooter: true,
|
|
136
|
-
rightHand: true,
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
});
|
|
140
|
-
expect(response.status).toBe(OK);
|
|
141
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
142
|
-
},
|
|
143
|
-
TIMEOUT,
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
it(
|
|
147
|
-
"双面打印的页码_单URL",
|
|
148
|
-
async () => {
|
|
149
|
-
const response = await agent.post(`/api/pdf`).send({
|
|
150
|
-
name: "asjsak啊实打实",
|
|
151
|
-
lay: {},
|
|
152
|
-
files: [
|
|
153
|
-
{
|
|
154
|
-
url: "report.pdf",
|
|
155
|
-
out: "热效率详细测试",
|
|
156
|
-
headFrom: 4,
|
|
157
|
-
frNo: 5,
|
|
158
|
-
localSumNo: true,
|
|
159
|
-
roman: true,
|
|
160
|
-
lay: {
|
|
161
|
-
head: [
|
|
162
|
-
'<div style=\\"position: relative; width:100%; text-align:center; border-bottom: 1pt solid #eeeeee; margin: 3.5mm 0px 10px; font-size: 10pt\\"></span>',
|
|
163
|
-
'<div style=\\"position: absolute; width:100%; text-align: center; bottom: 5px;\\"><span id=\\"titlespan\\" class=title></div>',
|
|
164
|
-
'<div style=\\"-NOT_DISPLAY- position: absolute; text-align: right; bottom: 5px;right: 20px;\\">',
|
|
165
|
-
"<span>${pageNumber}</span> / <span>${totalPages}</span></div>",
|
|
166
|
-
"</div>",
|
|
167
|
-
],
|
|
168
|
-
foot: [
|
|
169
|
-
'<div style=\\"position: relative; width: 100%; text-align: left; border-top: 1pt solid #eeeeee; margin: 10px 0px 1.5mm; font-size: 8pt;\\">',
|
|
170
|
-
'<div style=\\"position: absolute; text-align: left; top: 5px;left: 60px;\\">YYYY-MM-DD</div>',
|
|
171
|
-
'<div style=\\"position: absolute; width: 100%; text-align: center; top: 5px;\\">©2022 ABCD</div>',
|
|
172
|
-
'<div style=\\"-NOT_DISPLAY- position: absolute; text-align: right;top: 5px;right: 20px;\\"> <span>${pageNumber}</span> / <span>${totalPages}</span></div>',
|
|
173
|
-
"</div>",
|
|
174
|
-
],
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
url: "横页脚的.pdf",
|
|
179
|
-
displayHeaderFooter: true,
|
|
180
|
-
rightHand: true,
|
|
181
|
-
lay: {
|
|
182
|
-
head: [
|
|
183
|
-
'<div style=\\"position: relative; width:100%; text-align:center; border-bottom: 1pt solid #eeeeee; margin: 3.5mm 0px 10px; font-size: 10pt\\"></span>',
|
|
184
|
-
'<div style=\\"position: absolute; width:100%; text-align: center; bottom: 5px;\\"><span id=\\"titlespan\\" class=title></div>',
|
|
185
|
-
'<div style=\\"-NOT_DISPLAY- position: absolute; text-align: right; bottom: 5px;right: 20px;\\">',
|
|
186
|
-
"<span>${pageNumber}</span> / <span>${totalPages}</span></div>",
|
|
187
|
-
"</div>",
|
|
188
|
-
],
|
|
189
|
-
foot: [
|
|
190
|
-
'<div style=\\"position: relative; width: 100%; text-align: left; border-top: 1pt solid #eeeeee; margin: 10px 0px 1.5mm; font-size: 8pt;\\">',
|
|
191
|
-
'<div style=\\"position: absolute; text-align: left; top: 5px;left: 60px;\\">YYYY-MM-DD</div>',
|
|
192
|
-
'<div style=\\"position: absolute; width: 100%; text-align: center; top: 5px;\\">©2022 ABCD</div>',
|
|
193
|
-
'<div style=\\"-NOT_DISPLAY- position: absolute; text-align: right;top: 5px;right: 20px;\\"> <span>${pageNumber}</span> / <span>${totalPages}</span></div>',
|
|
194
|
-
"</div>",
|
|
195
|
-
],
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
});
|
|
200
|
-
expect(response.status).toBe(OK);
|
|
201
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
202
|
-
console.log("结果:", response.body.data);
|
|
203
|
-
},
|
|
204
|
-
TIMEOUT,
|
|
205
|
-
);
|
|
206
|
-
});
|
|
207
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { SuperAgentTest } from "supertest";
|
|
2
|
-
import { OK } from "http-status/lib";
|
|
3
|
-
import { initAgent } from "../helpers/index";
|
|
4
|
-
// import CONFIG from "../../src/configEnv";
|
|
5
|
-
|
|
6
|
-
//prettify真叼: 每个地方都给您报出 红色
|
|
7
|
-
const TIMEOUT = 260000; //设置超时,避免单步歇菜
|
|
8
|
-
let agent: SuperAgentTest;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
agent = await initAgent();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
/**替代: 浏览器postman等工具发送包后,后端服务器Debug模式运行单步调试模式已经没能使用了。只好改为jest来对付了。
|
|
15
|
-
后面的/${CONFIG.APP.VER} 就是加了/v1结尾的该服务工程的版本号;
|
|
16
|
-
* */
|
|
17
|
-
describe("[PDF] => Gen", () => {
|
|
18
|
-
describe("Post: '/api/pdf'", () => {
|
|
19
|
-
it(
|
|
20
|
-
"全部合并工作目录的所有pdf文件",
|
|
21
|
-
async () => {
|
|
22
|
-
const response = await agent.post(`/api/pdf`).send({});
|
|
23
|
-
expect(response.status).toBe(OK);
|
|
24
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
25
|
-
},
|
|
26
|
-
TIMEOUT,
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
it(
|
|
30
|
-
"pdf建议拆分成多个pdf",
|
|
31
|
-
async () => {
|
|
32
|
-
const response = await agent.post(`/api/split`).send({
|
|
33
|
-
input: "产生的22.pdf",
|
|
34
|
-
files: [
|
|
35
|
-
{
|
|
36
|
-
pageRanges: "1-3,7-8",
|
|
37
|
-
out: "拆分achaRErint转",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
pageRanges: "7,6,1",
|
|
41
|
-
out: "最小那3QWDS",
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
});
|
|
45
|
-
expect(response.status).toBe(OK);
|
|
46
|
-
expect(Object.keys(response.body.data)).toEqual(["result"]);
|
|
47
|
-
expect(response.body.data).toEqual({ result: "成功!" });
|
|
48
|
-
console.log("结果:", response.body.data);
|
|
49
|
-
},
|
|
50
|
-
TIMEOUT,
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
/*这里发送的和IDEA工具发送差异: .post(`/api/split`).send({})是对象化的。
|
|
56
|
-
{
|
|
57
|
-
"input": "产生的22.pdf",
|
|
58
|
-
"files": [
|
|
59
|
-
{
|
|
60
|
-
"pageRanges": "1-3,5,8",
|
|
61
|
-
"out": "ch拆分achaRErint转"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"pageRanges": "4,8",
|
|
65
|
-
"out": "tesrint2323QWDS"
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
* */
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import supertest, { SuperAgentTest } from "supertest";
|
|
2
|
-
|
|
3
|
-
import { createApp } from "@/app";
|
|
4
|
-
|
|
5
|
-
// let dbConnection: Mongoose;
|
|
6
|
-
|
|
7
|
-
export const initAgent = async (): Promise<SuperAgentTest> => {
|
|
8
|
-
const app = createApp();
|
|
9
|
-
const agent = supertest.agent(app);
|
|
10
|
-
// dbConnection = await mongoDbConnection();
|
|
11
|
-
// await agent.post("/api/v2/auth/signin").send({
|
|
12
|
-
// email: testUser.email,
|
|
13
|
-
// password: testUser.password,
|
|
14
|
-
// });
|
|
15
|
-
|
|
16
|
-
return agent;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// export const closeClients = async (): Promise<void> => {
|
|
20
|
-
// await dbConnection.disconnect();
|
|
21
|
-
// };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { SuperAgentTest } from "supertest";
|
|
2
|
-
import HttpStatus, { OK, BAD_REQUEST } from "http-status/lib";
|
|
3
|
-
import { initAgent } from "./helpers/index";
|
|
4
|
-
import CONFIG from "@/configEnv";
|
|
5
|
-
|
|
6
|
-
//prettify真叼: 每个地方都给您报出 红色
|
|
7
|
-
const TIMEOUT = 60000; //设置超时,避免单步歇菜
|
|
8
|
-
let agent: SuperAgentTest;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
agent = await initAgent();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
describe("[UNIT] => HOME", () => {
|
|
15
|
-
describe("GET: '/'", () => {
|
|
16
|
-
it(
|
|
17
|
-
"Should return API app information",
|
|
18
|
-
async () => {
|
|
19
|
-
const response = await agent.get(`/api`);
|
|
20
|
-
// const response = await agent.get(`/api/${CONFIG.APP.VER}`); 框架例子原始的 版本号;
|
|
21
|
-
expect(response.status).toBe(OK);
|
|
22
|
-
expect(Object.keys(response.body.data)).toEqual([
|
|
23
|
-
"NAME",
|
|
24
|
-
"VERSION",
|
|
25
|
-
"VER",
|
|
26
|
-
"DESCRIPTION",
|
|
27
|
-
"AUTHORS",
|
|
28
|
-
"HOST",
|
|
29
|
-
"PORT",
|
|
30
|
-
"ENV",
|
|
31
|
-
"PATH",
|
|
32
|
-
"MERGE",
|
|
33
|
-
]);
|
|
34
|
-
},
|
|
35
|
-
TIMEOUT,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
it.each`
|
|
39
|
-
query | field | expectedStatus
|
|
40
|
-
${"name"} | ${"NAME"} | ${OK}
|
|
41
|
-
${"version"} | ${"VERSION"} | ${OK}
|
|
42
|
-
${"description"} | ${"DESCRIPTION"} | ${OK}
|
|
43
|
-
${"authors"} | ${"AUTHORS"} | ${OK}
|
|
44
|
-
${"port"} | ${"PORT"} | ${OK}
|
|
45
|
-
${"env"} | ${"ENV"} | ${OK}
|
|
46
|
-
`(
|
|
47
|
-
"Should return CONFIG.APP[$field] value when query.key is `$query`",
|
|
48
|
-
async ({
|
|
49
|
-
query,
|
|
50
|
-
field,
|
|
51
|
-
expectedStatus,
|
|
52
|
-
}: {
|
|
53
|
-
query: string;
|
|
54
|
-
field: keyof typeof CONFIG.APP;
|
|
55
|
-
expectedStatus: string;
|
|
56
|
-
}) => {
|
|
57
|
-
const response = await agent.get(`/api`).query({ key: query });
|
|
58
|
-
|
|
59
|
-
expect(response.body.status).toBe(expectedStatus);
|
|
60
|
-
expect(response.body.data[field]).toBe(CONFIG.APP[field]);
|
|
61
|
-
},
|
|
62
|
-
TIMEOUT,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
it(
|
|
66
|
-
"Should return 400 status Validation Error",
|
|
67
|
-
async () => {
|
|
68
|
-
const invalidQuery = "invalid-field";
|
|
69
|
-
const response = await agent.get(`/api`).query({ key: invalidQuery });
|
|
70
|
-
|
|
71
|
-
expect(response.body.status).toBe(BAD_REQUEST);
|
|
72
|
-
expect(response.body.message).toBe(HttpStatus[BAD_REQUEST]);
|
|
73
|
-
},
|
|
74
|
-
TIMEOUT,
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
});
|
package/src/app.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import cors from "cors";
|
|
3
|
-
import express from "express";
|
|
4
|
-
import helmet from "helmet";
|
|
5
|
-
import morgan from "morgan";
|
|
6
|
-
import timeout from "connect-timeout";
|
|
7
|
-
import CONFIG from "./configEnv";
|
|
8
|
-
import { expressPinoLogger } from "./helpers";
|
|
9
|
-
import * as errorHandler from "./middlewares/errorHandler";
|
|
10
|
-
import routes from "./routes";
|
|
11
|
-
|
|
12
|
-
/**打印不全,太多页数情形:
|
|
13
|
-
* */
|
|
14
|
-
EventEmitter.defaultMaxListeners = 100;
|
|
15
|
-
|
|
16
|
-
export const createApp = (): express.Application => {
|
|
17
|
-
const app = express();
|
|
18
|
-
|
|
19
|
-
app.use(cors());
|
|
20
|
-
app.use(helmet());
|
|
21
|
-
app.use(express.json());
|
|
22
|
-
app.use(
|
|
23
|
-
express.urlencoded({
|
|
24
|
-
extended: true,
|
|
25
|
-
}),
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
if (CONFIG.APP.ENV !== "test") {
|
|
29
|
-
app.use(morgan("dev"));
|
|
30
|
-
app.use(expressPinoLogger());
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
app.use(timeout(CONFIG.SERVER.TIMEOUT));
|
|
35
|
-
|
|
36
|
-
// API Routes
|
|
37
|
-
// API Routes 如果代码非常简单,完全可以 app.get('/',....),如果路由比较复杂,需要路由的嵌套分层拆解模式:使用 express.Router() 更合适。
|
|
38
|
-
app.use(`/api`, routes);
|
|
39
|
-
//框架例子有:版本号的插入的。
|
|
40
|
-
//app.use(`/api/${CONFIG.APP.VER}`, routes);
|
|
41
|
-
|
|
42
|
-
// Error Middleware
|
|
43
|
-
app.use(errorHandler.genericErrorHandler);
|
|
44
|
-
app.use(errorHandler.notFoundError);
|
|
45
|
-
|
|
46
|
-
return app;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
//【CDP文档】 https://chromedevtools.github.io/devtools-protocol/tot/Target/
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { OK } from "http-status/lib";
|
|
2
|
-
import { Request, Response, NextFunction } from "express";
|
|
3
|
-
import { getAppInfoQuery } from "../../types/request/home";
|
|
4
|
-
import { apiResponse } from "../../helpers/apiResponse";
|
|
5
|
-
import { HomeServices } from "./services";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 为何为了保证单步模式调试运行"test:watchAll": "cross-env NODE_ENV=development jest --watchAll --runInBand --detectOpenHandles",
|
|
9
|
-
* 只能单独创建一个文件和类PdfController了,不能和HomeController合并在一个类class的俩个并行api处理函数啊?
|
|
10
|
-
* */
|
|
11
|
-
export class HomeController {
|
|
12
|
-
/**
|
|
13
|
-
* @description Gets the API information.
|
|
14
|
-
* @param {Req} req
|
|
15
|
-
* @param {Res} res
|
|
16
|
-
*/
|
|
17
|
-
static getAppInfo = async (
|
|
18
|
-
req: Request,
|
|
19
|
-
res: Response,
|
|
20
|
-
next: NextFunction,
|
|
21
|
-
) => {
|
|
22
|
-
try {
|
|
23
|
-
const appInfoKey = req.query.key as getAppInfoQuery;
|
|
24
|
-
const homeServices = new HomeServices();
|
|
25
|
-
const result = await homeServices.getAppInfo(appInfoKey);
|
|
26
|
-
|
|
27
|
-
res.status(OK).json(apiResponse(result));
|
|
28
|
-
} catch (error) {
|
|
29
|
-
next(error);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { OK } from "http-status/lib";
|
|
2
|
-
import { NextFunction, Request, Response } from "express";
|
|
3
|
-
import { HeadFooter } from "../../types/request/config";
|
|
4
|
-
import { apiResponse } from "../../helpers/apiResponse";
|
|
5
|
-
import { RenderPDF } from "../../utils/pdfgen";
|
|
6
|
-
import CONFIG from "../../configEnv";
|
|
7
|
-
import { ConfigRoot, FileTransform } from "../../types";
|
|
8
|
-
|
|
9
|
-
export class PdfController {
|
|
10
|
-
/** node.js对比前端App 太严格了,一点小毛病页不行啊。
|
|
11
|
-
* @description 生成pdf.
|
|
12
|
-
* @param {Req} req
|
|
13
|
-
* @param {Res} res
|
|
14
|
-
* 正常分解成两大步:task.files每一个文件生成,最后才是task.merge合并(包括页码生成)。
|
|
15
|
-
* @param next
|
|
16
|
-
*/
|
|
17
|
-
static postMakePdf = async (
|
|
18
|
-
req: Request,
|
|
19
|
-
res: Response,
|
|
20
|
-
next: NextFunction,
|
|
21
|
-
) => {
|
|
22
|
-
try {
|
|
23
|
-
// const appInfoKey1 = req.query.key as getAppInfoQuery; 所有打印都走ConfigRoot配置包=task:可能有多个URL合并输出的。
|
|
24
|
-
const task = req.body as ConfigRoot<FileTransform>;
|
|
25
|
-
task.lay as HeadFooter;
|
|
26
|
-
//预处理汇总输出的pdf页眉页脚, 转换页眉页脚的html存储
|
|
27
|
-
if (task.lay) {
|
|
28
|
-
const newfoot = "";
|
|
29
|
-
const formfoot =
|
|
30
|
-
task.lay.foot &&
|
|
31
|
-
newfoot.concat(...task.lay.foot).replaceAll(`\\"`, '"');
|
|
32
|
-
task.footerTemplate = formfoot ?? undefined;
|
|
33
|
-
const formhead =
|
|
34
|
-
task.lay.head &&
|
|
35
|
-
newfoot.concat(...task.lay.head).replaceAll(`\\"`, '"');
|
|
36
|
-
task.headerTemplate = formhead ?? undefined;
|
|
37
|
-
const formfootL =
|
|
38
|
-
task.lay.footL &&
|
|
39
|
-
newfoot.concat(...task.lay.footL).replaceAll(`\\"`, '"');
|
|
40
|
-
task.footerTemplateL = formfootL ?? undefined;
|
|
41
|
-
const formheadL =
|
|
42
|
-
task.lay.headL &&
|
|
43
|
-
newfoot.concat(...task.lay.headL).replaceAll(`\\"`, '"');
|
|
44
|
-
task.headerTemplateL = formheadL ?? undefined;
|
|
45
|
-
}
|
|
46
|
-
//const homeServices = new HomeServices();
|
|
47
|
-
//let result = { ["文件名"]: "产生的.pdf" };
|
|
48
|
-
let result;
|
|
49
|
-
//若是用RenderPDF.generateSinglePdf(会导致没有等待该函数执行结果就会去执行下一步了,应答res,客户端立刻获得http回答,无等待=异步模式的。还是由客户端主动取消等待为佳。这里死等的;
|
|
50
|
-
try {
|
|
51
|
-
//const jobs = generateJobList(urls, pdfs); 分解成多个URL文件多个步骤的情况,可能还有个汇总步骤的:
|
|
52
|
-
// generateSinglePdf mergePdfs pageNoForPdf yeMeiyeJiaoPdf
|
|
53
|
-
if (
|
|
54
|
-
(task.merge === undefined || task.merge) &&
|
|
55
|
-
task.files === undefined &&
|
|
56
|
-
!task.lay
|
|
57
|
-
) {
|
|
58
|
-
await RenderPDF.mergeAllPdfto(); //特殊的特殊? 没有涉及到CDP()函数:
|
|
59
|
-
result = `简易合并输出是: ${CONFIG.APP.MERGE}`;
|
|
60
|
-
} else {
|
|
61
|
-
//有涉及到CDP()函数:
|
|
62
|
-
const renderer = new RenderPDF({}); //提升上来:复用全局的
|
|
63
|
-
if (!task.files || task.files?.length <= 0) {
|
|
64
|
-
console.error("没配置files输入");
|
|
65
|
-
res.status(OK).json(apiResponse({ result: "没配置files输入" }));
|
|
66
|
-
return;
|
|
67
|
-
} else {
|
|
68
|
-
for (const meta of task.files) {
|
|
69
|
-
if (!meta.out) {
|
|
70
|
-
if (meta.url.endsWith(".pdf") && !meta.url.startsWith("http"))
|
|
71
|
-
continue;
|
|
72
|
-
else {
|
|
73
|
-
res
|
|
74
|
-
.status(OK)
|
|
75
|
-
.json(apiResponse({ result: meta.url + " 没配置out" }));
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
//本地pdf情形实际会有webview/iframe的?跳转?,实际会看到pdf之外的浏览控件框框的。 避免再次转换pdf实际捕获窗口并非pdf自身内容;
|
|
80
|
-
if (meta.url.endsWith(".pdf") && !meta.url.startsWith("http"))
|
|
81
|
-
throw new Error(
|
|
82
|
-
"url是本地的pdf文件,不应该设置out参数:" + meta.url,
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
try {
|
|
86
|
-
result = await renderer.generateSinglePdf(meta, task, {});
|
|
87
|
-
} catch (e) {
|
|
88
|
-
result = "算url失败:" + meta.url;
|
|
89
|
-
console.error(e);
|
|
90
|
-
}
|
|
91
|
-
if (result) {
|
|
92
|
-
result = "URL:" + meta.url + " > " + result;
|
|
93
|
-
break; //说明有某种报错
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
//正常的合并阶段的事情: 前一阶段页眉页脚也不打印了。也要放这里了
|
|
98
|
-
if (!result && (task.merge === undefined || task.merge))
|
|
99
|
-
result = await RenderPDF.MergeAllPdfs(task, {});
|
|
100
|
-
//关闭多余窗口
|
|
101
|
-
if (task.closeTab)
|
|
102
|
-
await renderer.closeAllTab(renderer.getCDPhostPort(), task);
|
|
103
|
-
}
|
|
104
|
-
} catch (e) {
|
|
105
|
-
result = "算失败了" + e;
|
|
106
|
-
console.error(e);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (!result || result === "") {
|
|
110
|
-
result = "成功!";
|
|
111
|
-
console.log(result, "输出是:", task.name ?? CONFIG.APP.MERGE);
|
|
112
|
-
}
|
|
113
|
-
res.status(OK).json(apiResponse({ result: result }));
|
|
114
|
-
} catch (error) {
|
|
115
|
-
next(error);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import AppInformation from "../../types/response/AppInformation";
|
|
2
|
-
import { HomeDAO } from "../../db/home";
|
|
3
|
-
import { getAppInfoQuery } from "../../types/request/home";
|
|
4
|
-
|
|
5
|
-
export class HomeServices {
|
|
6
|
-
homeDAO!: HomeDAO;
|
|
7
|
-
constructor() {
|
|
8
|
-
this.homeDAO = new HomeDAO();
|
|
9
|
-
}
|
|
10
|
-
// NAME: pkg.name,
|
|
11
|
-
// VERSION: pkg.version,
|
|
12
|
-
// VER: `v${pkg.version[0]}`,
|
|
13
|
-
// DESCRIPTION: pkg.description,
|
|
14
|
-
// AUTHORS: pkg.authors,
|
|
15
|
-
// HOST: process.env.APP_HOST,
|
|
16
|
-
// BASE_URL: process.env.API_BASE_URL,
|
|
17
|
-
// PORT: process.env.NODE_ENV === "test" ? 8888 : process.env.PORT || 8080,
|
|
18
|
-
// ENV: process.env.NODE_ENV,
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @description Get application information.
|
|
22
|
-
* @returns AppInformation
|
|
23
|
-
*/
|
|
24
|
-
getAppInfo = async (
|
|
25
|
-
appInfoKey?: getAppInfoQuery,
|
|
26
|
-
): Promise<AppInformation> => {
|
|
27
|
-
const result = await this.homeDAO.get(appInfoKey);
|
|
28
|
-
|
|
29
|
-
return result;
|
|
30
|
-
};
|
|
31
|
-
}
|