@vtj/local 0.9.29 → 0.10.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/dist/index.cjs ADDED
@@ -0,0 +1,1259 @@
1
+ 'use strict';
2
+
3
+ const cli = require('@vtj/cli');
4
+ const node = require('@vtj/node');
5
+ const path = require('path');
6
+ const bodyParser = require('body-parser');
7
+ const formidable = require('formidable');
8
+ const core = require('@vtj/core');
9
+ const coder = require('@vtj/coder');
10
+ const parser = require('@vtj/parser');
11
+
12
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
13
+
14
+ const bodyParser__default = /*#__PURE__*/_interopDefaultCompat(bodyParser);
15
+ const formidable__default = /*#__PURE__*/_interopDefaultCompat(formidable);
16
+
17
+ const success = (data) => {
18
+ return {
19
+ code: 0 /* Success */,
20
+ msg: "success",
21
+ data,
22
+ success: true
23
+ };
24
+ };
25
+ const fail = (msg, data = null, stack = null) => {
26
+ return {
27
+ code: 1 /* Fail */,
28
+ msg,
29
+ data,
30
+ stack,
31
+ success: false
32
+ };
33
+ };
34
+ const CLIENT_DIR = "__vtj__";
35
+
36
+ var __defProp$3 = Object.defineProperty;
37
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
38
+ var __publicField$3 = (obj, key, value) => {
39
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
40
+ return value;
41
+ };
42
+ class JsonRepository {
43
+ constructor(path$1, platform = "web") {
44
+ __publicField$3(this, "path");
45
+ const dir = platform === "uniapp" ? "src/vtj" : ".vtj";
46
+ this.path = path.resolve(dir, path$1);
47
+ }
48
+ exist(name) {
49
+ const filePath = path.join(this.path, `${name}.json`);
50
+ return node.pathExistsSync(filePath);
51
+ }
52
+ save(name, json) {
53
+ const filePath = path.join(this.path, `${name}.json`);
54
+ if (!this.exist(name)) {
55
+ node.ensureFileSync(filePath);
56
+ }
57
+ node.writeJsonSync(filePath, json, {
58
+ spaces: 2,
59
+ EOL: "\n"
60
+ });
61
+ return true;
62
+ }
63
+ get(name) {
64
+ const filePath = path.join(this.path, `${name}.json`);
65
+ if (node.pathExistsSync(filePath)) {
66
+ return node.readJsonSync(filePath);
67
+ } else {
68
+ return void 0;
69
+ }
70
+ }
71
+ remove(name) {
72
+ const filePath = path.join(this.path, `${name}.json`);
73
+ if (node.pathExistsSync(filePath)) {
74
+ node.removeSync(filePath);
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ clear() {
80
+ if (node.pathExistsSync(this.path)) {
81
+ node.removeSync(this.path);
82
+ return true;
83
+ }
84
+ return false;
85
+ }
86
+ }
87
+
88
+ var __defProp$2 = Object.defineProperty;
89
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
90
+ var __publicField$2 = (obj, key, value) => {
91
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
92
+ return value;
93
+ };
94
+ class VueRepository {
95
+ constructor(platform = "web") {
96
+ __publicField$2(this, "path");
97
+ const dir = platform === "uniapp" ? "src/pages" : ".vtj/vue";
98
+ this.path = path.resolve(dir);
99
+ }
100
+ exist(name) {
101
+ const filePath = path.join(this.path, `${name}.vue`);
102
+ return node.pathExistsSync(filePath);
103
+ }
104
+ save(name, content) {
105
+ const filePath = path.join(this.path, `${name}.vue`);
106
+ if (!this.exist(name)) {
107
+ node.ensureFileSync(filePath);
108
+ }
109
+ node.outputFileSync(filePath, content, "utf-8");
110
+ return true;
111
+ }
112
+ remove(name) {
113
+ const filePath = path.join(this.path, `${name}.vue`);
114
+ if (node.pathExistsSync(filePath)) {
115
+ node.removeSync(filePath);
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ clear() {
121
+ if (node.pathExistsSync(this.path)) {
122
+ node.removeSync(this.path);
123
+ return true;
124
+ }
125
+ return false;
126
+ }
127
+ }
128
+
129
+ var __defProp$1 = Object.defineProperty;
130
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
131
+ var __publicField$1 = (obj, key, value) => {
132
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
133
+ return value;
134
+ };
135
+ class StaticRepository {
136
+ constructor(options) {
137
+ this.options = options;
138
+ __publicField$1(this, "path");
139
+ this.path = path.resolve(this.options.staticDir, this.options.vtjDir);
140
+ }
141
+ exist(name) {
142
+ const filePath = path.join(this.path, name);
143
+ return node.pathExistsSync(filePath);
144
+ }
145
+ remove(name) {
146
+ const filePath = path.join(this.path, name);
147
+ if (node.pathExistsSync(filePath)) {
148
+ node.removeSync(filePath);
149
+ return true;
150
+ }
151
+ return false;
152
+ }
153
+ clear() {
154
+ if (node.pathExistsSync(this.path)) {
155
+ node.removeSync(this.path);
156
+ return true;
157
+ }
158
+ return false;
159
+ }
160
+ getAllFiles() {
161
+ if (node.pathExistsSync(this.path)) {
162
+ const files = node.readdirSync(this.path) || [];
163
+ return files.map((name) => {
164
+ return {
165
+ filename: name,
166
+ filepath: path.join(
167
+ this.options.staticBase,
168
+ this.options.vtjDir,
169
+ name
170
+ ).replace(/\\/g, "/")
171
+ };
172
+ });
173
+ }
174
+ return [];
175
+ }
176
+ validate(files) {
177
+ let isExists = false;
178
+ const result = [];
179
+ for (let file of files) {
180
+ if (file.originalFilename) {
181
+ const filePath = path.join(this.path, file.originalFilename);
182
+ if (node.pathExistsSync(filePath)) {
183
+ isExists = true;
184
+ result.push({
185
+ filename: file.originalFilename,
186
+ filepath: path.join(
187
+ this.options.staticBase,
188
+ this.options.vtjDir,
189
+ file.originalFilename
190
+ ).replace(/\\/g, "/")
191
+ });
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ if (isExists) {
197
+ for (let file of files) {
198
+ if (file.filepath) {
199
+ if (node.pathExistsSync(file.filepath)) {
200
+ node.removeSync(file.filepath);
201
+ }
202
+ }
203
+ }
204
+ }
205
+ return isExists ? result : false;
206
+ }
207
+ save(files) {
208
+ const result = [];
209
+ for (let file of files) {
210
+ if (file.filepath && file.originalFilename) {
211
+ const filePath = path.join(this.path, file.originalFilename);
212
+ node.moveSync(file.filepath, filePath, { overwrite: true });
213
+ result.push({
214
+ filename: file.originalFilename,
215
+ filepath: path.join(
216
+ this.options.staticBase,
217
+ this.options.vtjDir,
218
+ file.originalFilename
219
+ ).replace(/\\/g, "/")
220
+ });
221
+ }
222
+ }
223
+ return result;
224
+ }
225
+ }
226
+
227
+ var __defProp = Object.defineProperty;
228
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
229
+ var __publicField = (obj, key, value) => {
230
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
231
+ return value;
232
+ };
233
+ class PluginRepository {
234
+ constructor(pkg, opts) {
235
+ this.pkg = pkg;
236
+ this.opts = opts;
237
+ __publicField(this, "deps", []);
238
+ const { devDependencies, dependencies } = pkg || {};
239
+ const { presetPlugins } = opts;
240
+ this.deps = Object.keys({ ...devDependencies, ...dependencies }).filter(
241
+ (name) => presetPlugins.some((regex) => name.startsWith(regex))
242
+ );
243
+ }
244
+ getName(dep) {
245
+ const { presetPlugins } = this.opts;
246
+ let name = dep;
247
+ for (const regex of presetPlugins) {
248
+ name = name.replace(regex, "x-");
249
+ }
250
+ return node.upperFirstCamelCase(name);
251
+ }
252
+ getPlugins() {
253
+ const { vtj = {} } = this.pkg;
254
+ const { pluginNodeModulesDir = "node_modules", staticBase = "/" } = this.opts;
255
+ const plugins = (vtj.plugins || []).map((n) => {
256
+ n.type = "block";
257
+ n.fromType = "Plugin";
258
+ n.preset = true;
259
+ n.category = "\u63D2\u4EF6\u533A\u5757";
260
+ return n;
261
+ });
262
+ const ext = [".css", ".js", ".json"];
263
+ for (const dep of this.deps) {
264
+ const dist = path.join(pluginNodeModulesDir, dep, "dist");
265
+ if (node.pathExistsSync(dist)) {
266
+ const pkg = node.readJsonSync(
267
+ path.join(pluginNodeModulesDir, dep, "package.json")
268
+ );
269
+ const files = node.readdirSync(dist, { recursive: true, encoding: "utf-8" });
270
+ const urls = files.filter((url) => ext.some((n) => url.endsWith(n))).map(
271
+ (url) => `${staticBase}@vtj/plugins/${url.replace(/\\/gi, "/")}`
272
+ );
273
+ const { description } = pkg || "";
274
+ const name = node.upperFirstCamelCase(dep);
275
+ if (files.length) {
276
+ plugins.push({
277
+ type: "block",
278
+ fromType: "Plugin",
279
+ preset: true,
280
+ id: dep,
281
+ name: this.getName(dep),
282
+ title: description || name,
283
+ library: name,
284
+ urls: urls.join(","),
285
+ category: "\u63D2\u4EF6\u533A\u5757"
286
+ });
287
+ }
288
+ }
289
+ }
290
+ return plugins;
291
+ }
292
+ }
293
+
294
+ const APP_LIFE_CYCLE = [
295
+ "onLaunch",
296
+ "onShow",
297
+ "onHide",
298
+ "onError",
299
+ "onPageNotFound",
300
+ "onUnhandledRejection",
301
+ "onThemeChange",
302
+ "onPageNotFound",
303
+ "onUniNViewMessage",
304
+ "onExit"
305
+ ];
306
+ const vueAppTempalte = `
307
+ <script setup lang="ts">
308
+ {{ts}}
309
+ <\/script>
310
+ <style>
311
+ {{css}}
312
+ </style>
313
+ `;
314
+ class UniRepository {
315
+ constructor() {
316
+ }
317
+ createProjectPages(project) {
318
+ const oPages = (project.uniConfig?.pagesJson?.pages || []).filter(
319
+ (n) => !n.vtj
320
+ );
321
+ const pages = project.pages || [];
322
+ const json = [];
323
+ for (const page of pages) {
324
+ if (page.id === project.homepage) {
325
+ json.unshift({
326
+ path: `pages/${page.id}`,
327
+ style: page.style || {},
328
+ needLogin: page.needLogin,
329
+ vtj: true
330
+ });
331
+ } else {
332
+ json.push({
333
+ path: `pages/${page.id}`,
334
+ style: page.style || {},
335
+ needLogin: page.needLogin,
336
+ vtj: true
337
+ });
338
+ }
339
+ }
340
+ for (const item of oPages) {
341
+ const exist = json.find((n) => n.path === item.path);
342
+ if (!exist) {
343
+ json.push(item);
344
+ }
345
+ }
346
+ return json;
347
+ }
348
+ savePagesJson(project) {
349
+ const pages = this.createProjectPages(project);
350
+ const { pagesJson = {} } = project.uniConfig || {};
351
+ const filePath = path.resolve("src/pages.json");
352
+ pagesJson.pages = pages;
353
+ node.writeJsonSync(filePath, pagesJson, {
354
+ spaces: 2,
355
+ EOL: "\n"
356
+ });
357
+ return true;
358
+ }
359
+ saveManifestJson(project) {
360
+ const { manifestJson } = project.uniConfig || {};
361
+ const filePath = path.resolve("src/manifest.json");
362
+ node.writeJsonSync(filePath, manifestJson, {
363
+ spaces: 2,
364
+ EOL: "\n"
365
+ });
366
+ return true;
367
+ }
368
+ async saveApp(project) {
369
+ const filePath = path.resolve("src/App.vue");
370
+ const uniConfig = project.uniConfig || {};
371
+ const names = [];
372
+ const content = [];
373
+ for (const [name, value] of Object.entries(uniConfig)) {
374
+ if (APP_LIFE_CYCLE.includes(name) && value.value) {
375
+ names.push(name);
376
+ const code = value.value.replace(/;\n/g, "\n");
377
+ content.push(`${name}(${code})`);
378
+ }
379
+ }
380
+ const tsCode = names.length ? `import {${names.join(",")}} from '@dcloudio/uni-app';${content.join(";\n")}` : "";
381
+ const css = uniConfig.css || "";
382
+ let result = vueAppTempalte.replace("{{ts}}", await coder.tsFormatter(tsCode));
383
+ result = result.replace("{{css}}", await coder.cssFormatter(css));
384
+ node.outputFileSync(filePath, await coder.vueFormatter(result), "utf-8");
385
+ }
386
+ }
387
+
388
+ const manifestJson = {
389
+ name: "VTJ",
390
+ appid: "__UNI__1FC118B",
391
+ description: "VTJ\u79FB\u52A8\u8DE8\u7AEF\u9879\u76EE\u6A21\u677F",
392
+ versionName: "1.0.0",
393
+ versionCode: "100",
394
+ transformPx: false,
395
+ "app-plus": {
396
+ usingComponents: true,
397
+ nvueStyleCompiler: "uni-app",
398
+ compilerVersion: 3,
399
+ splashscreen: {
400
+ alwaysShowBeforeRender: true,
401
+ waiting: true,
402
+ autoclose: true,
403
+ delay: 0
404
+ },
405
+ modules: {},
406
+ distribute: {
407
+ android: {
408
+ permissions: [
409
+ '<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>',
410
+ '<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>',
411
+ '<uses-permission android:name="android.permission.VIBRATE"/>',
412
+ '<uses-permission android:name="android.permission.READ_LOGS"/>',
413
+ '<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>',
414
+ '<uses-feature android:name="android.hardware.camera.autofocus"/>',
415
+ '<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>',
416
+ '<uses-permission android:name="android.permission.CAMERA"/>',
417
+ '<uses-permission android:name="android.permission.GET_ACCOUNTS"/>',
418
+ '<uses-permission android:name="android.permission.READ_PHONE_STATE"/>',
419
+ '<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>',
420
+ '<uses-permission android:name="android.permission.WAKE_LOCK"/>',
421
+ '<uses-permission android:name="android.permission.FLASHLIGHT"/>',
422
+ '<uses-feature android:name="android.hardware.camera"/>',
423
+ '<uses-permission android:name="android.permission.WRITE_SETTINGS"/>'
424
+ ]
425
+ },
426
+ ios: {},
427
+ sdkConfigs: {},
428
+ icons: {
429
+ android: {
430
+ hdpi: "src/static/logo.png",
431
+ xhdpi: "src/static/logo.png",
432
+ xxhdpi: "src/static/logo.png",
433
+ xxxhdpi: "src/static/logo.png"
434
+ }
435
+ }
436
+ }
437
+ },
438
+ quickapp: {},
439
+ "mp-weixin": {
440
+ appid: "",
441
+ setting: {
442
+ urlCheck: false
443
+ },
444
+ usingComponents: true
445
+ },
446
+ "mp-alipay": {
447
+ usingComponents: true
448
+ },
449
+ "mp-baidu": {
450
+ usingComponents: true
451
+ },
452
+ "mp-toutiao": {
453
+ usingComponents: true
454
+ },
455
+ uniStatistics: {
456
+ enable: false
457
+ },
458
+ vueVersion: "3"
459
+ };
460
+
461
+ const pagesJson = {
462
+ pages: [],
463
+ globalStyle: {
464
+ navigationBarTextStyle: "black",
465
+ navigationBarTitleText: "uni-app",
466
+ navigationBarBackgroundColor: "#F8F8F8",
467
+ backgroundColor: "#F8F8F8"
468
+ }
469
+ };
470
+
471
+ function isJSFunction(x) {
472
+ return typeof x === "object" && x && x.type === "JSFunction";
473
+ }
474
+ function getJson(name, dsl) {
475
+ const map = {
476
+ manifestJson: "manifest.json",
477
+ pagesJson: "pages.json"
478
+ };
479
+ const defaults = {
480
+ manifestJson: manifestJson,
481
+ pagesJson: pagesJson
482
+ };
483
+ const file = map[name];
484
+ const filePath = path.resolve("./src", file);
485
+ if (node.pathExistsSync(filePath)) {
486
+ return node.readJsonSync(filePath);
487
+ }
488
+ const uniConfig = dsl.uniConfig || {};
489
+ return uniConfig[name] || defaults[name];
490
+ }
491
+ function getApp(dsl) {
492
+ const filePath = path.resolve("./src/App.vue");
493
+ if (node.pathExistsSync(filePath)) {
494
+ const source = node.fs.readFileSync(filePath, "utf-8");
495
+ return parser.parseUniApp(source);
496
+ }
497
+ return dsl.uniConfig || {};
498
+ }
499
+ async function formatUniConfigCode(uniConfig) {
500
+ for (const [name, value] of Object.entries(uniConfig)) {
501
+ if (isJSFunction(value)) {
502
+ const code = uniConfig[name].value;
503
+ uniConfig[name].value = await coder.tsFormatter(code);
504
+ }
505
+ }
506
+ return uniConfig;
507
+ }
508
+ async function getUniConfig(dsl) {
509
+ const manifestJson = getJson("manifestJson", dsl);
510
+ const pagesJson = getJson("pagesJson", dsl);
511
+ const lifeCycle = getApp(dsl);
512
+ const { name, id, description } = dsl;
513
+ const appId = node.camelCase(id?.replace(/\//, "__")).toUpperCase();
514
+ Object.assign(manifestJson, {
515
+ name,
516
+ appid: appId.startsWith("__UNI__") ? appId : `__UNI__${appId}`,
517
+ description
518
+ });
519
+ return {
520
+ ...dsl.uniConfig,
521
+ ...await formatUniConfigCode(lifeCycle),
522
+ manifestJson,
523
+ pagesJson
524
+ };
525
+ }
526
+
527
+ let isInit = false;
528
+ let _platform = "web";
529
+ async function saveLogs(e) {
530
+ const name = `error-${node.timestamp()}`;
531
+ const logs = new JsonRepository("logs", _platform);
532
+ const json = JSON.parse(JSON.stringify(e));
533
+ return logs.save(name, json);
534
+ }
535
+ async function getExtension(_body, opts) {
536
+ const root = path.resolve("./");
537
+ const pkg = node.readJsonSync(path.resolve(root, "package.json"));
538
+ const { vtj = {} } = pkg || {};
539
+ const adapters = {
540
+ remote: "https://lcdp.vtj.pro",
541
+ access: {
542
+ auth: "/auth.html",
543
+ privateKey: "MIIBOgIBAAJBAKoIzmn1FYQ1YOhOBw9EhABxZ+PySAIaydI+zdhoKflrdgJ4A5E4/5gbQmRpk09hPWG8nvX7h+l/QLU8kXxAIBECAwEAAQJAAlgpxQY6sByLsXqzJcthC8LSGsLf2JEJkHwlnpwFqlEV8UCkoINpuZ2Wzl+aftURu5rIfAzRCQBvHmeOTW9/zQIhAO5ufWDmnSLyfAAsNo5JRNpVuLFCFodR8Xm+ulDlosR/AiEAtpAltyP9wmCABKG/v/hrtTr3mcvFNGCjoGa9bUAok28CIHbrVs9w1ijrBlvTsXYwJw46uP539uKRRT4ymZzlm9QjAiB+1KH/G9f9pEEL9rtaSOG7JF5D0JcOjlze4MGVFs+ZrQIhALKOUFBNr2zEsyJIjw2PlvEucdlG77UniszjXTROHSPd"
544
+ }
545
+ };
546
+ const extension = {
547
+ ...vtj.extension || {},
548
+ history: vtj.history || "hash",
549
+ base: vtj.base || "/",
550
+ pageRouteName: vtj.pageRouteName || (vtj.platform === "uniapp" ? "pages" : "page"),
551
+ __BASE_PATH__: opts.staticBase,
552
+ __adapters__: node.merge({}, adapters, vtj.adapters || {})
553
+ };
554
+ return success(extension);
555
+ }
556
+ async function init(_body, opts) {
557
+ const root = path.resolve("./");
558
+ const pkg = node.readJsonSync(path.resolve(root, "package.json"));
559
+ const pluginPepository = new PluginRepository(pkg, opts);
560
+ const { vtj = {} } = pkg || {};
561
+ const id = vtj.id || pkg.name;
562
+ const name = vtj.name || pkg.description || node.upperFirstCamelCase(id);
563
+ const description = vtj.description || pkg.description || "";
564
+ const platform = vtj.platform || "web";
565
+ _platform = platform;
566
+ const repository = new JsonRepository("projects", _platform);
567
+ let dsl = repository.get(id);
568
+ const plugins = pluginPepository.getPlugins();
569
+ if (dsl) {
570
+ const blocks = (dsl.blocks || []).filter((n) => !n.preset);
571
+ dsl.blocks = plugins.concat(blocks);
572
+ Object.assign(dsl, { id, name, description, platform });
573
+ if (platform === "uniapp") {
574
+ dsl.uniConfig = await getUniConfig(dsl);
575
+ }
576
+ if (!isInit) {
577
+ isInit = true;
578
+ repository.save(id, dsl);
579
+ }
580
+ dsl.__BASE_PATH__ = opts.staticBase;
581
+ return success(dsl);
582
+ } else {
583
+ const model = new core.ProjectModel({
584
+ id,
585
+ name,
586
+ description,
587
+ platform,
588
+ blocks: plugins
589
+ });
590
+ dsl = model.toDsl();
591
+ if (platform === "uniapp") {
592
+ dsl.uniConfig = await getUniConfig(dsl);
593
+ }
594
+ repository.save(id, dsl);
595
+ dsl.__BASE_PATH__ = opts.staticBase;
596
+ return success(dsl);
597
+ }
598
+ }
599
+ async function saveProject(dsl, type) {
600
+ const repository = new JsonRepository("projects", dsl.platform);
601
+ if (repository.exist(dsl.id)) {
602
+ const ret = repository.save(dsl.id, dsl);
603
+ if (dsl.platform === "uniapp") {
604
+ await genUniConfig(dsl, type === "delete");
605
+ }
606
+ return success(ret);
607
+ } else {
608
+ return fail("\u9879\u76EE\u6587\u4EF6\u4E0D\u5B58\u5728");
609
+ }
610
+ }
611
+ async function saveFile(dsl) {
612
+ const repository = new JsonRepository("files", _platform);
613
+ const ret = repository.save(dsl.id, dsl);
614
+ return success(ret);
615
+ }
616
+ async function getFile(id) {
617
+ const repository = new JsonRepository("files", _platform);
618
+ const json = repository.get(id);
619
+ if (json) {
620
+ return success(json);
621
+ } else {
622
+ return fail("\u6587\u4EF6\u4E0D\u5B58\u5728");
623
+ }
624
+ }
625
+ async function removeFile(id) {
626
+ const repository = new JsonRepository("files", _platform);
627
+ const ret = repository.remove(id);
628
+ return success(ret);
629
+ }
630
+ async function getHistory(id) {
631
+ const repository = new JsonRepository("histories", _platform);
632
+ const json = repository.get(id);
633
+ if (json) {
634
+ return success(json);
635
+ } else {
636
+ return success({});
637
+ }
638
+ }
639
+ async function saveHistory(file) {
640
+ const repository = new JsonRepository("histories", _platform);
641
+ const ret = repository.save(file.id, file);
642
+ return success(ret);
643
+ }
644
+ async function removeHistory(id) {
645
+ const repository = new JsonRepository("histories", _platform);
646
+ const items = new JsonRepository(`histories/${id}`, _platform);
647
+ items.clear();
648
+ repository.remove(id);
649
+ return success(true);
650
+ }
651
+ async function getHistoryItem(fId, id) {
652
+ const repository = new JsonRepository(`histories/${fId}`, _platform);
653
+ const json = repository.get(id);
654
+ if (json) {
655
+ return success(json);
656
+ } else {
657
+ return fail("\u6587\u4EF6\u4E0D\u5B58\u5728");
658
+ }
659
+ }
660
+ async function saveHistoryItem(fId, item) {
661
+ const repository = new JsonRepository(`histories/${fId}`, _platform);
662
+ repository.save(item.id, item);
663
+ return success(true);
664
+ }
665
+ async function removeHistoryItem(fId, ids) {
666
+ const repository = new JsonRepository(`histories/${fId}`, _platform);
667
+ ids.forEach((id) => {
668
+ repository.remove(id);
669
+ });
670
+ return success(true);
671
+ }
672
+ async function saveMaterials(project, materials) {
673
+ const repository = new JsonRepository("materials", _platform);
674
+ repository.save(project.id, materials);
675
+ return success(true);
676
+ }
677
+ async function publishFile(project, file, componentMap) {
678
+ const materialsRepository = new JsonRepository("materials", project.platform);
679
+ const materials = materialsRepository.get(project.id);
680
+ componentMap = componentMap || new Map(Object.entries(materials || {}));
681
+ const fileRepository = new JsonRepository("files", project.platform);
682
+ const dsl = fileRepository.get(file.id);
683
+ if (dsl) {
684
+ const content = await coder.generator(
685
+ dsl,
686
+ componentMap,
687
+ project.dependencies,
688
+ project.platform
689
+ ).catch((e) => {
690
+ try {
691
+ saveLogs({
692
+ dsl,
693
+ componentMap,
694
+ dependencies: project.dependencies,
695
+ message: e.message,
696
+ stack: e.stack
697
+ });
698
+ } catch (e2) {
699
+ }
700
+ throw e;
701
+ });
702
+ const vueRepository = new VueRepository(_platform);
703
+ vueRepository.save(file.id, content);
704
+ return success(true);
705
+ } else {
706
+ return fail("\u6587\u4EF6\u4E0D\u5B58\u5728");
707
+ }
708
+ }
709
+ async function publish(project) {
710
+ const { pages = [], blocks = [] } = project;
711
+ const materialsRepository = new JsonRepository("materials", project.platform);
712
+ const materials = materialsRepository.get(project.id);
713
+ const componentMap = new Map(
714
+ Object.entries(materials)
715
+ );
716
+ for (const block of blocks) {
717
+ if (!block.fromType || block.fromType === "Schema") {
718
+ await publishFile(project, block, componentMap);
719
+ }
720
+ }
721
+ for (const page of pages) {
722
+ if (!page.raw) {
723
+ await publishFile(project, page, componentMap);
724
+ }
725
+ }
726
+ if (project.platform === "uniapp") {
727
+ await genUniConfig(project, true);
728
+ }
729
+ return success(true);
730
+ }
731
+ async function genUniConfig(project, injectPages = false) {
732
+ const uniRepository = new UniRepository();
733
+ uniRepository.saveManifestJson(project);
734
+ if (injectPages) {
735
+ uniRepository.savePagesJson(project);
736
+ }
737
+ await uniRepository.saveApp(project);
738
+ return success(true);
739
+ }
740
+ async function genVueContent(project, dsl) {
741
+ const materialsRepository = new JsonRepository("materials", project.platform);
742
+ const materials = materialsRepository.get(project.id);
743
+ const componentMap = new Map(
744
+ Object.entries(materials)
745
+ );
746
+ const content = await coder.generator(
747
+ dsl,
748
+ componentMap,
749
+ project.dependencies,
750
+ project.platform
751
+ ).catch((e) => {
752
+ throw e;
753
+ });
754
+ return success(content);
755
+ }
756
+ async function createRawPage(file) {
757
+ const repository = new VueRepository(_platform);
758
+ const page = await coder.createEmptyPage(file);
759
+ repository.save(file.id, page);
760
+ return success(true);
761
+ }
762
+ async function removeRawPage(id) {
763
+ const repository = new VueRepository(_platform);
764
+ repository.remove(id);
765
+ return success(true);
766
+ }
767
+ async function uploadStaticFiles(files, options) {
768
+ const repository = new StaticRepository(options);
769
+ const error = repository.validate(files);
770
+ if (error) {
771
+ return fail("\u6587\u4EF6\u540D\u79F0\u5DF2\u5B58\u5728", error);
772
+ }
773
+ const res = repository.save(files);
774
+ return success(res);
775
+ }
776
+ async function removeStaticFile(filename, options) {
777
+ const repository = new StaticRepository(options);
778
+ const ret = repository.remove(filename);
779
+ return ret ? success(true) : fail("\u5220\u9664\u5931\u8D25");
780
+ }
781
+ async function getStaticFiles(options) {
782
+ const repository = new StaticRepository(options);
783
+ return success(repository.getAllFiles());
784
+ }
785
+ async function clearStaticFiles(options) {
786
+ const repository = new StaticRepository(options);
787
+ return success(repository.clear());
788
+ }
789
+
790
+ const controller = {
791
+ notMatch: async (_req) => {
792
+ return fail("\u627E\u4E0D\u5230\u5904\u7406\u7A0B\u5E8F");
793
+ },
794
+ getExtension: getExtension,
795
+ init: init,
796
+ saveProject: async (req) => {
797
+ const project = req.data;
798
+ return saveProject(project, req.query?.type);
799
+ },
800
+ saveFile: async (req) => {
801
+ const file = req.data;
802
+ return saveFile(file);
803
+ },
804
+ getFile: async (req) => {
805
+ const id = req.data;
806
+ return getFile(id);
807
+ },
808
+ removeFile: async (req) => {
809
+ const id = req.data;
810
+ return removeFile(id);
811
+ },
812
+ getHistory: async (req) => {
813
+ const id = req.data;
814
+ return getHistory(id);
815
+ },
816
+ saveHistory: async (req) => {
817
+ const file = req.data;
818
+ return saveHistory(file);
819
+ },
820
+ removeHistory: async (req) => {
821
+ const id = req.data;
822
+ return removeHistory(id);
823
+ },
824
+ getHistoryItem: async (req) => {
825
+ const { fId, id } = req.data || {};
826
+ return getHistoryItem(fId, id);
827
+ },
828
+ saveHistoryItem: async (req) => {
829
+ const { fId, item } = req.data || {};
830
+ return saveHistoryItem(fId, item);
831
+ },
832
+ removeHistoryItem: async (req) => {
833
+ const { fId, ids = [] } = req.data || {};
834
+ return removeHistoryItem(fId, ids);
835
+ },
836
+ saveMaterials: async (req) => {
837
+ const { project, materials } = req.data || {};
838
+ return saveMaterials(project, materials);
839
+ },
840
+ publishFile: async (req) => {
841
+ const { project, file } = req.data || {};
842
+ const result = await publishFile(project, file);
843
+ if (project.platform === "uniapp") {
844
+ await genUniConfig(project, true);
845
+ }
846
+ return result;
847
+ },
848
+ publish: async (req) => {
849
+ const project = req.data || {};
850
+ return publish(project);
851
+ },
852
+ genVueContent: async (req) => {
853
+ const { project, dsl } = req.data || {};
854
+ return genVueContent(project, dsl);
855
+ },
856
+ createRawPage: async (req) => {
857
+ const file = req.data;
858
+ return createRawPage(file);
859
+ },
860
+ removeRawPage: async (req) => {
861
+ const id = req.data;
862
+ return removeRawPage(id);
863
+ },
864
+ getStaticFiles: async (_req, opts) => {
865
+ return getStaticFiles(opts);
866
+ },
867
+ removeStaticFile: async (req, opts) => {
868
+ const name = req.data?.name;
869
+ return removeStaticFile(name, opts);
870
+ },
871
+ clearStaticFiles: async (_req, opts) => {
872
+ return clearStaticFiles(opts);
873
+ },
874
+ uploader: async (req, opts) => {
875
+ if (!opts)
876
+ return fail("\u5F02\u5E38\u9519\u8BEF");
877
+ const uploadDir = path.resolve(opts.staticDir, opts.vtjDir);
878
+ const form = formidable__default({
879
+ keepExtensions: true,
880
+ multiples: true,
881
+ createDirsFromUploads: true,
882
+ uploadDir
883
+ });
884
+ return await new Promise((reslove) => {
885
+ form.parse(req, (err, _fields, files) => {
886
+ if (err) {
887
+ reslove(fail("\u5F02\u5E38\u9519\u8BEF", err));
888
+ return;
889
+ }
890
+ const tempFiles = files.files || [];
891
+ const result = uploadStaticFiles(tempFiles, opts);
892
+ reslove(result);
893
+ });
894
+ });
895
+ }
896
+ };
897
+ function parse(str, sep, eq) {
898
+ const obj = {};
899
+ str = str.replace(/^[^]*\?/, "");
900
+ sep = sep || "&";
901
+ eq = eq || "=";
902
+ let arr;
903
+ const reg = new RegExp(
904
+ "(?:^|\\" + sep + ")([^\\" + eq + "\\" + sep + "]+)(?:\\" + eq + "([^\\" + sep + "]*))?",
905
+ "g"
906
+ );
907
+ while ((arr = reg.exec(str)) !== null) {
908
+ if (arr[1] !== str) {
909
+ obj[decodeURIComponent(arr[1])] = decodeURIComponent(arr[2] || "");
910
+ }
911
+ }
912
+ return obj;
913
+ }
914
+ const router = async (req, opts) => {
915
+ const body = req.body || {};
916
+ body.query = parse(req.url);
917
+ const reqUrl = req.url || "";
918
+ const uploaderPath = `${opts.baseURL}${opts.uploader}`;
919
+ const isUploader = reqUrl.startsWith(uploaderPath);
920
+ if (isUploader) {
921
+ return await controller.uploader(req, opts);
922
+ } else {
923
+ const handler = controller[body.type] || controller.notMatch;
924
+ try {
925
+ return await handler(body, opts);
926
+ } catch (e) {
927
+ const info = {
928
+ input: body,
929
+ error: {
930
+ message: e?.message,
931
+ stack: e?.stack
932
+ }
933
+ };
934
+ await saveLogs(info);
935
+ return fail("\u5F02\u5E38\u9519\u8BEF", e?.message, e?.stack);
936
+ }
937
+ }
938
+ };
939
+
940
+ const setApis = (server, options) => {
941
+ server.middlewares.use((req, res, next) => {
942
+ const reqUrl = req.url || "";
943
+ if (reqUrl.startsWith(options.baseURL)) {
944
+ bodyParser__default.json({ type: "application/json", limit: "50000kb" })(
945
+ req,
946
+ res,
947
+ next
948
+ );
949
+ } else {
950
+ next();
951
+ }
952
+ });
953
+ server.middlewares.use(async (req, res, next) => {
954
+ const reqUrl = req.url || "";
955
+ if (reqUrl.startsWith(options.baseURL)) {
956
+ const data = await router(req, options);
957
+ res.writeHead(200, { "Content-Type": "application/json" });
958
+ res.end(JSON.stringify(data));
959
+ } else {
960
+ next();
961
+ }
962
+ });
963
+ };
964
+ const apiServerPlugin = function(options) {
965
+ return {
966
+ name: "vtj-api-plugin",
967
+ apply: "serve",
968
+ configureServer(server) {
969
+ setApis(server, options);
970
+ },
971
+ configurePreviewServer(server) {
972
+ return () => {
973
+ setApis(server, options);
974
+ };
975
+ }
976
+ };
977
+ };
978
+ const linkPlugin = function(options) {
979
+ const {
980
+ entry = "/index.html",
981
+ href = "",
982
+ serveOnly = true
983
+ } = options.linkOptions || {};
984
+ let config;
985
+ return {
986
+ name: "vtj-link-plugin",
987
+ apply: serveOnly ? "serve" : void 0,
988
+ configResolved(resolvedConfig) {
989
+ config = resolvedConfig;
990
+ },
991
+ transformIndexHtml(html, ctx) {
992
+ if (html.includes("__VTJ_LINK__")) {
993
+ return html;
994
+ }
995
+ if (options.link) {
996
+ if (ctx.path !== entry) {
997
+ return html;
998
+ }
999
+ const link = typeof options.link === "string" ? options.link : `${CLIENT_DIR}/entry/index.js`;
1000
+ const url = `${config.base}${link}`;
1001
+ return html.replace(
1002
+ /<\/body>/,
1003
+ `
1004
+ <script>window.__VTJ_LINK__ = { href: '${href}' }<\/script>
1005
+ <script src="${url}"><\/script></body>
1006
+ `
1007
+ );
1008
+ }
1009
+ return html;
1010
+ }
1011
+ };
1012
+ };
1013
+ const hmPlugin = function(options) {
1014
+ const { hm } = options;
1015
+ return {
1016
+ name: "vtj-hm-plugin",
1017
+ transformIndexHtml(html) {
1018
+ return html.replace(
1019
+ /<\/body>/,
1020
+ `
1021
+ <script>
1022
+ (function () {
1023
+ window._hmt = window._hmt || [];
1024
+ const hm = document.createElement('script');
1025
+ hm.src = 'https://hm.baidu.com/hm.js?${hm}';
1026
+ var s = document.getElementsByTagName('script')[0];
1027
+ s.parentNode.insertBefore(hm, s);
1028
+ })();
1029
+ <\/script>
1030
+ `
1031
+ );
1032
+ }
1033
+ };
1034
+ };
1035
+ const aliasPlugin = function(options) {
1036
+ return {
1037
+ name: "vtj-alias-plugin",
1038
+ config(config) {
1039
+ const { root = process.cwd() } = config || {};
1040
+ const vtjDir = path.join(root, options.vtjDir);
1041
+ const packagesDir = path.join(root, options.packagesDir);
1042
+ const devAlias = options.devMode && process.env.NODE_ENV === "development" ? {
1043
+ "@vtj/ui/dist/style.css": path.join(
1044
+ packagesDir,
1045
+ "ui/src/style/index.scss"
1046
+ ),
1047
+ "@vtj/icons/dist/style.css": path.join(
1048
+ packagesDir,
1049
+ "icons/src/style.scss"
1050
+ ),
1051
+ "@vtj/designer/dist/style.css": path.join(
1052
+ packagesDir,
1053
+ "designer/src/style/index.scss"
1054
+ ),
1055
+ "@vtj/uni/dist/style.css": path.join(
1056
+ packagesDir,
1057
+ "uni/src/index.scss"
1058
+ ),
1059
+ "@vtj/base": path.join(packagesDir, "base/src"),
1060
+ "@vtj/utils": path.join(packagesDir, "utils/src/index.ts"),
1061
+ "@vtj/icons/svg": path.join(packagesDir, "icons/dist/svg.ts"),
1062
+ "@vtj/icons": path.join(packagesDir, "icons/src"),
1063
+ "@vtj/ui": path.join(packagesDir, "ui/src"),
1064
+ "@vtj/charts": path.join(packagesDir, "charts/src"),
1065
+ "@vtj/core": path.join(packagesDir, "core/src"),
1066
+ "@vtj/designer": path.join(packagesDir, "designer/src"),
1067
+ "@vtj/renderer": path.join(packagesDir, "renderer/src"),
1068
+ "@vtj/coder": path.join(packagesDir, "coder/src"),
1069
+ "@vtj/uni": path.join(packagesDir, "uni/src")
1070
+ } : {};
1071
+ if (config.resolve) {
1072
+ let alias = config.resolve.alias || {};
1073
+ if (Array.isArray(alias)) {
1074
+ alias.push({
1075
+ find: "$vtj",
1076
+ replacement: vtjDir
1077
+ });
1078
+ alias.push(
1079
+ ...Object.entries(devAlias).map(([find, replacement]) => ({
1080
+ find,
1081
+ replacement
1082
+ }))
1083
+ );
1084
+ } else {
1085
+ Object.assign(alias, {
1086
+ $vtj: vtjDir,
1087
+ ...devAlias
1088
+ });
1089
+ }
1090
+ config.resolve.alias = alias;
1091
+ } else {
1092
+ config.resolve = {
1093
+ alias: {
1094
+ $vtj: vtjDir,
1095
+ ...devAlias
1096
+ }
1097
+ };
1098
+ }
1099
+ }
1100
+ };
1101
+ };
1102
+ function parsePresetPlugins(options) {
1103
+ const {
1104
+ presetPlugins = [],
1105
+ pluginNodeModulesDir = "node_modules",
1106
+ staticBase
1107
+ } = options;
1108
+ const pkg = node.readJsonSync(path.resolve("./package.json"));
1109
+ const { devDependencies, dependencies } = pkg || {};
1110
+ const deps = Object.keys({ ...devDependencies, ...dependencies }).filter(
1111
+ (name) => presetPlugins.some((regex) => name.startsWith(regex))
1112
+ );
1113
+ const copies = [];
1114
+ const staticDirs = [];
1115
+ for (const dep of deps) {
1116
+ const dist = path.join(pluginNodeModulesDir, dep, "dist");
1117
+ if (node.pathExistsSync(dist)) {
1118
+ copies.push({
1119
+ from: dist,
1120
+ to: "@vtj/plugins",
1121
+ emptyDir: false
1122
+ });
1123
+ staticDirs.push({
1124
+ path: `${staticBase}@vtj/plugins`,
1125
+ dir: dist
1126
+ });
1127
+ }
1128
+ }
1129
+ return {
1130
+ copies,
1131
+ staticDirs
1132
+ };
1133
+ }
1134
+ function createDevTools(options = {}) {
1135
+ const opts = {
1136
+ baseURL: `/${CLIENT_DIR}/api`,
1137
+ copy: true,
1138
+ server: true,
1139
+ staticBase: "/",
1140
+ staticDir: "public",
1141
+ link: true,
1142
+ linkOptions: null,
1143
+ vtjDir: ".vtj",
1144
+ packagesDir: "../../packages",
1145
+ devMode: false,
1146
+ uploader: "/uploader.json",
1147
+ packageName: "@vtj/pro",
1148
+ nodeModulesDir: "node_modules",
1149
+ presetPlugins: ["@newpearl/plugin-", "@vtj/plugin-"],
1150
+ pluginNodeModulesDir: "node_modules",
1151
+ extensionDir: "",
1152
+ materialDirs: [],
1153
+ hm: "42f2469b4aa27c3f8978f634c0c19d24",
1154
+ ...options
1155
+ };
1156
+ const plugins = [aliasPlugin(opts)];
1157
+ const proPath = `${opts.nodeModulesDir}/${opts.packageName}/dist`;
1158
+ const materialsPath1 = `${opts.nodeModulesDir}/@vtj/materials/dist`;
1159
+ const materialsPath2 = `${opts.nodeModulesDir}/${opts.packageName}/${materialsPath1}`;
1160
+ const materialDirs = opts.materialDirs.map((n) => {
1161
+ return `${opts.pluginNodeModulesDir}/${n}/dist`;
1162
+ });
1163
+ if (opts.copy) {
1164
+ const copyOptions = [];
1165
+ if (node.pathExistsSync(materialsPath1)) {
1166
+ copyOptions.push({
1167
+ from: materialsPath1,
1168
+ to: "@vtj/materials",
1169
+ emptyDir: true
1170
+ });
1171
+ } else if (node.pathExistsSync(materialsPath2)) {
1172
+ copyOptions.push({
1173
+ from: materialsPath2,
1174
+ to: "@vtj/materials",
1175
+ emptyDir: true
1176
+ });
1177
+ } else {
1178
+ console.warn(
1179
+ "\n @vtj/materials is not installed, please install it first.\n"
1180
+ );
1181
+ }
1182
+ materialDirs.forEach((form) => {
1183
+ copyOptions.push({
1184
+ from: form,
1185
+ to: "@vtj/materials",
1186
+ emptyDir: false
1187
+ });
1188
+ });
1189
+ if (opts.extensionDir && node.pathExistsSync(opts.extensionDir)) {
1190
+ copyOptions.push({
1191
+ from: opts.extensionDir,
1192
+ to: "@vtj/extension",
1193
+ emptyDir: true
1194
+ });
1195
+ }
1196
+ if (copyOptions.length > 0) {
1197
+ plugins.push(cli.copyPlugin(copyOptions));
1198
+ }
1199
+ }
1200
+ if (opts.server) {
1201
+ plugins.push(apiServerPlugin(opts));
1202
+ const staticOptions = [];
1203
+ if (node.pathExistsSync(proPath)) {
1204
+ staticOptions.push({
1205
+ path: `${opts.staticBase}${CLIENT_DIR}`,
1206
+ dir: proPath
1207
+ });
1208
+ }
1209
+ if (node.pathExistsSync(materialsPath1)) {
1210
+ staticOptions.push({
1211
+ path: `${opts.staticBase}@vtj/materials`,
1212
+ dir: materialsPath1
1213
+ });
1214
+ } else if (node.pathExistsSync(materialsPath2)) {
1215
+ staticOptions.push({
1216
+ path: `${opts.staticBase}@vtj/materials`,
1217
+ dir: materialsPath2
1218
+ });
1219
+ } else {
1220
+ console.warn(
1221
+ "\n @vtj/materials is not installed, please install it first.\n"
1222
+ );
1223
+ }
1224
+ materialDirs.forEach((dir) => {
1225
+ staticOptions.push({
1226
+ path: `${opts.staticBase}@vtj/materials`,
1227
+ dir
1228
+ });
1229
+ });
1230
+ if (opts.extensionDir && node.pathExistsSync(opts.extensionDir)) {
1231
+ staticOptions.push({
1232
+ path: `${opts.staticBase}@vtj/extension`,
1233
+ dir: opts.extensionDir
1234
+ });
1235
+ }
1236
+ if (staticOptions.length > 0) {
1237
+ plugins.push(cli.staticPlugin(staticOptions));
1238
+ }
1239
+ }
1240
+ if (opts.presetPlugins && opts.presetPlugins.length) {
1241
+ const { copies, staticDirs } = parsePresetPlugins(opts);
1242
+ if (copies.length) {
1243
+ plugins.push(cli.copyPlugin(copies));
1244
+ }
1245
+ if (staticDirs.length) {
1246
+ plugins.push(cli.staticPlugin(staticDirs));
1247
+ }
1248
+ }
1249
+ if (!!opts.link) {
1250
+ plugins.push(linkPlugin(opts));
1251
+ }
1252
+ if (opts.hm) {
1253
+ plugins.push(hmPlugin(opts));
1254
+ }
1255
+ return plugins;
1256
+ }
1257
+
1258
+ exports.createDevTools = createDevTools;
1259
+ exports.parsePresetPlugins = parsePresetPlugins;