zero-tools 1.3.7 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.ts +57 -37
- package/dist/bin.js +82 -7
- package/dist/tinify.js +409 -0
- package/package.json +3 -2
- package/tinify.ts +252 -0
- package/.vscode/tasks.json +0 -14
package/bin.ts
CHANGED
|
@@ -4,30 +4,36 @@ import minimist = require('minimist')
|
|
|
4
4
|
import * as fs from 'fs'
|
|
5
5
|
import * as path from 'path'
|
|
6
6
|
import { xlsxToTs } from './xlsx-ts';
|
|
7
|
+
import { TaskParser } from './tinify';
|
|
7
8
|
let cwd = process.cwd()
|
|
8
9
|
let name = path.basename(cwd)
|
|
9
10
|
let argv = minimist(process.argv.slice(2), {
|
|
10
11
|
// string: ['unitTesting'],
|
|
11
|
-
boolean: ['help', 'version', 'unitTesting', "xlsxToTs"],
|
|
12
|
+
boolean: ['help', 'version', 'unitTesting', "xlsxToTs", "tinify", "packHotup"],
|
|
12
13
|
alias: {
|
|
13
14
|
unitTesting: ['ut'],
|
|
15
|
+
packHotup: ['pp'],
|
|
16
|
+
tinify: ['ty'],
|
|
14
17
|
xlsxToTs: ['xt'],
|
|
15
18
|
help: ['h'],
|
|
16
19
|
version: ['v'],
|
|
17
20
|
}
|
|
18
21
|
})
|
|
19
22
|
|
|
20
|
-
let packageTem =
|
|
21
|
-
|
|
23
|
+
let packageTem = `
|
|
24
|
+
{
|
|
22
25
|
"name": "${name}",
|
|
23
26
|
"version": "1.0.0",
|
|
24
27
|
"description": "",
|
|
25
|
-
"main": "
|
|
28
|
+
"main": "index.ts",
|
|
26
29
|
"scripts": {
|
|
30
|
+
"debug": "ts-node-dev index.ts"
|
|
27
31
|
},
|
|
28
32
|
"author": "",
|
|
29
33
|
"license": "ISC",
|
|
30
|
-
"dependencies": {
|
|
34
|
+
"dependencies": {},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"ts-node-dev": "^1.1.6"
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
`
|
|
@@ -92,14 +98,12 @@ let tsconfigTem =
|
|
|
92
98
|
}
|
|
93
99
|
`
|
|
94
100
|
|
|
95
|
-
let indexTem =
|
|
96
|
-
`
|
|
101
|
+
let indexTem = `
|
|
97
102
|
let a="test"
|
|
98
103
|
console.log(a)
|
|
99
104
|
`
|
|
100
105
|
|
|
101
|
-
let cwsTem =
|
|
102
|
-
`
|
|
106
|
+
let cwsTem = `
|
|
103
107
|
{
|
|
104
108
|
"folders": [
|
|
105
109
|
{
|
|
@@ -109,43 +113,28 @@ let cwsTem =
|
|
|
109
113
|
"settings": {}
|
|
110
114
|
}
|
|
111
115
|
`
|
|
112
|
-
|
|
113
|
-
let taskTem =
|
|
114
|
-
`
|
|
115
|
-
{
|
|
116
|
-
"version": "2.0.0",
|
|
117
|
-
"tasks": [
|
|
118
|
-
{
|
|
119
|
-
"label": "tsc",
|
|
120
|
-
"type": "typescript",
|
|
121
|
-
"tsconfig": "tsconfig.json",
|
|
122
|
-
"problemMatcher": [
|
|
123
|
-
"$tsc"
|
|
124
|
-
]
|
|
125
|
-
}
|
|
126
|
-
]
|
|
127
|
-
}
|
|
128
|
-
`
|
|
129
|
-
let launchTem =
|
|
130
|
-
`
|
|
116
|
+
let launchTem = `
|
|
131
117
|
{
|
|
132
118
|
"version": "0.2.0",
|
|
133
119
|
"configurations": [
|
|
134
120
|
{
|
|
135
121
|
"type": "node",
|
|
136
122
|
"request": "launch",
|
|
137
|
-
"name": "
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
|
|
123
|
+
"name": "启动",
|
|
124
|
+
"runtimeExecutable": "yarn",
|
|
125
|
+
"args": [
|
|
126
|
+
"debug",
|
|
127
|
+
],
|
|
128
|
+
},
|
|
141
129
|
]
|
|
142
130
|
}
|
|
143
131
|
`
|
|
144
|
-
let helpString =
|
|
145
|
-
`
|
|
132
|
+
let helpString = `
|
|
146
133
|
----------------------开发工具包-----------------------
|
|
147
134
|
zero ut (zero --unitTesting)在当前文件夹新建TS单元测试项目
|
|
148
135
|
zero xt (zero --xlsxToTs)在当前文件夹下的xlsx.json中所描述的Excel文件转换TS文件
|
|
136
|
+
zero ty (zero --tinify)在当前文件夹下的tinify.json中所描述的文件进行压缩
|
|
137
|
+
zero pp (zero --packHotup)在当前文件夹下的packHotup.json中所描述的文件进行打包热更新
|
|
149
138
|
zero h (zero --help)帮助
|
|
150
139
|
zero v (zero --version)版本号
|
|
151
140
|
----------------------蓝面包 制作----------------------`
|
|
@@ -159,7 +148,6 @@ let fn = {
|
|
|
159
148
|
if (!fs.existsSync(cwd + "/.vscode")) {
|
|
160
149
|
fs.mkdirSync(cwd + "/.vscode")
|
|
161
150
|
}
|
|
162
|
-
fs.writeFileSync(cwd + "/.vscode/tasks.json", taskTem)
|
|
163
151
|
fs.writeFileSync(cwd + "/.vscode/launch.json", launchTem)
|
|
164
152
|
},
|
|
165
153
|
xt: () => {
|
|
@@ -181,7 +169,7 @@ let fn = {
|
|
|
181
169
|
data.forEach(ExcelName => {
|
|
182
170
|
if (ExcelName.substr(-5) == ".xlsx" && ExcelName.substr(0, 1) != "~") {
|
|
183
171
|
let FileDir: string = `${xlsxPath}/${ExcelName}`
|
|
184
|
-
xlsxToTs(FileDir, tsPath, checkCell, startCell,note)
|
|
172
|
+
xlsxToTs(FileDir, tsPath, checkCell, startCell, note)
|
|
185
173
|
console.log(`${ExcelName}`)
|
|
186
174
|
}
|
|
187
175
|
})
|
|
@@ -189,11 +177,35 @@ let fn = {
|
|
|
189
177
|
}
|
|
190
178
|
})
|
|
191
179
|
},
|
|
180
|
+
ty: () => {
|
|
181
|
+
|
|
182
|
+
// let p = new TaskParser("../../doomsdayrise-clinet/tinify.json")
|
|
183
|
+
let p = new TaskParser("./tinify.json")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
async function test() {
|
|
187
|
+
await p.parserConfig()
|
|
188
|
+
await p.loadInfo()
|
|
189
|
+
await p.readDir("")
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
test().then(() => {
|
|
193
|
+
console.log("完成")
|
|
194
|
+
}).catch((err) => {
|
|
195
|
+
console.log("错误", err)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
},
|
|
201
|
+
pp: () => {
|
|
202
|
+
console.log("to do pp")
|
|
203
|
+
},
|
|
192
204
|
h: () => {
|
|
193
205
|
console.log(helpString)
|
|
194
206
|
},
|
|
195
207
|
v: () => {
|
|
196
|
-
console.log("1.
|
|
208
|
+
console.log("1.4.0")
|
|
197
209
|
}
|
|
198
210
|
}
|
|
199
211
|
let isFree = true
|
|
@@ -205,6 +217,14 @@ if (argv.xt) {
|
|
|
205
217
|
fn.xt()
|
|
206
218
|
isFree = false
|
|
207
219
|
}
|
|
220
|
+
if (argv.ty) {
|
|
221
|
+
fn.ty()
|
|
222
|
+
isFree = false
|
|
223
|
+
}
|
|
224
|
+
if (argv.pp) {
|
|
225
|
+
fn.pp()
|
|
226
|
+
isFree = false
|
|
227
|
+
}
|
|
208
228
|
if (argv.h) {
|
|
209
229
|
fn.h()
|
|
210
230
|
isFree = false
|
package/dist/bin.js
CHANGED
|
@@ -19,30 +19,68 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
19
19
|
__setModuleDefault(result, mod);
|
|
20
20
|
return result;
|
|
21
21
|
};
|
|
22
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
23
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
24
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
25
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
26
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
27
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
28
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
32
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
33
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
34
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
35
|
+
function step(op) {
|
|
36
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
37
|
+
while (_) try {
|
|
38
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
39
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
40
|
+
switch (op[0]) {
|
|
41
|
+
case 0: case 1: t = op; break;
|
|
42
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
43
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
44
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
45
|
+
default:
|
|
46
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
47
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
48
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
49
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
50
|
+
if (t[2]) _.ops.pop();
|
|
51
|
+
_.trys.pop(); continue;
|
|
52
|
+
}
|
|
53
|
+
op = body.call(thisArg, _);
|
|
54
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
55
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
22
58
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
59
|
var minimist = require("minimist");
|
|
24
60
|
var fs = __importStar(require("fs"));
|
|
25
61
|
var path = __importStar(require("path"));
|
|
26
62
|
var xlsx_ts_1 = require("./xlsx-ts");
|
|
63
|
+
var tinify_1 = require("./tinify");
|
|
27
64
|
var cwd = process.cwd();
|
|
28
65
|
var name = path.basename(cwd);
|
|
29
66
|
var argv = minimist(process.argv.slice(2), {
|
|
30
67
|
// string: ['unitTesting'],
|
|
31
|
-
boolean: ['help', 'version', 'unitTesting', "xlsxToTs"],
|
|
68
|
+
boolean: ['help', 'version', 'unitTesting', "xlsxToTs", "tinify", "packHotup"],
|
|
32
69
|
alias: {
|
|
33
70
|
unitTesting: ['ut'],
|
|
71
|
+
packHotup: ['pp'],
|
|
72
|
+
tinify: ['ty'],
|
|
34
73
|
xlsxToTs: ['xt'],
|
|
35
74
|
help: ['h'],
|
|
36
75
|
version: ['v'],
|
|
37
76
|
}
|
|
38
77
|
});
|
|
39
|
-
var packageTem = "{\n \"name\": \"" + name + "\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"
|
|
78
|
+
var packageTem = "\n{\n \"name\": \"" + name + "\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.ts\",\n \"scripts\": {\n \"debug\": \"ts-node-dev index.ts\"\n },\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {},\n \"devDependencies\": {\n \"ts-node-dev\": \"^1.1.6\"\n }\n}\n";
|
|
40
79
|
var tsconfigTem = "\n{\n \"compilerOptions\": {\n /* Basic Options */\n \"target\": \"es5\", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */\n \"module\": \"commonjs\", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */\n // \"lib\": [], /* Specify library files to be included in the compilation. */\n // \"allowJs\": true, /* Allow javascript files to be compiled. */\n // \"checkJs\": true, /* Report errors in .js files. */\n // \"jsx\": \"preserve\", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */\n // \"declaration\": true, /* Generates corresponding '.d.ts' file. */\n \"sourceMap\": true, /* Generates corresponding '.map' file. */\n // \"outFile\": \"./\", /* Concatenate and emit output to single file. */\n \"outDir\": \"./dist\", /* Redirect output structure to the directory. */\n // \"rootDir\": \"./\", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n // \"removeComments\": true, /* Do not emit comments to output. */\n // \"noEmit\": true, /* Do not emit outputs. */\n // \"importHelpers\": true, /* Import emit helpers from 'tslib'. */\n // \"downlevelIteration\": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n // \"isolatedModules\": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n \n /* Strict Type-Checking Options */\n \"strict\": true, /* Enable all strict type-checking options. */\n // \"noImplicitAny\": true, /* Raise error on expressions and declarations with an implied 'any' type. */\n // \"strictNullChecks\": true, /* Enable strict null checks. */\n // \"strictFunctionTypes\": true, /* Enable strict checking of function types. */\n // \"strictPropertyInitialization\": true, /* Enable strict checking of property initialization in classes. */\n // \"noImplicitThis\": true, /* Raise error on 'this' expressions with an implied 'any' type. */\n // \"alwaysStrict\": true, /* Parse in strict mode and emit \"use strict\" for each source file. */\n \n /* Additional Checks */\n // \"noUnusedLocals\": true, /* Report errors on unused locals. */\n // \"noUnusedParameters\": true, /* Report errors on unused parameters. */\n // \"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n // \"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n \n /* Module Resolution Options */\n // \"moduleResolution\": \"node\", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */\n // \"baseUrl\": \"./\", /* Base directory to resolve non-absolute module names. */\n // \"paths\": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n // \"rootDirs\": [], /* List of root folders whose combined content represents the structure of the project at runtime. */\n // \"typeRoots\": [], /* List of folders to include type definitions from. */\n // \"types\": [], /* Type declaration files to be included in compilation. */\n // \"allowSyntheticDefaultImports\": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n \"esModuleInterop\": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */\n // \"preserveSymlinks\": true, /* Do not resolve the real path of symlinks. */\n \n /* Source Map Options */\n // \"sourceRoot\": \"./\", /* Specify the location where debugger should locate TypeScript files instead of source locations. */\n // \"mapRoot\": \"./\", /* Specify the location where debugger should locate map files instead of generated locations. */\n // \"inlineSourceMap\": true, /* Emit a single file with source maps instead of having a separate file. */\n // \"inlineSources\": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */\n \n /* Experimental Options */\n // \"experimentalDecorators\": true, /* Enables experimental support for ES7 decorators. */\n // \"emitDecoratorMetadata\": true, /* Enables experimental support for emitting type metadata for decorators. */\n }\n }\n";
|
|
41
80
|
var indexTem = "\nlet a=\"test\"\nconsole.log(a)\n";
|
|
42
81
|
var cwsTem = "\n{\n\t\"folders\": [\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t}\n\t],\n\t\"settings\": {}\n}\n";
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var helpString = "\n----------------------\u5F00\u53D1\u5DE5\u5177\u5305-----------------------\nzero ut (zero --unitTesting)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u65B0\u5EFATS\u5355\u5143\u6D4B\u8BD5\u9879\u76EE\nzero xt (zero --xlsxToTs)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u4E0B\u7684xlsx.json\u4E2D\u6240\u63CF\u8FF0\u7684Excel\u6587\u4EF6\u8F6C\u6362TS\u6587\u4EF6\nzero h (zero --help)\u5E2E\u52A9\nzero v (zero --version)\u7248\u672C\u53F7\n----------------------\u84DD\u9762\u5305 \u5236\u4F5C----------------------";
|
|
82
|
+
var launchTem = "\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"type\": \"node\",\n \"request\": \"launch\",\n \"name\": \"\u542F\u52A8\",\n \"runtimeExecutable\": \"yarn\",\n \"args\": [\n \"debug\",\n ],\n },\n ]\n}\n";
|
|
83
|
+
var helpString = "\n----------------------\u5F00\u53D1\u5DE5\u5177\u5305-----------------------\nzero ut (zero --unitTesting)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u65B0\u5EFATS\u5355\u5143\u6D4B\u8BD5\u9879\u76EE\nzero xt (zero --xlsxToTs)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u4E0B\u7684xlsx.json\u4E2D\u6240\u63CF\u8FF0\u7684Excel\u6587\u4EF6\u8F6C\u6362TS\u6587\u4EF6\nzero ty (zero --tinify)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u4E0B\u7684tinify.json\u4E2D\u6240\u63CF\u8FF0\u7684\u6587\u4EF6\u8FDB\u884C\u538B\u7F29\nzero pp (zero --packHotup)\u5728\u5F53\u524D\u6587\u4EF6\u5939\u4E0B\u7684packHotup.json\u4E2D\u6240\u63CF\u8FF0\u7684\u6587\u4EF6\u8FDB\u884C\u6253\u5305\u70ED\u66F4\u65B0\nzero h (zero --help)\u5E2E\u52A9\nzero v (zero --version)\u7248\u672C\u53F7\n----------------------\u84DD\u9762\u5305 \u5236\u4F5C----------------------";
|
|
46
84
|
var fn = {
|
|
47
85
|
ut: function () {
|
|
48
86
|
fs.writeFileSync(cwd + "/package.json", packageTem);
|
|
@@ -52,7 +90,6 @@ var fn = {
|
|
|
52
90
|
if (!fs.existsSync(cwd + "/.vscode")) {
|
|
53
91
|
fs.mkdirSync(cwd + "/.vscode");
|
|
54
92
|
}
|
|
55
|
-
fs.writeFileSync(cwd + "/.vscode/tasks.json", taskTem);
|
|
56
93
|
fs.writeFileSync(cwd + "/.vscode/launch.json", launchTem);
|
|
57
94
|
},
|
|
58
95
|
xt: function () {
|
|
@@ -83,11 +120,41 @@ var fn = {
|
|
|
83
120
|
}
|
|
84
121
|
});
|
|
85
122
|
},
|
|
123
|
+
ty: function () {
|
|
124
|
+
// let p = new TaskParser("../../doomsdayrise-clinet/tinify.json")
|
|
125
|
+
var p = new tinify_1.TaskParser("./tinify.json");
|
|
126
|
+
function test() {
|
|
127
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
128
|
+
return __generator(this, function (_a) {
|
|
129
|
+
switch (_a.label) {
|
|
130
|
+
case 0: return [4 /*yield*/, p.parserConfig()];
|
|
131
|
+
case 1:
|
|
132
|
+
_a.sent();
|
|
133
|
+
return [4 /*yield*/, p.loadInfo()];
|
|
134
|
+
case 2:
|
|
135
|
+
_a.sent();
|
|
136
|
+
return [4 /*yield*/, p.readDir("")];
|
|
137
|
+
case 3:
|
|
138
|
+
_a.sent();
|
|
139
|
+
return [2 /*return*/];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
test().then(function () {
|
|
145
|
+
console.log("完成");
|
|
146
|
+
}).catch(function (err) {
|
|
147
|
+
console.log("错误", err);
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
pp: function () {
|
|
151
|
+
console.log("to do pp");
|
|
152
|
+
},
|
|
86
153
|
h: function () {
|
|
87
154
|
console.log(helpString);
|
|
88
155
|
},
|
|
89
156
|
v: function () {
|
|
90
|
-
console.log("1.
|
|
157
|
+
console.log("1.4.0");
|
|
91
158
|
}
|
|
92
159
|
};
|
|
93
160
|
var isFree = true;
|
|
@@ -99,6 +166,14 @@ if (argv.xt) {
|
|
|
99
166
|
fn.xt();
|
|
100
167
|
isFree = false;
|
|
101
168
|
}
|
|
169
|
+
if (argv.ty) {
|
|
170
|
+
fn.ty();
|
|
171
|
+
isFree = false;
|
|
172
|
+
}
|
|
173
|
+
if (argv.pp) {
|
|
174
|
+
fn.pp();
|
|
175
|
+
isFree = false;
|
|
176
|
+
}
|
|
102
177
|
if (argv.h) {
|
|
103
178
|
fn.h();
|
|
104
179
|
isFree = false;
|
package/dist/tinify.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
31
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
32
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
33
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
34
|
+
function step(op) {
|
|
35
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
36
|
+
while (_) try {
|
|
37
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
38
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
39
|
+
switch (op[0]) {
|
|
40
|
+
case 0: case 1: t = op; break;
|
|
41
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
42
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
43
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
44
|
+
default:
|
|
45
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
46
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
47
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
48
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
49
|
+
if (t[2]) _.ops.pop();
|
|
50
|
+
_.trys.pop(); continue;
|
|
51
|
+
}
|
|
52
|
+
op = body.call(thisArg, _);
|
|
53
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
54
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.TaskParser = void 0;
|
|
59
|
+
var fs = __importStar(require("fs"));
|
|
60
|
+
var path = __importStar(require("path"));
|
|
61
|
+
var tinify = __importStar(require("tinify"));
|
|
62
|
+
var crypto = __importStar(require("crypto"));
|
|
63
|
+
/**
|
|
64
|
+
* 忽略含有命名为
|
|
65
|
+
* atlas8
|
|
66
|
+
* atlas9
|
|
67
|
+
* 忽略 20000 字节以下的文件
|
|
68
|
+
*/
|
|
69
|
+
var TaskParser = /** @class */ (function () {
|
|
70
|
+
function TaskParser(tinfiyUrl) {
|
|
71
|
+
this.tinfiyUrl = tinfiyUrl;
|
|
72
|
+
this.count = 0;
|
|
73
|
+
this.tinfiyUrlInfo = path.parse(tinfiyUrl);
|
|
74
|
+
}
|
|
75
|
+
TaskParser.prototype.loadInfo = function () {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
77
|
+
var buffer;
|
|
78
|
+
return __generator(this, function (_a) {
|
|
79
|
+
switch (_a.label) {
|
|
80
|
+
case 0: return [4 /*yield*/, this.readBuffer(this.config.info)];
|
|
81
|
+
case 1:
|
|
82
|
+
buffer = _a.sent();
|
|
83
|
+
this.info = JSON.parse(buffer.toString('utf-8'));
|
|
84
|
+
return [2 /*return*/];
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
TaskParser.prototype.saveInfo = function () {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
91
|
+
return __generator(this, function (_a) {
|
|
92
|
+
this.witeBuffer(this.config.info, JSON.stringify(this.info, null, 4));
|
|
93
|
+
return [2 /*return*/];
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
TaskParser.prototype.idDir = function (pathUrl) {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
99
|
+
var _this = this;
|
|
100
|
+
return __generator(this, function (_a) {
|
|
101
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
102
|
+
fs.stat(path.join(_this.config.inPath, pathUrl), function (err, stats) {
|
|
103
|
+
if (err) {
|
|
104
|
+
reject(err);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
resolve(stats.isDirectory());
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
})];
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
TaskParser.prototype.readDir = function (pathUrl) {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
116
|
+
var data, index, element, isDir, info;
|
|
117
|
+
return __generator(this, function (_a) {
|
|
118
|
+
switch (_a.label) {
|
|
119
|
+
case 0: return [4 /*yield*/, this.readDirData(pathUrl)];
|
|
120
|
+
case 1:
|
|
121
|
+
data = _a.sent();
|
|
122
|
+
index = 0;
|
|
123
|
+
_a.label = 2;
|
|
124
|
+
case 2:
|
|
125
|
+
if (!(index < data.length)) return [3 /*break*/, 8];
|
|
126
|
+
element = path.join(pathUrl, data[index]);
|
|
127
|
+
return [4 /*yield*/, this.idDir(element)];
|
|
128
|
+
case 3:
|
|
129
|
+
isDir = _a.sent();
|
|
130
|
+
if (!isDir) return [3 /*break*/, 5];
|
|
131
|
+
return [4 /*yield*/, this.readDir(element)];
|
|
132
|
+
case 4:
|
|
133
|
+
_a.sent();
|
|
134
|
+
return [3 /*break*/, 7];
|
|
135
|
+
case 5:
|
|
136
|
+
info = path.parse(element);
|
|
137
|
+
if (!(info.ext == ".png")) return [3 /*break*/, 7];
|
|
138
|
+
return [4 /*yield*/, this.pick(element)];
|
|
139
|
+
case 6:
|
|
140
|
+
_a.sent();
|
|
141
|
+
_a.label = 7;
|
|
142
|
+
case 7:
|
|
143
|
+
index++;
|
|
144
|
+
return [3 /*break*/, 2];
|
|
145
|
+
case 8: return [2 /*return*/];
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
TaskParser.prototype.pick = function (element) {
|
|
151
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
152
|
+
var inPath, outPath, info, reg, buffer, md5, code, _a, doc;
|
|
153
|
+
return __generator(this, function (_b) {
|
|
154
|
+
switch (_b.label) {
|
|
155
|
+
case 0:
|
|
156
|
+
inPath = path.join(this.config.inPath, element);
|
|
157
|
+
outPath = path.join(this.config.outPath, element);
|
|
158
|
+
info = path.parse(inPath);
|
|
159
|
+
reg = /atlas[89]/;
|
|
160
|
+
if (!!reg.test(info.name)) return [3 /*break*/, 15];
|
|
161
|
+
if (!this.config.ignore.has(info.name)) return [3 /*break*/, 1];
|
|
162
|
+
console.log("出现在白名单", inPath);
|
|
163
|
+
return [3 /*break*/, 15];
|
|
164
|
+
case 1: return [4 /*yield*/, this.isSamll(inPath)];
|
|
165
|
+
case 2:
|
|
166
|
+
if (!!(_b.sent())) return [3 /*break*/, 15];
|
|
167
|
+
return [4 /*yield*/, this.readBuffer(inPath)];
|
|
168
|
+
case 3:
|
|
169
|
+
buffer = _b.sent();
|
|
170
|
+
md5 = crypto.createHash('md5');
|
|
171
|
+
code = md5.update(buffer).digest('hex');
|
|
172
|
+
_a = this.config.skipSpine;
|
|
173
|
+
if (!_a) return [3 /*break*/, 5];
|
|
174
|
+
return [4 /*yield*/, this.isSpine(inPath)];
|
|
175
|
+
case 4:
|
|
176
|
+
_a = (_b.sent());
|
|
177
|
+
_b.label = 5;
|
|
178
|
+
case 5:
|
|
179
|
+
if (!_a) return [3 /*break*/, 6];
|
|
180
|
+
return [3 /*break*/, 15];
|
|
181
|
+
case 6:
|
|
182
|
+
doc = this.info[inPath];
|
|
183
|
+
if (!(doc == null)) return [3 /*break*/, 9];
|
|
184
|
+
//没有记录
|
|
185
|
+
// this.count++
|
|
186
|
+
return [4 /*yield*/, this.tinify(inPath, outPath, buffer, code)];
|
|
187
|
+
case 7:
|
|
188
|
+
//没有记录
|
|
189
|
+
// this.count++
|
|
190
|
+
_b.sent();
|
|
191
|
+
return [4 /*yield*/, this.copy(inPath, outPath, buffer, code)];
|
|
192
|
+
case 8:
|
|
193
|
+
_b.sent();
|
|
194
|
+
console.log("没有记录:", inPath);
|
|
195
|
+
return [3 /*break*/, 15];
|
|
196
|
+
case 9:
|
|
197
|
+
if (!(doc.inMd5 == code)) return [3 /*break*/, 11];
|
|
198
|
+
//没有复制
|
|
199
|
+
return [4 /*yield*/, this.copy(inPath, outPath, buffer, code)];
|
|
200
|
+
case 10:
|
|
201
|
+
//没有复制
|
|
202
|
+
_b.sent();
|
|
203
|
+
console.log("没有复制:", inPath);
|
|
204
|
+
return [3 /*break*/, 15];
|
|
205
|
+
case 11:
|
|
206
|
+
if (!(doc.outMd5 == code)) return [3 /*break*/, 12];
|
|
207
|
+
console.log("正常跳过:", inPath);
|
|
208
|
+
return [3 /*break*/, 15];
|
|
209
|
+
case 12:
|
|
210
|
+
//图是新的
|
|
211
|
+
return [4 /*yield*/, this.tinify(inPath, outPath, buffer, code)];
|
|
212
|
+
case 13:
|
|
213
|
+
//图是新的
|
|
214
|
+
_b.sent();
|
|
215
|
+
return [4 /*yield*/, this.copy(inPath, outPath, buffer, code)];
|
|
216
|
+
case 14:
|
|
217
|
+
_b.sent();
|
|
218
|
+
console.log("新图:", inPath);
|
|
219
|
+
_b.label = 15;
|
|
220
|
+
case 15: return [2 /*return*/];
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
TaskParser.prototype.tinify = function (inPath, outPath, buffer, code) {
|
|
226
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
227
|
+
var outBuffer, md5Hash, inMd5, outMd5;
|
|
228
|
+
return __generator(this, function (_a) {
|
|
229
|
+
switch (_a.label) {
|
|
230
|
+
case 0:
|
|
231
|
+
console.log("开始转换" + inPath);
|
|
232
|
+
return [4 /*yield*/, tinify.default.fromBuffer(buffer).toBuffer()];
|
|
233
|
+
case 1:
|
|
234
|
+
outBuffer = _a.sent();
|
|
235
|
+
md5Hash = crypto.createHash('md5');
|
|
236
|
+
inMd5 = code;
|
|
237
|
+
outMd5 = md5Hash.update(outBuffer).digest('hex');
|
|
238
|
+
this.witeBuffer(outPath, outBuffer);
|
|
239
|
+
console.log(inMd5, outMd5);
|
|
240
|
+
// await this.db.updateOne({ inPath }, { inPath, outPath, inMd5, outMd5 }, { upsert: true })
|
|
241
|
+
this.info[inPath] = { outPath: outPath, inMd5: inMd5, outMd5: outMd5 };
|
|
242
|
+
this.saveInfo();
|
|
243
|
+
this.count++;
|
|
244
|
+
console.log("转换结束", this.count);
|
|
245
|
+
return [2 /*return*/];
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
TaskParser.prototype.copy = function (inPath, outPath, buffer, code) {
|
|
251
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
252
|
+
var _a, _b;
|
|
253
|
+
return __generator(this, function (_c) {
|
|
254
|
+
switch (_c.label) {
|
|
255
|
+
case 0:
|
|
256
|
+
_a = this.witeBuffer;
|
|
257
|
+
_b = [inPath];
|
|
258
|
+
return [4 /*yield*/, this.readBuffer(outPath)];
|
|
259
|
+
case 1: return [4 /*yield*/, _a.apply(this, _b.concat([_c.sent()]))];
|
|
260
|
+
case 2:
|
|
261
|
+
_c.sent();
|
|
262
|
+
return [2 /*return*/];
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
TaskParser.prototype.isSamll = function (url) {
|
|
268
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
269
|
+
return __generator(this, function (_a) {
|
|
270
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
271
|
+
fs.stat(url, function (err, s) {
|
|
272
|
+
if (err) {
|
|
273
|
+
reject(err);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
resolve(s.size < 20000);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
})];
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
};
|
|
283
|
+
TaskParser.prototype.isSpine = function (url) {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
285
|
+
return __generator(this, function (_a) {
|
|
286
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
287
|
+
var info = path.parse(url);
|
|
288
|
+
var checkUrl = info.dir + "/" + info.name + ".json";
|
|
289
|
+
fs.stat(checkUrl, function (err, s) {
|
|
290
|
+
if (err) {
|
|
291
|
+
resolve(false);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
resolve(s != null);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
})];
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
TaskParser.prototype.readBuffer = function (url) {
|
|
302
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
303
|
+
return __generator(this, function (_a) {
|
|
304
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
305
|
+
fs.readFile(url, function (err, sourceData) {
|
|
306
|
+
if (err) {
|
|
307
|
+
reject(err);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
resolve(sourceData);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
})];
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
TaskParser.prototype.witeBuffer = function (url, buffer) {
|
|
318
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
319
|
+
return __generator(this, function (_a) {
|
|
320
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
321
|
+
fs.writeFile(url, buffer, function (err) {
|
|
322
|
+
if (err) {
|
|
323
|
+
reject(err);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
resolve();
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
})];
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
TaskParser.prototype.hasStat = function (url) {
|
|
334
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
335
|
+
return __generator(this, function (_a) {
|
|
336
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
337
|
+
fs.stat(url, function (err, s) {
|
|
338
|
+
if (err) {
|
|
339
|
+
resolve(false);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
resolve(s != null);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
})];
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
TaskParser.prototype.mkdirs = function (url) {
|
|
350
|
+
if (!fs.existsSync(url)) {
|
|
351
|
+
this.mkdirs(path.resolve(url, "../"));
|
|
352
|
+
fs.mkdirSync(url);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
TaskParser.prototype.readDirData = function (pathUrl) {
|
|
356
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
357
|
+
var _this = this;
|
|
358
|
+
return __generator(this, function (_a) {
|
|
359
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
360
|
+
fs.readdir(path.join(_this.config.inPath, pathUrl), function (err, data) {
|
|
361
|
+
if (err) {
|
|
362
|
+
reject("这个目录不存在");
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
resolve(data);
|
|
366
|
+
});
|
|
367
|
+
})];
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
TaskParser.prototype.parserConfig = function () {
|
|
372
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
373
|
+
var _this = this;
|
|
374
|
+
return __generator(this, function (_a) {
|
|
375
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
376
|
+
fs.readFile(_this.tinfiyUrl, function (err, txt) {
|
|
377
|
+
if (err) {
|
|
378
|
+
reject("这个目录下没有目录配置文件tinify.json");
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
var json = JSON.parse(txt.toString());
|
|
382
|
+
var inPath = path.join(_this.tinfiyUrlInfo.dir, json.inPath);
|
|
383
|
+
var outPath = path.join(_this.tinfiyUrlInfo.dir, json.outPath);
|
|
384
|
+
var tinifyKey = json.tinifyKey;
|
|
385
|
+
var skipSpine = json.skipSpine || false;
|
|
386
|
+
var info = path.join(_this.tinfiyUrlInfo.dir, json.info);
|
|
387
|
+
var ignore_1 = new Set();
|
|
388
|
+
json.ignore.forEach(function (ignoreItem) {
|
|
389
|
+
ignore_1.add(ignoreItem);
|
|
390
|
+
});
|
|
391
|
+
tinify.default.key = tinifyKey;
|
|
392
|
+
_this.config = {
|
|
393
|
+
skipSpine: skipSpine,
|
|
394
|
+
inPath: inPath,
|
|
395
|
+
outPath: outPath,
|
|
396
|
+
ignore: ignore_1,
|
|
397
|
+
tinifyKey: tinifyKey,
|
|
398
|
+
info: info,
|
|
399
|
+
};
|
|
400
|
+
resolve(_this.config);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
})];
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
};
|
|
407
|
+
return TaskParser;
|
|
408
|
+
}());
|
|
409
|
+
exports.TaskParser = TaskParser;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zero-tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Zero游戏开发工具",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"minimist": "^1.2.0",
|
|
16
|
-
"
|
|
16
|
+
"tinify": "^1.6.1",
|
|
17
|
+
"xlsx": "^0.13.5"
|
|
17
18
|
},
|
|
18
19
|
"devDependencies": {
|
|
19
20
|
"@types/minimist": "^1.2.0",
|
package/tinify.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import * as fs from 'fs'
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
import * as tinify from 'tinify'
|
|
4
|
+
import * as crypto from 'crypto'
|
|
5
|
+
|
|
6
|
+
interface ITinifyConfig {
|
|
7
|
+
inPath: string
|
|
8
|
+
outPath: string
|
|
9
|
+
info: string
|
|
10
|
+
ignore: Set<string>
|
|
11
|
+
tinifyKey: string
|
|
12
|
+
skipSpine: boolean
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 忽略含有命名为
|
|
16
|
+
* atlas8
|
|
17
|
+
* atlas9
|
|
18
|
+
* 忽略 20000 字节以下的文件
|
|
19
|
+
*/
|
|
20
|
+
export class TaskParser {
|
|
21
|
+
tinfiyUrlInfo: path.ParsedPath
|
|
22
|
+
config!: ITinifyConfig
|
|
23
|
+
info: any;
|
|
24
|
+
constructor(public tinfiyUrl: string) {
|
|
25
|
+
this.tinfiyUrlInfo = path.parse(tinfiyUrl)
|
|
26
|
+
}
|
|
27
|
+
async loadInfo() {
|
|
28
|
+
let buffer = await this.readBuffer(this.config.info)
|
|
29
|
+
this.info = JSON.parse(buffer.toString('utf-8'))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async saveInfo() {
|
|
33
|
+
this.witeBuffer(this.config.info, JSON.stringify(this.info, null, 4))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async idDir(pathUrl: string): Promise<boolean> {
|
|
37
|
+
return new Promise<boolean>(
|
|
38
|
+
(resolve: (value: boolean) => void, reject: (reason?: any) => void) => {
|
|
39
|
+
fs.stat(path.join(this.config.inPath, pathUrl), (err: NodeJS.ErrnoException | null, stats: fs.Stats) => {
|
|
40
|
+
if (err) {
|
|
41
|
+
reject(err)
|
|
42
|
+
} else {
|
|
43
|
+
resolve(stats.isDirectory())
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
async readDir(pathUrl: string) {
|
|
49
|
+
let data = await this.readDirData(pathUrl)
|
|
50
|
+
for (let index = 0; index < data.length; index++) {
|
|
51
|
+
const element = path.join(pathUrl, data[index]);
|
|
52
|
+
let isDir = await this.idDir(element)
|
|
53
|
+
if (isDir) {
|
|
54
|
+
await this.readDir(element)
|
|
55
|
+
} else {
|
|
56
|
+
let info = path.parse(element)
|
|
57
|
+
// if (info.ext == ".png" || info.ext == ".jpg") {
|
|
58
|
+
if (info.ext == ".png") {
|
|
59
|
+
await this.pick(element)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
count = 0
|
|
65
|
+
async pick(element: string): Promise<void> {
|
|
66
|
+
let inPath = path.join(this.config.inPath, element)
|
|
67
|
+
let outPath = path.join(this.config.outPath, element)
|
|
68
|
+
let info = path.parse(inPath)
|
|
69
|
+
let reg = /atlas[89]/;
|
|
70
|
+
|
|
71
|
+
if (!reg.test(info.name)) {
|
|
72
|
+
if (this.config.ignore.has(info.name)) {
|
|
73
|
+
console.log("出现在白名单", inPath)
|
|
74
|
+
} else {
|
|
75
|
+
if (!await this.isSamll(inPath)) {
|
|
76
|
+
let buffer = await this.readBuffer(inPath)
|
|
77
|
+
const md5 = crypto.createHash('md5');
|
|
78
|
+
const code = md5.update(buffer).digest('hex');
|
|
79
|
+
if (this.config.skipSpine && await this.isSpine(inPath)) {
|
|
80
|
+
} else {
|
|
81
|
+
// let doc = await this.db.findOne({ inPath })
|
|
82
|
+
let doc = this.info[inPath]
|
|
83
|
+
|
|
84
|
+
if (doc == null) {
|
|
85
|
+
//没有记录
|
|
86
|
+
// this.count++
|
|
87
|
+
await this.tinify(inPath, outPath, buffer, code)
|
|
88
|
+
await this.copy(inPath, outPath, buffer, code)
|
|
89
|
+
console.log("没有记录:", inPath)
|
|
90
|
+
} else if (doc.inMd5 == code) {
|
|
91
|
+
//没有复制
|
|
92
|
+
await this.copy(inPath, outPath, buffer, code)
|
|
93
|
+
console.log("没有复制:", inPath)
|
|
94
|
+
} else if (doc.outMd5 == code) {
|
|
95
|
+
console.log("正常跳过:", inPath)
|
|
96
|
+
//正常
|
|
97
|
+
} else {
|
|
98
|
+
//图是新的
|
|
99
|
+
await this.tinify(inPath, outPath, buffer, code)
|
|
100
|
+
await this.copy(inPath, outPath, buffer, code)
|
|
101
|
+
console.log("新图:", inPath)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
async tinify(inPath: string, outPath: string, buffer: Buffer, code: string): Promise<void> {
|
|
110
|
+
console.log("开始转换" + inPath)
|
|
111
|
+
let outBuffer = await tinify.default.fromBuffer(buffer).toBuffer()
|
|
112
|
+
const md5Hash = crypto.createHash('md5');
|
|
113
|
+
let inMd5 = code
|
|
114
|
+
let outMd5 = md5Hash.update(outBuffer).digest('hex');
|
|
115
|
+
this.witeBuffer(outPath, outBuffer)
|
|
116
|
+
console.log(inMd5, outMd5)
|
|
117
|
+
// await this.db.updateOne({ inPath }, { inPath, outPath, inMd5, outMd5 }, { upsert: true })
|
|
118
|
+
this.info[inPath] = { outPath, inMd5, outMd5 }
|
|
119
|
+
this.saveInfo()
|
|
120
|
+
this.count++
|
|
121
|
+
console.log("转换结束", this.count)
|
|
122
|
+
}
|
|
123
|
+
async copy(inPath: string, outPath: string, buffer: Buffer, code: string): Promise<void> {
|
|
124
|
+
await this.witeBuffer(inPath, await this.readBuffer(outPath))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async isSamll(url: string): Promise<boolean> {
|
|
128
|
+
return new Promise<boolean>(
|
|
129
|
+
(resolve: (value: boolean) => void, reject: (reason?: any) => void) => {
|
|
130
|
+
fs.stat(url, (err, s) => {
|
|
131
|
+
if (err) {
|
|
132
|
+
reject(err)
|
|
133
|
+
} else {
|
|
134
|
+
resolve(s.size < 20000)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
async isSpine(url: string): Promise<boolean> {
|
|
141
|
+
return new Promise<boolean>(
|
|
142
|
+
(resolve: (value: boolean) => void, reject: (reason?: any) => void) => {
|
|
143
|
+
let info = path.parse(url)
|
|
144
|
+
let checkUrl = info.dir + "/" + info.name + ".json"
|
|
145
|
+
fs.stat(checkUrl, (err, s) => {
|
|
146
|
+
if (err) {
|
|
147
|
+
resolve(false)
|
|
148
|
+
} else {
|
|
149
|
+
resolve(s != null)
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
async readBuffer(url: string): Promise<Buffer> {
|
|
158
|
+
return new Promise<Buffer>(
|
|
159
|
+
(resolve: (value: Buffer) => void, reject: (reason?: any) => void) => {
|
|
160
|
+
fs.readFile(url, (err, sourceData) => {
|
|
161
|
+
if (err) {
|
|
162
|
+
reject(err)
|
|
163
|
+
} else {
|
|
164
|
+
resolve(sourceData)
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async witeBuffer(url: string, buffer: Uint8Array | string): Promise<void> {
|
|
172
|
+
return new Promise<void>(
|
|
173
|
+
(resolve: (value: void) => void, reject: (reason?: any) => void) => {
|
|
174
|
+
fs.writeFile(url, buffer, (err) => {
|
|
175
|
+
if (err) {
|
|
176
|
+
reject(err)
|
|
177
|
+
} else {
|
|
178
|
+
resolve()
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
async hasStat(url: string): Promise<boolean> {
|
|
187
|
+
return new Promise<boolean>(
|
|
188
|
+
(resolve: (value: boolean) => void, reject: (reason?: any) => void) => {
|
|
189
|
+
fs.stat(url, (err, s) => {
|
|
190
|
+
if (err) {
|
|
191
|
+
resolve(false)
|
|
192
|
+
} else {
|
|
193
|
+
resolve(s != null)
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
mkdirs(url: string) {
|
|
201
|
+
if (!fs.existsSync(url)) {
|
|
202
|
+
this.mkdirs(path.resolve(url, "../"))
|
|
203
|
+
fs.mkdirSync(url)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async readDirData(pathUrl: string): Promise<string[]> {
|
|
207
|
+
return new Promise<string[]>(
|
|
208
|
+
(resolve: (value: string[]) => void, reject: (reason?: any) => void) => {
|
|
209
|
+
fs.readdir(path.join(this.config.inPath, pathUrl), function (err, data) {
|
|
210
|
+
if (err) {
|
|
211
|
+
reject("这个目录不存在")
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
resolve(data)
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
async parserConfig(): Promise<ITinifyConfig> {
|
|
220
|
+
return new Promise<ITinifyConfig>((resolve: (value: ITinifyConfig) => void, reject: (reason?: any) => void) => {
|
|
221
|
+
fs.readFile(this.tinfiyUrl, (err, txt) => {
|
|
222
|
+
if (err) {
|
|
223
|
+
reject("这个目录下没有目录配置文件tinify.json")
|
|
224
|
+
} else {
|
|
225
|
+
let json = JSON.parse(txt.toString())
|
|
226
|
+
|
|
227
|
+
let inPath: string = path.join(this.tinfiyUrlInfo.dir, json.inPath)
|
|
228
|
+
let outPath: string = path.join(this.tinfiyUrlInfo.dir, json.outPath)
|
|
229
|
+
|
|
230
|
+
let tinifyKey: string = json.tinifyKey
|
|
231
|
+
let skipSpine: boolean = json.skipSpine || false
|
|
232
|
+
let info: string = path.join(this.tinfiyUrlInfo.dir, json.info)
|
|
233
|
+
let ignore: Set<string> = new Set()
|
|
234
|
+
json.ignore.forEach((ignoreItem: string) => {
|
|
235
|
+
ignore.add(ignoreItem)
|
|
236
|
+
})
|
|
237
|
+
tinify.default.key = tinifyKey
|
|
238
|
+
this.config = {
|
|
239
|
+
skipSpine,
|
|
240
|
+
inPath,
|
|
241
|
+
outPath,
|
|
242
|
+
ignore,
|
|
243
|
+
tinifyKey,
|
|
244
|
+
info,
|
|
245
|
+
}
|
|
246
|
+
resolve(this.config)
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
}
|
package/.vscode/tasks.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
|
3
|
-
// for the documentation about the tasks.json format
|
|
4
|
-
"version": "2.0.0",
|
|
5
|
-
"tasks": [
|
|
6
|
-
{
|
|
7
|
-
"type": "typescript",
|
|
8
|
-
"tsconfig": "tsconfig.json",
|
|
9
|
-
"problemMatcher": [
|
|
10
|
-
"$tsc"
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
]
|
|
14
|
-
}
|