page2pdf_server 1.1.1 → 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/tsconfig.json +3 -3
- 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 -113
- package/src/components/home/services.ts +0 -31
- package/src/components/home/splitController.ts +0 -125
- 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 -32
- 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
package/src/routes/index.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import {
|
|
3
|
-
HomeController,
|
|
4
|
-
appKeyValidator,
|
|
5
|
-
PdfController,
|
|
6
|
-
SplitController,
|
|
7
|
-
} from "../components/home";
|
|
8
|
-
import { sanitizer } from "../helpers";
|
|
9
|
-
|
|
10
|
-
const router = Router();
|
|
11
|
-
|
|
12
|
-
router.get("/", sanitizer(appKeyValidator), HomeController.getAppInfo);
|
|
13
|
-
//正常都用一个的 post传输的数据量比get大得多;
|
|
14
|
-
//基本都统一入口:
|
|
15
|
-
router.post("/pdf", sanitizer(appKeyValidator), PdfController.postMakePdf);
|
|
16
|
-
|
|
17
|
-
//为了支持拆分pdf操作:
|
|
18
|
-
router.post("/split", sanitizer(appKeyValidator), SplitController.postSplitPdf);
|
|
19
|
-
|
|
20
|
-
export default router;
|
|
21
|
-
|
|
22
|
-
//厂家的文档: https://pdf-lib.js.org/ https://www.npmjs.com/package/pdf-lib
|
package/src/server.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Server, createServer } from "http";
|
|
2
|
-
import e from "express";
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import config from "config";
|
|
5
|
-
import { exitLog } from "./helpers";
|
|
6
|
-
import CONFIG from "./configEnv";
|
|
7
|
-
//自定义服务端口:
|
|
8
|
-
const server_port = config.get("server_port");
|
|
9
|
-
|
|
10
|
-
export const startServer = (app: e.Application): Server => {
|
|
11
|
-
const httpServer = createServer(app);
|
|
12
|
-
|
|
13
|
-
process
|
|
14
|
-
.on("SIGINT", () => exitLog(null, "SIGINT"))
|
|
15
|
-
.on("SIGQUIT", () => exitLog(null, "SIGQUIT"))
|
|
16
|
-
.on("SIGTERM", () => exitLog(null, "SIGTERM"))
|
|
17
|
-
.on("uncaughtException", (err) => exitLog(err, "uncaughtException"))
|
|
18
|
-
.on("beforeExit", () => exitLog(null, "beforeExit"))
|
|
19
|
-
.on("exit", () => exitLog(null, "exit"));
|
|
20
|
-
|
|
21
|
-
//自定义用server_port替代掉 CONFIG.APP.PORT;
|
|
22
|
-
|
|
23
|
-
return httpServer.listen({ port: server_port }, (): void => {
|
|
24
|
-
process.stdout.write(`⚙️ Application Environment: ${CONFIG.APP.ENV}\n`);
|
|
25
|
-
process.stdout.write(`⏱ Started on: ${Date.now()}\n`);
|
|
26
|
-
process.stdout.write(
|
|
27
|
-
`🚀 文书打印转换器启动好 http://localhost:${server_port}\n`,
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
};
|
package/src/testCSS.html
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="robots" content="noindex, nofollow">
|
|
6
|
-
<style>
|
|
7
|
-
body {
|
|
8
|
-
padding: 0;
|
|
9
|
-
margin: 0;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
svg:not(:root) {
|
|
13
|
-
display: block;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.playable-code {
|
|
17
|
-
background-color: #f4f7f8;
|
|
18
|
-
border: none;
|
|
19
|
-
border-left: 6px solid #558abb;
|
|
20
|
-
border-width: medium medium medium 6px;
|
|
21
|
-
color: #4d4e53;
|
|
22
|
-
height: 100px;
|
|
23
|
-
width: 90%;
|
|
24
|
-
padding: 10px 10px 0;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.playable-canvas {
|
|
28
|
-
border: 1px solid #4d4e53;
|
|
29
|
-
border-radius: 2px;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.playable-buttons {
|
|
33
|
-
text-align: right;
|
|
34
|
-
width: 90%;
|
|
35
|
-
padding: 5px 10px 5px 26px;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
|
38
|
-
|
|
39
|
-
<style>
|
|
40
|
-
fieldset {
|
|
41
|
-
display: flex;
|
|
42
|
-
flex-direction: row;
|
|
43
|
-
justify-content: space-between;
|
|
44
|
-
gap: 1rem;
|
|
45
|
-
width: fit-content;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@page toc {
|
|
49
|
-
size: a4 portrait;
|
|
50
|
-
@top-middle {
|
|
51
|
-
content: "Table of contents";
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@page foreword {
|
|
56
|
-
size: a4 portrait;
|
|
57
|
-
@top-middle {
|
|
58
|
-
content: "Foreword";
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@page introduction {
|
|
63
|
-
size: a4 portrait;
|
|
64
|
-
@top-middle {
|
|
65
|
-
content: "Introduction";
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@page conclusion {
|
|
70
|
-
size: a4 portrait;
|
|
71
|
-
@top-middle {
|
|
72
|
-
content: "Conclusion";
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
@page chapter {
|
|
77
|
-
size: a4 landscape;
|
|
78
|
-
@top-middle {
|
|
79
|
-
content: "Chapter";
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@media print {
|
|
84
|
-
fieldset {
|
|
85
|
-
display: none;
|
|
86
|
-
}
|
|
87
|
-
section {
|
|
88
|
-
font-size: 2rem;
|
|
89
|
-
font-family: Roboto;
|
|
90
|
-
}
|
|
91
|
-
.chapter {
|
|
92
|
-
border: tomato 2px solid;
|
|
93
|
-
}
|
|
94
|
-
[data-print="grouped"] > #toc,
|
|
95
|
-
[data-print="paged"] > #toc {
|
|
96
|
-
page: toc;
|
|
97
|
-
font-family: Courier;
|
|
98
|
-
}
|
|
99
|
-
[data-print="grouped"] > #foreword,
|
|
100
|
-
[data-print="paged"] > #foreword {
|
|
101
|
-
page: foreword;
|
|
102
|
-
font-family: Courier;
|
|
103
|
-
}
|
|
104
|
-
[data-print="grouped"] > #introduction,
|
|
105
|
-
[data-print="paged"] > #introduction {
|
|
106
|
-
page: introduction;
|
|
107
|
-
font-family: Courier;
|
|
108
|
-
}
|
|
109
|
-
[data-print="grouped"] > #conclusion,
|
|
110
|
-
[data-print="paged"] > #conclusion {
|
|
111
|
-
page: conclusion;
|
|
112
|
-
font-family: Courier;
|
|
113
|
-
}
|
|
114
|
-
[data-print="grouped"] > .chapter,
|
|
115
|
-
[data-print="paged"] > .chapter {
|
|
116
|
-
page: chapter;
|
|
117
|
-
}
|
|
118
|
-
[data-print="paged"] > .chapter {
|
|
119
|
-
border: none;
|
|
120
|
-
break-after: page;
|
|
121
|
-
}
|
|
122
|
-
.chapter > ul {
|
|
123
|
-
columns: 2;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
</style>
|
|
128
|
-
|
|
129
|
-
<title>page - named_page_example - code sample</title>
|
|
130
|
-
|
|
131
|
-
</head>
|
|
132
|
-
<body>
|
|
133
|
-
|
|
134
|
-
<!-- print options 文档看 https://developer.mozilla.org/en-US/docs/Web/CSS/page#named_page_example
|
|
135
|
-
[data-print="paged"] > .chapter { 属性选择符号?
|
|
136
|
-
-->
|
|
137
|
-
|
|
138
|
-
<fieldset id="printStyle">
|
|
139
|
-
<legend>How would you like to print</legend>
|
|
140
|
-
<label for="single"
|
|
141
|
-
><input type="radio" id="single" name="type" value="single" checked />No
|
|
142
|
-
Pages</label
|
|
143
|
-
>
|
|
144
|
-
<label for="grouped"
|
|
145
|
-
><input type="radio" id="grouped" name="type" value="grouped" />Pages with
|
|
146
|
-
Grouped Chapters</label
|
|
147
|
-
>
|
|
148
|
-
<label for="paged"
|
|
149
|
-
><input type="radio" id="paged" name="type" value="paged" />Chapters
|
|
150
|
-
Paged</label
|
|
151
|
-
>
|
|
152
|
-
<button id="print">Print</button>
|
|
153
|
-
</fieldset>
|
|
154
|
-
<!-- Content to be printed -->
|
|
155
|
-
<article id="print-area" data-print="single">
|
|
156
|
-
<section id="toc">
|
|
157
|
-
<h2>Table of contents</h2>
|
|
158
|
-
<ul>
|
|
159
|
-
<li>Foreword</li>
|
|
160
|
-
<li>Introduction</li>
|
|
161
|
-
<li>Chapter One - named pages</li>
|
|
162
|
-
<li>Chapter Two - page orientation</li>
|
|
163
|
-
<li>Chapter Three - page margins</li>
|
|
164
|
-
<li>Conclusion</li>
|
|
165
|
-
</ul>
|
|
166
|
-
</section>
|
|
167
|
-
<section id="foreword">
|
|
168
|
-
<h2>Foreword</h2>
|
|
169
|
-
<p>
|
|
170
|
-
This book is all about how the CSS <code>@page</code> at-rule can help
|
|
171
|
-
with printing HTML books.
|
|
172
|
-
</p>
|
|
173
|
-
</section>
|
|
174
|
-
<section id="introduction">
|
|
175
|
-
<h2>Introduction</h2>
|
|
176
|
-
<p>
|
|
177
|
-
This book is a concept to show how an <em>HTML</em> document can easily be
|
|
178
|
-
printed out in pages.
|
|
179
|
-
</p>
|
|
180
|
-
</section>
|
|
181
|
-
<section id="chapter1" class="chapter">
|
|
182
|
-
<h2>Named pages</h2>
|
|
183
|
-
<p>Lorem ipsum</p>
|
|
184
|
-
</section>
|
|
185
|
-
<section id="chapter2" class="chapter">
|
|
186
|
-
<h2>Page Orientation</h2>
|
|
187
|
-
<p>Lorem ipsum</p>
|
|
188
|
-
</section>
|
|
189
|
-
<section id="chapter3" class="chapter">
|
|
190
|
-
<h2>Page Margins</h2>
|
|
191
|
-
<p>There are 16 page margins that can be set:</p>
|
|
192
|
-
<ul>
|
|
193
|
-
<li>@top-left-corner</li>
|
|
194
|
-
<li>@top-left</li>
|
|
195
|
-
<li>@top-middle</li>
|
|
196
|
-
<li>@top-right</li>
|
|
197
|
-
<li>@top-right-corner</li>
|
|
198
|
-
<li>@left-top</li>
|
|
199
|
-
<li>@left-middle</li>
|
|
200
|
-
<li>@left-bottom</li>
|
|
201
|
-
<li>@right-top</li>
|
|
202
|
-
<li>@right-middle</li>
|
|
203
|
-
<li>@right-bottom</li>
|
|
204
|
-
<li>@bottom-left-corner</li>
|
|
205
|
-
<li>@bottom-left</li>
|
|
206
|
-
<li>@bottom-middle</li>
|
|
207
|
-
<li>@bottom-right</li>
|
|
208
|
-
<li>@bottom-right-corner</li>
|
|
209
|
-
</ul>
|
|
210
|
-
<p>They can be used to show what appears in these parts of the margin</p>
|
|
211
|
-
</section>
|
|
212
|
-
<section id="conclusion">
|
|
213
|
-
<h2>Conclusion</h2>
|
|
214
|
-
<p>Now go ahead and write books.</p>
|
|
215
|
-
</section>
|
|
216
|
-
</article>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
<script>
|
|
221
|
-
const printArea = document.querySelector("#print-area");
|
|
222
|
-
const printButton = document.querySelector("#print");
|
|
223
|
-
const printOption = document.querySelector("#printStyle");
|
|
224
|
-
printOption.addEventListener("change", (event) => {
|
|
225
|
-
//对调paged single: ?? .dataset.print如何变身 data-print="single"属性值的??
|
|
226
|
-
if (event.target.value === "single") {
|
|
227
|
-
printArea.dataset.print = "paged";
|
|
228
|
-
} else if (event.target.value === "grouped") {
|
|
229
|
-
printArea.dataset.print = "grouped";
|
|
230
|
-
} else {
|
|
231
|
-
printArea.dataset.print = "single";
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
printButton.addEventListener("click", () => {
|
|
235
|
-
window.print();
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
</script>
|
|
239
|
-
|
|
240
|
-
</body>
|
|
241
|
-
</html>
|
package/src/types/global.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
type TodoType = any;
|
|
5
|
-
type Req = Request;
|
|
6
|
-
type Res = Response;
|
|
7
|
-
type NextFn = NextFunction;
|
|
8
|
-
type ResponseData<T> = {
|
|
9
|
-
opcode: number;
|
|
10
|
-
message: string;
|
|
11
|
-
data?: T;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**拆分大的pdf文件,输出部分页数的小的pdf
|
|
2
|
-
* 支持按pdf纸张页面进行重新排序, 部分提取页数。
|
|
3
|
-
* */
|
|
4
|
-
export interface SplitConfig {
|
|
5
|
-
//等待拆分大的df文件名, 需要加 .pdf结尾的;只能是pdf文档!
|
|
6
|
-
input: string;
|
|
7
|
-
//每一个独立的pdf生成:
|
|
8
|
-
files: [SplitPdfFile];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface SplitPdfFile {
|
|
12
|
-
//定义部分页面输出的。 Paper ranges to print, one based, e.g., '1-5, 8, 11-13'.
|
|
13
|
-
pageRanges: string;
|
|
14
|
-
//输出本地工作目录的文件名, 不需要加 .pdf结尾的。
|
|
15
|
-
//【特别】必须配置唯一性 的本地 工作目录的文件名,同名的被直接覆盖了。
|
|
16
|
-
//拆分提取的pdf输出页面顺序是依据pageRanges所选定的顺序来输出的,不是原本pdf的顺序。
|
|
17
|
-
out: string;
|
|
18
|
-
}
|
package/src/utils/array.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { differenceWith, isEqual } from "lodash-es";
|
|
2
|
-
|
|
3
|
-
export interface ArrayDifference {
|
|
4
|
-
added: any[];
|
|
5
|
-
removed: any[];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {any[]} arr1
|
|
11
|
-
* @param {any[]} arr2
|
|
12
|
-
* @returns {ArrayDifference}
|
|
13
|
-
*/
|
|
14
|
-
export const diff = (arr1: any[], arr2: any[]): ArrayDifference => {
|
|
15
|
-
const added = differenceWith(arr2, arr1, isEqual);
|
|
16
|
-
const removed = differenceWith(arr1, arr2, isEqual);
|
|
17
|
-
|
|
18
|
-
return { added, removed };
|
|
19
|
-
};
|
package/src/utils/auth.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description hide password content with '*'
|
|
3
|
-
* @param {object} bodyData
|
|
4
|
-
* @returns bodyData with formatted 'password'
|
|
5
|
-
*/
|
|
6
|
-
export const hidePassword = (bodyData: Record<string, any>) => {
|
|
7
|
-
if (bodyData.hasOwnProperty("password")) {
|
|
8
|
-
bodyData.password = "********";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
return bodyData;
|
|
12
|
-
};
|
package/src/utils/crypt.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// import bcrypt from "bcrypt";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @description Create a bcrypt hash for a string.
|
|
5
|
-
* @param {string} value
|
|
6
|
-
* @returns {Promise<any>}
|
|
7
|
-
*/
|
|
8
|
-
// export const hash = async (value: string): Promise<any> => {
|
|
9
|
-
// const saltRounds = parseInt(CONFIG.AUTH.SALT_ROUNDS, 10);
|
|
10
|
-
//
|
|
11
|
-
// return bcrypt.hash(value, saltRounds);
|
|
12
|
-
// };
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @description Compare a string with the hash.
|
|
16
|
-
* @param {string} value
|
|
17
|
-
* @param {string} hashedValue
|
|
18
|
-
* @returns {Promise<boolean>}
|
|
19
|
-
*/
|
|
20
|
-
// export const compare = async (
|
|
21
|
-
// value: string,
|
|
22
|
-
// hashedValue: string,
|
|
23
|
-
// ): Promise<boolean> => {
|
|
24
|
-
// return bcrypt.compare(value, hashedValue);
|
|
25
|
-
// };
|
package/src/utils/filter.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Converts empty value to null.
|
|
3
|
-
*
|
|
4
|
-
* @param obj
|
|
5
|
-
* @returns {*}
|
|
6
|
-
*/
|
|
7
|
-
export const emptyToNull = (obj: any): any => {
|
|
8
|
-
if (isScalarType(obj)) {
|
|
9
|
-
return obj;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (Array.isArray(obj)) {
|
|
13
|
-
return obj.map(emptyToNull);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const result: any = {};
|
|
17
|
-
|
|
18
|
-
for (const key of Object.keys(obj)) {
|
|
19
|
-
const value = obj[key];
|
|
20
|
-
|
|
21
|
-
if (typeof value === "object") {
|
|
22
|
-
result[key] = emptyToNull(value);
|
|
23
|
-
} else {
|
|
24
|
-
result[key] = nullIfEmpty(value);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return result;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Returns if scalar type.
|
|
33
|
-
*
|
|
34
|
-
* @param obj
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
const isScalarType = (obj: any) => {
|
|
38
|
-
return (
|
|
39
|
-
typeof obj !== "object" ||
|
|
40
|
-
obj instanceof String ||
|
|
41
|
-
obj instanceof Number ||
|
|
42
|
-
obj instanceof Boolean ||
|
|
43
|
-
obj === null
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Changes empty value to null.
|
|
49
|
-
*
|
|
50
|
-
* @param value
|
|
51
|
-
* @returns {*}
|
|
52
|
-
*/
|
|
53
|
-
const nullIfEmpty = (value: any) => {
|
|
54
|
-
if (typeof value !== "string") {
|
|
55
|
-
return value;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return value.trim() === "" ? null : value;
|
|
59
|
-
};
|
package/src/utils/object.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { differenceBy, intersectionBy } from "lodash-es";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Get the copy of object without attributes.
|
|
5
|
-
*
|
|
6
|
-
* @param {Object} obj
|
|
7
|
-
* @param {Array} attrsToExclude
|
|
8
|
-
* @return {Object}
|
|
9
|
-
*/
|
|
10
|
-
export const withoutAttrs = (obj: any, attrsToExclude: any[]) => {
|
|
11
|
-
const result: any = {};
|
|
12
|
-
|
|
13
|
-
Object.keys(obj).forEach((key: string) => {
|
|
14
|
-
if (!attrsToExclude.includes(key)) {
|
|
15
|
-
result[key] = obj[key];
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get the copy of object with only specified attributes.
|
|
24
|
-
*
|
|
25
|
-
* @param {Object} obj
|
|
26
|
-
* @param {Array} attrs
|
|
27
|
-
* @return {Object}
|
|
28
|
-
*/
|
|
29
|
-
export const withOnlyAttrs = (obj: any, attrs: any[]) => {
|
|
30
|
-
const result: any = {};
|
|
31
|
-
|
|
32
|
-
Object.keys(obj).forEach((key) => {
|
|
33
|
-
if (attrs.includes(key)) {
|
|
34
|
-
result[key] = obj[key];
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Compare array of two objects and find data that needs to be create, update
|
|
43
|
-
* and delete.
|
|
44
|
-
*
|
|
45
|
-
* @param {Array} list1
|
|
46
|
-
* @param {Array} list2
|
|
47
|
-
* @param {String} key
|
|
48
|
-
* @returns {Object}
|
|
49
|
-
*/
|
|
50
|
-
export const difference = (list1: any[], list2: any[], key = "id") => {
|
|
51
|
-
return {
|
|
52
|
-
create: list2
|
|
53
|
-
.filter((obj) => obj.hasOwnProperty(key) && obj[key] === null)
|
|
54
|
-
.map((obj) => withoutAttrs(obj, [key])),
|
|
55
|
-
update: intersectionBy(list2, list1, key),
|
|
56
|
-
destroy: differenceBy(list1, list2, key).map((obj: any) => obj[key]),
|
|
57
|
-
};
|
|
58
|
-
};
|