@yinuo-ngm/server 1.0.19 → 1.0.21

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.
Files changed (104) hide show
  1. package/lib/app.js +0 -4
  2. package/lib/env.js +5 -1
  3. package/lib/plugins/success-handle.plugin.js +1 -1
  4. package/lib/plugins/ws/topics/nginx.ws.js +1 -1
  5. package/lib/plugins/ws/ws.context.js +3 -1
  6. package/lib/plugins/ws/ws.plugin.js +14 -2
  7. package/lib/routes/api-client/collection.routes.js +35 -35
  8. package/lib/routes/api-client/env.routes.js +12 -8
  9. package/lib/routes/api-client/history.routes.js +10 -5
  10. package/lib/routes/api-client/request.routes.js +14 -8
  11. package/lib/routes/api-client/route-mappers.d.ts +7 -0
  12. package/lib/routes/api-client/route-mappers.js +78 -0
  13. package/lib/routes/api-client/send.routes.js +12 -8
  14. package/lib/routes/config.routes.js +73 -49
  15. package/lib/routes/deps.route.js +47 -5
  16. package/lib/routes/nginx/nginx-config.routes.js +3 -3
  17. package/lib/routes/nginx/nginx-lifecycle.routes.js +14 -13
  18. package/lib/routes/nginx/nginx-module.routes.js +6 -6
  19. package/lib/routes/nginx/nginx-route.context.d.ts +16 -1
  20. package/lib/routes/nginx/nginx-route.context.js +136 -1
  21. package/lib/routes/nginx/nginx-server.routes.js +5 -5
  22. package/lib/routes/project.routes.js +90 -13
  23. package/lib/routes/sprite-browse.routes.js +17 -11
  24. package/lib/routes/sprite.routes.d.ts +1 -1
  25. package/lib/routes/sprite.routes.js +68 -11
  26. package/lib/routes/svn.routes.js +48 -14
  27. package/lib/routes/task.routes.js +99 -7
  28. package/package.json +7 -7
  29. package/www/3rdpartylicenses.txt +5 -5
  30. package/www/browser/{chunk-OZCK4XVV.js → chunk-2VJVGBXG.js} +1 -1
  31. package/www/browser/{chunk-FL6GDGHW.js → chunk-3ODVU46S.js} +1 -1
  32. package/www/browser/chunk-442QFABJ.js +1 -0
  33. package/www/browser/{chunk-WD2EKZQC.js → chunk-6J6G7JEP.js} +1 -1
  34. package/www/browser/{chunk-7U44RF5F.js → chunk-6UFDNETG.js} +1 -1
  35. package/www/browser/{chunk-75W3GVSO.js → chunk-7AKVG375.js} +1 -1
  36. package/www/browser/chunk-7GLWEFTM.js +1 -0
  37. package/www/browser/{chunk-DIJPUYIA.js → chunk-7QR6RHLA.js} +1 -1
  38. package/www/browser/{chunk-HJTXXSMC.js → chunk-CO3CQHKV.js} +1 -1
  39. package/www/browser/{chunk-3XNNQFWR.js → chunk-CPJTSA6E.js} +1 -1
  40. package/www/browser/chunk-DENFXXOY.js +1 -0
  41. package/www/browser/{chunk-HDNG236Q.js → chunk-HC5KLPHD.js} +1 -1
  42. package/www/browser/chunk-HJAP6WBI.js +1 -0
  43. package/www/browser/{chunk-N2PELLMM.js → chunk-JM6DCZP6.js} +7 -7
  44. package/www/browser/chunk-K6C5ZIV2.js +20 -0
  45. package/www/browser/chunk-M6NZ6C2R.js +2 -0
  46. package/www/browser/{chunk-RGOYDY7H.js → chunk-MBPB43C6.js} +1 -1
  47. package/www/browser/chunk-MPLGMTLT.js +3 -0
  48. package/www/browser/chunk-NNOWADVM.js +1 -0
  49. package/www/browser/{chunk-M4QRBV3K.js → chunk-NREWZQVN.js} +1 -1
  50. package/www/browser/{chunk-6YYNHZ2A.js → chunk-OUGN4APK.js} +1 -1
  51. package/www/browser/chunk-PB2LGZNW.js +1 -0
  52. package/www/browser/chunk-PDI3HSSH.js +4 -0
  53. package/www/browser/chunk-PUG3VNTI.js +3 -0
  54. package/www/browser/{chunk-QJP5F735.js → chunk-PY3AUTHC.js} +1 -1
  55. package/www/browser/{chunk-3M56F2S2.js → chunk-R4HSZU2J.js} +1 -1
  56. package/www/browser/{chunk-DE6E23ET.js → chunk-RKK4I2RT.js} +1 -1
  57. package/www/browser/chunk-RMIYLAEM.js +1 -0
  58. package/www/browser/chunk-RZA3IFQV.js +2 -0
  59. package/www/browser/{chunk-K7PESFPY.js → chunk-SD2HFD54.js} +1 -1
  60. package/www/browser/{chunk-BTQIUVTQ.js → chunk-SEJGGBE2.js} +1 -1
  61. package/www/browser/chunk-SSCUT2GF.js +1 -0
  62. package/www/browser/chunk-TCBOC5FF.js +1 -0
  63. package/www/browser/{chunk-AZ6SIMYH.js → chunk-TS5ZQYYY.js} +1 -1
  64. package/www/browser/chunk-TVJHI463.js +1 -0
  65. package/www/browser/{chunk-YNW4HEJO.js → chunk-TXAXE73U.js} +17 -17
  66. package/www/browser/{chunk-4X42HB6N.js → chunk-U2YWR3HF.js} +1 -1
  67. package/www/browser/{chunk-D2ODDESN.js → chunk-U3EUR236.js} +1 -1
  68. package/www/browser/chunk-UKCMUTYL.js +1 -0
  69. package/www/browser/{chunk-DLGJD6YU.js → chunk-UPOORT3S.js} +1 -1
  70. package/www/browser/chunk-VW3S7C2Z.js +1 -0
  71. package/www/browser/chunk-VZYJ3MSW.js +15 -0
  72. package/www/browser/{chunk-AELTP6YN.js → chunk-WCHN62X6.js} +1 -1
  73. package/www/browser/chunk-WWIPELAV.js +1 -0
  74. package/www/browser/{chunk-B3C35ET3.js → chunk-WYNERG74.js} +1 -1
  75. package/www/browser/{chunk-ZTDLWBW5.js → chunk-XJDJL3TQ.js} +1 -1
  76. package/www/browser/{chunk-EEDA5U4V.js → chunk-YV6QPLF5.js} +1 -1
  77. package/www/browser/{chunk-ONXBYGIG.js → chunk-YVRGRFK2.js} +1 -1
  78. package/www/browser/index.html +1 -1
  79. package/www/browser/main-7GYUOEJY.js +38 -0
  80. package/lib/plugins/api-client.plugin.d.ts +0 -3
  81. package/lib/plugins/api-client.plugin.js +0 -55
  82. package/lib/plugins/nginx.binding.store.d.ts +0 -4
  83. package/lib/plugins/nginx.binding.store.js +0 -39
  84. package/lib/plugins/nginx.plugin.d.ts +0 -3
  85. package/lib/plugins/nginx.plugin.js +0 -23
  86. package/www/browser/chunk-2L7NUOMX.js +0 -2
  87. package/www/browser/chunk-2NZJ7CN2.js +0 -20
  88. package/www/browser/chunk-3CM4SKDO.js +0 -15
  89. package/www/browser/chunk-3OHBKMAA.js +0 -1
  90. package/www/browser/chunk-4LBSLURA.js +0 -1
  91. package/www/browser/chunk-5DYX4DUX.js +0 -11
  92. package/www/browser/chunk-6SYVDN5L.js +0 -1
  93. package/www/browser/chunk-AMXRL4GR.js +0 -1
  94. package/www/browser/chunk-AV2ZODEH.js +0 -1
  95. package/www/browser/chunk-CN5J4WNO.js +0 -1
  96. package/www/browser/chunk-FK6Z4HLL.js +0 -1
  97. package/www/browser/chunk-FXCG34QS.js +0 -1
  98. package/www/browser/chunk-H5HGMOE6.js +0 -1
  99. package/www/browser/chunk-HB3HECPD.js +0 -1
  100. package/www/browser/chunk-HUMCWAKJ.js +0 -3
  101. package/www/browser/chunk-IKB3EQCP.js +0 -2
  102. package/www/browser/chunk-OSBDR36P.js +0 -1
  103. package/www/browser/chunk-XLFHB7RS.js +0 -3
  104. package/www/browser/main-N64WJCHX.js +0 -34
@@ -37,10 +37,82 @@ exports.default = projectRoutes;
37
37
  const errors_1 = require("@yinuo-ngm/errors");
38
38
  const path = __importStar(require("path"));
39
39
  const editor_1 = require("../common/editor");
40
+ function toProjectAssetSourceSvnDto(source) {
41
+ return {
42
+ kind: source.kind,
43
+ id: source.id,
44
+ label: source.label,
45
+ url: source.url,
46
+ localDir: source.localDir,
47
+ mode: source.mode,
48
+ };
49
+ }
50
+ function toProjectAssetsDto(assets) {
51
+ if (!assets)
52
+ return undefined;
53
+ return {
54
+ iconsSvn: assets.iconsSvn ? toProjectAssetSourceSvnDto(assets.iconsSvn) : undefined,
55
+ cutImageSvn: assets.cutImageSvn ? toProjectAssetSourceSvnDto(assets.cutImageSvn) : undefined,
56
+ };
57
+ }
58
+ function toProjectDto(project) {
59
+ return {
60
+ id: project.id,
61
+ name: project.name,
62
+ description: project.description,
63
+ root: project.root,
64
+ createdAt: project.createdAt,
65
+ updatedAt: project.updatedAt,
66
+ scripts: project.scripts,
67
+ packageManager: project.packageManager,
68
+ framework: project.framework,
69
+ env: project.env,
70
+ isFavorite: project.isFavorite,
71
+ lastOpened: project.lastOpened,
72
+ repoUrl: project.repoUrl,
73
+ repoPageUrl: project.repoPageUrl,
74
+ assets: toProjectAssetsDto(project.assets),
75
+ };
76
+ }
77
+ function toDetectResultDto(detect) {
78
+ if (!detect)
79
+ return undefined;
80
+ return {
81
+ framework: detect.framework,
82
+ hasPackageJson: detect.hasPackageJson,
83
+ scripts: detect.scripts,
84
+ scriptsCount: detect.scriptsCount,
85
+ recommendedScript: detect.recommendedScript,
86
+ lockFile: detect.lockFile,
87
+ hasGit: detect.hasGit,
88
+ hasMakefile: detect.hasMakefile,
89
+ hasDockerCompose: detect.hasDockerCompose,
90
+ };
91
+ }
92
+ function toImportCheckResultDto(result) {
93
+ return {
94
+ ok: result.ok,
95
+ root: result.root,
96
+ code: result.code,
97
+ reason: result.reason,
98
+ detect: toDetectResultDto(result.detect),
99
+ warnings: result.warnings,
100
+ };
101
+ }
102
+ function toCheckRootResultDto(result) {
103
+ return {
104
+ ok: result.ok,
105
+ root: result.root,
106
+ exists: result.exists,
107
+ isDir: result.isDir,
108
+ alreadyRegistered: result.alreadyRegistered,
109
+ message: result.message,
110
+ };
111
+ }
40
112
  async function projectRoutes(fastify) {
41
113
  fastify.get("/list", async () => {
42
114
  const projects = await fastify.core.project.list();
43
- return projects;
115
+ return projects.map(toProjectDto);
44
116
  });
45
117
  fastify.post("/update/:id", async (req, reply) => {
46
118
  const { id } = req.params;
@@ -55,7 +127,7 @@ async function projectRoutes(fastify) {
55
127
  ...(body.env !== undefined ? { env: body.env } : {}),
56
128
  ...(body.scripts !== undefined ? { scripts: body.scripts } : {}),
57
129
  });
58
- return updated;
130
+ return toProjectDto(updated);
59
131
  }
60
132
  catch (err) {
61
133
  if (err instanceof Error) {
@@ -67,7 +139,7 @@ async function projectRoutes(fastify) {
67
139
  fastify.get("/getInfo/:id", async (req) => {
68
140
  const { id } = req.params;
69
141
  const project = await fastify.core.project.get(id);
70
- return project;
142
+ return toProjectDto(project);
71
143
  });
72
144
  fastify.delete("/delete/:id", async (req) => {
73
145
  const { id } = req.params;
@@ -76,7 +148,8 @@ async function projectRoutes(fastify) {
76
148
  });
77
149
  fastify.post("/check", async (req) => {
78
150
  const body = req.body;
79
- return fastify.core.project.checkRoot(body.rootPath);
151
+ const result = await fastify.core.project.checkRoot(body.rootPath);
152
+ return toCheckRootResultDto(result);
80
153
  });
81
154
  fastify.post("/detect", async (req) => {
82
155
  const body = req.body;
@@ -85,13 +158,16 @@ async function projectRoutes(fastify) {
85
158
  return {
86
159
  framework: meta.framework ?? "unknown",
87
160
  hasPackageJson: !!meta.scripts && Object.keys(meta.scripts).length > 0,
88
- scripts: meta.scripts ?? {},
161
+ scripts: Object.keys(meta.scripts ?? {}),
162
+ scriptsCount: Object.keys(meta.scripts ?? {}).length,
89
163
  recommendedScript: meta.scripts?.dev
90
164
  ? "dev"
91
165
  : meta.scripts?.start
92
166
  ? "start"
93
167
  : Object.keys(meta.scripts ?? {})[0],
94
168
  hasGit: meta.hasGit ?? false,
169
+ hasMakefile: meta.hasMakefile ?? false,
170
+ hasDockerCompose: meta.hasDockerCompose ?? false,
95
171
  };
96
172
  });
97
173
  fastify.post("/import", async (req) => {
@@ -109,7 +185,8 @@ async function projectRoutes(fastify) {
109
185
  });
110
186
  fastify.post("/checkImport", async (req) => {
111
187
  const body = req.body;
112
- return fastify.core.project.checkImport(body.root);
188
+ const result = await fastify.core.project.checkImport(body.root);
189
+ return toImportCheckResultDto(result);
113
190
  });
114
191
  fastify.post("/create", async (req) => {
115
192
  const body = req.body;
@@ -127,12 +204,12 @@ async function projectRoutes(fastify) {
127
204
  return { message: "isFavorite must be boolean" };
128
205
  }
129
206
  const updated = await fastify.core.project.setFavorite(id, body.isFavorite);
130
- return updated;
207
+ return toProjectDto(updated);
131
208
  });
132
209
  fastify.post("/favorite/:id/toggle", async (req) => {
133
210
  const { id } = req.params;
134
211
  const updated = await fastify.core.project.toggleFavorite(id);
135
- return updated;
212
+ return toProjectDto(updated);
136
213
  });
137
214
  fastify.post("/lastOpened/:id", async (req) => {
138
215
  const { id } = req.params;
@@ -141,7 +218,7 @@ async function projectRoutes(fastify) {
141
218
  throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.INVALID_TIMESTAMP, "timestamp must be a number");
142
219
  }
143
220
  const updated = await fastify.core.project.setLastOpened(id, body.timestamp);
144
- return updated;
221
+ return toProjectDto(updated);
145
222
  });
146
223
  fastify.post("/rename/:id", async (req) => {
147
224
  const { id } = req.params;
@@ -150,12 +227,12 @@ async function projectRoutes(fastify) {
150
227
  throw new errors_1.CoreError(errors_1.CoreErrorCodes.INVALID_NAME, "name must be a non-empty string");
151
228
  }
152
229
  const updated = await fastify.core.project.rename(id, body.name.trim());
153
- return updated;
230
+ return toProjectDto(updated);
154
231
  });
155
232
  fastify.post("/refreshScripts/:id", async (req) => {
156
233
  const { id } = req.params;
157
234
  const updated = await fastify.core.project.refreshScripts(id);
158
- return updated;
235
+ return toProjectDto(updated);
159
236
  });
160
237
  fastify.post("/edit/:id", async (req) => {
161
238
  const { id } = req.params;
@@ -168,7 +245,7 @@ async function projectRoutes(fastify) {
168
245
  description: body.description?.trim(),
169
246
  repoPageUrl: body.repoPageUrl?.trim(),
170
247
  });
171
- return updated;
248
+ return toProjectDto(updated);
172
249
  });
173
250
  fastify.post("/updateAssets/:id", async (req) => {
174
251
  const { id } = req.params;
@@ -178,7 +255,7 @@ async function projectRoutes(fastify) {
178
255
  throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, "参数错误,assets.iconsSvn 是必需的");
179
256
  }
180
257
  const updated = await fastify.core.project.updateAssets(id, assets);
181
- return updated;
258
+ return toProjectDto(updated);
182
259
  });
183
260
  fastify.post("/openInEditor/:id", async (req) => {
184
261
  try {
@@ -31,7 +31,7 @@ function listDir(root) {
31
31
  .filter(d => !SKIP.has(d.name) && !d.name.startsWith("."))
32
32
  .map(d => ({
33
33
  name: d.name,
34
- kind: d.isDirectory() ? "dir" : "file",
34
+ kind: (d.isDirectory() ? "dir" : "file"),
35
35
  ext: d.isDirectory() ? undefined : node_path_1.default.extname(d.name).toLowerCase(),
36
36
  })).sort((a, b) => {
37
37
  if (a.kind === b.kind) {
@@ -45,6 +45,12 @@ function countFiles(dir) {
45
45
  return 0;
46
46
  return node_fs_1.default.readdirSync(dir, { withFileTypes: true }).filter(d => d.isFile()).length;
47
47
  }
48
+ function toBrowseEntriesDto(root, entries) {
49
+ return { root, entries };
50
+ }
51
+ function toBrowseFilesDto(root, dir, entries) {
52
+ return { root, dir, entries };
53
+ }
48
54
  async function spriteBrowseRoutes(fastify) {
49
55
  fastify.get("/icons/groups/:projectId", async (req) => {
50
56
  const { projectId } = req.params;
@@ -53,7 +59,7 @@ async function spriteBrowseRoutes(fastify) {
53
59
  const localRoot = String(cfg?.localImageRoot ?? "").trim();
54
60
  const root = localRoot || project?.assets?.iconsSvn?.localDir;
55
61
  if (!root) {
56
- return { root: "", entries: [] };
62
+ return toBrowseEntriesDto("", []);
57
63
  }
58
64
  const entries = listDir(root).filter(e => e.kind === "dir");
59
65
  if (localRoot) {
@@ -62,7 +68,7 @@ async function spriteBrowseRoutes(fastify) {
62
68
  entries.unshift({ name: "root", kind: "dir", ext: undefined });
63
69
  }
64
70
  }
65
- return { root, entries };
71
+ return toBrowseEntriesDto(root, entries);
66
72
  });
67
73
  fastify.get("/icons/files/:projectId", async (req) => {
68
74
  const { projectId } = req.params;
@@ -72,10 +78,10 @@ async function spriteBrowseRoutes(fastify) {
72
78
  const localRoot = String(cfg?.localImageRoot ?? "").trim();
73
79
  const root = localRoot || project?.assets?.iconsSvn?.localDir;
74
80
  if (!root) {
75
- return { root: "", entries: [] };
81
+ return toBrowseEntriesDto("", []);
76
82
  }
77
83
  const isRootGroup = !!localRoot && (group === "root");
78
- const groupDir = isRootGroup ? root : safeJoin(root, group || '');
84
+ const groupDir = isRootGroup ? root : safeJoin(root, group || "");
79
85
  const entries = listDir(groupDir)
80
86
  .filter(e => e.kind === "file")
81
87
  .map(e => ({
@@ -84,22 +90,22 @@ async function spriteBrowseRoutes(fastify) {
84
90
  ? `/api/static/local/${projectId}/${isRootGroup ? e.name : `${group}/${e.name}`}`
85
91
  : `/api/static/svn/${projectId}/icons/${group}/${e.name}`,
86
92
  }));
87
- return { root: groupDir, entries };
93
+ return toBrowseEntriesDto(groupDir, entries);
88
94
  });
89
95
  fastify.get("/images/list/:projectId", async (req) => {
90
96
  const { projectId } = req.params;
91
97
  const project = await fastify.core.project.get(projectId);
92
98
  const root = project?.assets?.cutImageSvn?.localDir;
93
99
  if (!root) {
94
- return { root: "", entries: [] };
100
+ return toBrowseEntriesDto("", []);
95
101
  }
96
102
  const dir = String(req.query?.dir ?? "").trim();
97
103
  if (dir.split(/[\\/]/g).some(seg => seg === "..")) {
98
- return { root, dir: "", entries: [] };
104
+ return toBrowseFilesDto(root, "", []);
99
105
  }
100
106
  const absDir = dir ? safeJoin(root, dir) : root;
101
107
  if (!node_fs_1.default.existsSync(absDir))
102
- return { root, dir, entries: [] };
108
+ return toBrowseFilesDto(root, dir, []);
103
109
  const entries = listDir(absDir).map(e => {
104
110
  if (e.kind === "file") {
105
111
  const rel = dir ? `${dir}/${e.name}` : e.name;
@@ -112,11 +118,11 @@ async function spriteBrowseRoutes(fastify) {
112
118
  const rel = dir ? `${dir}/${e.name}` : e.name;
113
119
  return {
114
120
  ...e,
115
- fileCount: countFiles(safeJoin(root, rel))
121
+ fileCount: countFiles(safeJoin(root, rel)),
116
122
  };
117
123
  }
118
124
  return e;
119
125
  });
120
- return { root, dir, entries };
126
+ return toBrowseFilesDto(root, dir, entries);
121
127
  });
122
128
  }
@@ -1,2 +1,2 @@
1
- import { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance } from "fastify";
2
2
  export declare function spriteRoutes(fastify: FastifyInstance): Promise<void>;
@@ -6,27 +6,75 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.spriteRoutes = spriteRoutes;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const errors_1 = require("@yinuo-ngm/errors");
9
+ function toSpriteConfigDto(cfg) {
10
+ return {
11
+ projectId: cfg.projectId,
12
+ enabled: cfg.enabled,
13
+ sourceId: cfg.sourceId,
14
+ localDir: cfg.localDir,
15
+ prefix: cfg.prefix,
16
+ template: cfg.template,
17
+ spriteUrl: cfg.spriteUrl,
18
+ spriteExportDir: cfg.spriteExportDir,
19
+ lessExportDir: cfg.lessExportDir,
20
+ algorithm: cfg.algorithm,
21
+ persistLess: cfg.persistLess,
22
+ updatedAt: cfg.updatedAt,
23
+ localImageRoot: cfg.localImageRoot,
24
+ localCacheDir: cfg.localCacheDir,
25
+ };
26
+ }
27
+ function toSpriteGroupItemDto(item) {
28
+ return {
29
+ group: item.group,
30
+ kind: item.kind,
31
+ previewSpriteUrl: item.previewSpriteUrl,
32
+ spriteUrl: item.spriteUrl,
33
+ meta: item.meta,
34
+ lessText: item.lessText,
35
+ exported: item.exported,
36
+ status: item.status,
37
+ error: item.error,
38
+ };
39
+ }
40
+ function toSpriteSnapshotDto(snapshot) {
41
+ return {
42
+ projectId: snapshot.projectId,
43
+ sourceId: snapshot.sourceId,
44
+ iconsRoot: snapshot.iconsRoot,
45
+ cacheOutDir: snapshot.cacheOutDir,
46
+ config: toSpriteConfigDto(snapshot.config),
47
+ total: snapshot.total,
48
+ success: snapshot.success,
49
+ failed: snapshot.failed,
50
+ groups: (snapshot.groups ?? []).map(toSpriteGroupItemDto),
51
+ };
52
+ }
53
+ function toGenerateSpriteResultDto(snapshot) {
54
+ return toSpriteSnapshotDto(snapshot);
55
+ }
9
56
  async function spriteRoutes(fastify) {
10
57
  fastify.get("/config/:projectId", async (req) => {
11
58
  const { projectId } = req.params;
12
- return await fastify.core.sprite.getConfig(projectId);
59
+ const cfg = await fastify.core.sprite.getConfig(projectId);
60
+ return cfg ? toSpriteConfigDto(cfg) : null;
13
61
  });
14
62
  fastify.post("/config/:projectId", async (req) => {
15
63
  const { projectId } = req.params;
16
64
  const body = req.body;
17
65
  if (!body || !body.config) {
18
- throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, 'Missing config in request body');
66
+ throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, "Missing config in request body");
19
67
  }
20
68
  const nextCfg = body.config;
21
- const nextAssets = body.assets || {};
69
+ const nextAssets = (body.assets || {});
22
70
  const hasLocalImageRoot = !!String(nextCfg.localImageRoot ?? "").trim();
23
71
  if (!nextAssets.iconsSvn && !hasLocalImageRoot) {
24
- throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, 'iconsSvn asset or localImageRoot is required');
72
+ throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, "iconsSvn asset or localImageRoot is required");
25
73
  }
26
74
  if (nextCfg.localDir && nextAssets.iconsSvn) {
27
- nextAssets.iconsSvn.localDir = node_path_1.default.join(nextCfg.localDir, nextAssets.iconsSvn.label || 'icons');
75
+ nextAssets.iconsSvn.localDir = node_path_1.default.join(nextCfg.localDir, nextAssets.iconsSvn.label || "icons");
28
76
  if (nextAssets.cutImageSvn) {
29
- nextAssets.cutImageSvn.localDir = node_path_1.default.join(nextCfg.localDir, nextAssets.cutImageSvn.label || 'images');
77
+ nextAssets.cutImageSvn.localDir = node_path_1.default.join(nextCfg.localDir, nextAssets.cutImageSvn.label || "images");
30
78
  }
31
79
  }
32
80
  const shouldUpdateAssets = !!(nextAssets.iconsSvn || nextAssets.cutImageSvn);
@@ -37,7 +85,16 @@ async function spriteRoutes(fastify) {
37
85
  nextCfg.sourceId = project.assets.iconsSvn.id;
38
86
  }
39
87
  const cfg = await fastify.core.sprite.createConfig(projectId, nextCfg);
40
- return { cfg, project };
88
+ const assets = project.assets
89
+ ? {
90
+ iconsSvn: project.assets.iconsSvn,
91
+ cutImageSvn: project.assets.cutImageSvn,
92
+ }
93
+ : undefined;
94
+ return {
95
+ cfg: toSpriteConfigDto(cfg),
96
+ project: { id: project.id, name: project.name, root: project.root, assets },
97
+ };
41
98
  });
42
99
  fastify.post("/generate/:projectId", async (req) => {
43
100
  const { projectId } = req.params;
@@ -48,12 +105,12 @@ async function spriteRoutes(fastify) {
48
105
  concurrency: body.concurrency ?? 1,
49
106
  continueOnError: body.continueOnError ?? true,
50
107
  });
51
- return result;
108
+ return toGenerateSpriteResultDto(result);
52
109
  });
53
110
  fastify.get("/list/:projectId", async (req) => {
54
111
  const { projectId } = req.params;
55
- const query = req.query;
56
- const local = String(query['local'] ?? '').toLowerCase() === 'true';
57
- return await fastify.core.sprite.getSprites(projectId, local);
112
+ const local = String(req.query?.local ?? "").toLowerCase() === "true";
113
+ const snapshot = await fastify.core.sprite.getSprites(projectId, local);
114
+ return toSpriteSnapshotDto(snapshot);
58
115
  });
59
116
  }
@@ -4,51 +4,85 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = svnRoutes;
7
- const errors_1 = require("@yinuo-ngm/errors");
8
7
  const node_path_1 = __importDefault(require("node:path"));
9
8
  const env_1 = require("../env");
9
+ const errors_1 = require("@yinuo-ngm/errors");
10
+ function toSvnSyncResultDto(result) {
11
+ return {
12
+ ok: result.ok,
13
+ projectId: result.projectId,
14
+ sourceId: result.sourceId,
15
+ mode: result.mode,
16
+ updatedAt: result.updatedAt,
17
+ desiredUrl: result.desiredUrl,
18
+ currentUrl: result.currentUrl,
19
+ stdout: result.stdout,
20
+ stderr: result.stderr,
21
+ };
22
+ }
23
+ function toSvnRuntimeDto(runtime) {
24
+ return {
25
+ projectId: runtime.projectId,
26
+ sourceId: runtime.sourceId,
27
+ lastSyncAt: runtime.lastSyncAt,
28
+ lastSyncMode: runtime.lastSyncMode,
29
+ desiredUrl: runtime.desiredUrl,
30
+ currentUrl: runtime.currentUrl,
31
+ lastStdout: runtime.lastStdout,
32
+ lastStderr: runtime.lastStderr,
33
+ };
34
+ }
35
+ function resolveSources(assets, body) {
36
+ const includeIcons = !body?.types?.length || body.types.includes("icons");
37
+ const includeImages = !body?.types?.length || body.types.includes("images");
38
+ const list = [];
39
+ if (includeIcons && assets.iconsSvn?.kind === "svn")
40
+ list.push(assets.iconsSvn);
41
+ if (includeImages && assets.cutImageSvn?.kind === "svn")
42
+ list.push(assets.cutImageSvn);
43
+ return list;
44
+ }
10
45
  async function svnRoutes(fastify) {
46
+ const svnSync = fastify.core.svnSync;
11
47
  fastify.post("/sync/:projectId", async (req) => {
12
48
  const { projectId } = req.params;
13
49
  const p = await fastify.core.project.get(projectId);
14
50
  const assets = p.assets;
15
51
  if (!assets) {
16
- throw new errors_1.CoreError(errors_1.CoreErrorCodes.ASSET_NOT_FOUND, 'Project assets are required for SVN sync');
17
- ;
52
+ throw new errors_1.CoreError(errors_1.CoreErrorCodes.ASSET_NOT_FOUND, "Project assets are required for SVN sync");
18
53
  }
19
54
  const { iconsSvn, cutImageSvn } = assets;
20
- const svnSources = [iconsSvn, cutImageSvn].filter(s => s && s.kind === "svn");
55
+ const svnSources = resolveSources({ iconsSvn, cutImageSvn }, req.body);
21
56
  const results = [];
22
57
  for (const s of svnSources) {
23
58
  let localDir = s.localDir;
24
59
  if (!localDir) {
25
- localDir = node_path_1.default.join(env_1.env.dataDir, 'svn', projectId, s.label || s.id);
60
+ localDir = node_path_1.default.join(env_1.env.dataDir, "svn", projectId, s.label || s.id);
26
61
  }
27
- const r = await fastify.core.svnSync.sync(projectId, s.id, localDir, s.url);
28
- results.push(r);
62
+ const r = await svnSync.sync(projectId, s.id, localDir, s.url);
63
+ results.push(toSvnSyncResultDto(r));
29
64
  }
30
65
  return results;
31
66
  });
32
67
  fastify.get("/runtime/:projectId", async (req) => {
33
68
  const { projectId } = req.params;
34
- const runtimes = await fastify.core.svnSync.getRuntimeByProjectId(projectId);
35
- return runtimes;
69
+ const runtimes = await svnSync.getRuntimeByProjectId(projectId);
70
+ return runtimes.map(toSvnRuntimeDto);
36
71
  });
37
72
  fastify.post("/sync/stream/:projectId", async (req) => {
38
73
  const { projectId } = req.params;
39
74
  const assets = (await fastify.core.project.get(projectId)).assets;
40
75
  if (!assets) {
41
- throw new errors_1.CoreError(errors_1.CoreErrorCodes.ASSET_NOT_FOUND, 'Project assets are required for SVN sync');
42
- ;
76
+ throw new errors_1.CoreError(errors_1.CoreErrorCodes.ASSET_NOT_FOUND, "Project assets are required for SVN sync");
43
77
  }
44
78
  const { iconsSvn, cutImageSvn } = assets;
45
- const svnSources = [iconsSvn, cutImageSvn].filter(s => s && s.kind === "svn");
79
+ const svnSources = resolveSources({ iconsSvn, cutImageSvn }, req.body);
46
80
  for (const s of svnSources) {
47
81
  let localDir = s.localDir;
48
82
  if (!localDir) {
49
- localDir = node_path_1.default.join(env_1.env.dataDir, 'svn', projectId, s.label || s.id);
83
+ localDir = node_path_1.default.join(env_1.env.dataDir, "svn", projectId, s.label || s.id);
50
84
  }
51
- await fastify.core.svnSync.syncWithStream(projectId, s.id, localDir, s.url);
85
+ await svnSync.syncWithStream(projectId, s.id, localDir, s.url);
52
86
  }
53
87
  return { message: "SVN sync started" };
54
88
  });
@@ -2,6 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = taskRoutes;
4
4
  const errors_1 = require("@yinuo-ngm/errors");
5
+ function toTaskDefinitionDto(spec) {
6
+ return {
7
+ id: spec.id,
8
+ projectId: spec.projectId,
9
+ projectRoot: spec.projectRoot,
10
+ projectName: spec.projectName,
11
+ name: spec.name,
12
+ kind: spec.kind,
13
+ description: spec.description,
14
+ command: spec.command,
15
+ displayCommand: spec.displayCommand,
16
+ file: spec.file,
17
+ args: spec.args,
18
+ runnable: spec.runnable,
19
+ views: spec.views,
20
+ capabilities: spec.capabilities,
21
+ };
22
+ }
23
+ function toTaskRuntimeDto(runtime) {
24
+ return {
25
+ taskId: runtime.taskId,
26
+ projectId: runtime.projectId,
27
+ name: runtime.name,
28
+ runId: runtime.runId,
29
+ status: runtime.status,
30
+ pid: runtime.pid,
31
+ startedAt: runtime.startedAt,
32
+ stoppedAt: runtime.stoppedAt,
33
+ exitCode: runtime.exitCode,
34
+ signal: runtime.signal,
35
+ lastError: runtime.lastError,
36
+ urls: runtime.urls,
37
+ lastOutputAt: runtime.lastOutputAt,
38
+ readyAt: runtime.readyAt,
39
+ rebuildDurationMs: runtime.rebuildDurationMs,
40
+ warningsCount: runtime.warningsCount,
41
+ errorsCount: runtime.errorsCount,
42
+ };
43
+ }
44
+ function toTaskRowDto(row) {
45
+ return {
46
+ spec: toTaskDefinitionDto(row.spec),
47
+ runtime: row.runtime ? toTaskRuntimeDto(row.runtime) : undefined,
48
+ };
49
+ }
50
+ function limitFromQuery(query) {
51
+ const limit = Number(query?.limit);
52
+ return Math.min(Math.max(Number.isFinite(limit) ? limit : 20, 1), 100);
53
+ }
5
54
  async function ensureSpecs(fastify, projectId) {
6
55
  const specs = await fastify.core.task.listSpecsByProject(projectId);
7
56
  if (specs.length === 0) {
@@ -12,39 +61,82 @@ async function taskRoutes(fastify) {
12
61
  fastify.get("/list/:projectId", async (req) => {
13
62
  const { projectId } = req.params;
14
63
  await ensureSpecs(fastify, projectId);
15
- return fastify.core.task.listViewsByProject(projectId);
64
+ const rows = await fastify.core.task.listViewsByProject(projectId);
65
+ return rows.map(toTaskRowDto);
16
66
  });
17
67
  fastify.post("/refresh/:projectId", async (req) => {
18
68
  const { projectId } = req.params;
19
- return await fastify.core.task.refreshByProject(projectId);
69
+ const rows = await fastify.core.task.refreshByProject(projectId);
70
+ return rows.map(toTaskRowDto);
20
71
  });
21
72
  fastify.post("/start", async (req) => {
22
73
  const body = req.body;
23
74
  const taskId = body?.taskId?.trim();
24
75
  if (!taskId)
25
76
  throw new errors_1.CoreError(errors_1.CoreErrorCodes.TASK_ID_REQUIRED, "taskId is required", { body });
26
- return await fastify.core.task.start(taskId);
77
+ const runtime = await fastify.core.task.start(taskId);
78
+ return toTaskRuntimeDto(runtime);
27
79
  });
28
80
  fastify.post("/stop", async (req) => {
29
81
  const body = req.body;
30
82
  const taskId = body?.taskId?.trim();
31
83
  if (!taskId)
32
84
  throw new errors_1.CoreError(errors_1.CoreErrorCodes.TASK_ID_REQUIRED, "taskId is required", { body });
33
- return await fastify.core.task.stop(taskId);
85
+ const runtime = await fastify.core.task.stop(taskId);
86
+ return toTaskRuntimeDto(runtime);
34
87
  });
35
88
  fastify.post("/restart", async (req) => {
36
89
  const body = req.body;
37
90
  const taskId = body?.taskId?.trim();
38
91
  if (!taskId)
39
92
  throw new errors_1.CoreError(errors_1.CoreErrorCodes.TASK_ID_REQUIRED, "taskId is required", { body });
40
- return await fastify.core.task.restart(taskId);
93
+ const runtime = await fastify.core.task.restart(taskId);
94
+ return toTaskRuntimeDto(runtime);
41
95
  });
42
96
  fastify.get("/status/:taskId", async (req) => {
43
97
  const { taskId } = req.params;
44
- return await fastify.core.task.status(taskId);
98
+ const runtime = await fastify.core.task.status(taskId);
99
+ return toTaskRuntimeDto(runtime);
45
100
  });
46
101
  fastify.get("/active", async () => {
47
- return await fastify.core.task.listActive();
102
+ const runtimes = await fastify.core.task.listActive();
103
+ return runtimes.map(toTaskRuntimeDto);
104
+ });
105
+ fastify.get("/report/run/:runId", async (req) => {
106
+ const { runId } = req.params;
107
+ return await fastify.core.task.getReportByRunId(runId);
108
+ });
109
+ fastify.get("/report/latest/:taskId", async (req) => {
110
+ const { taskId } = req.params;
111
+ return await fastify.core.task.getLatestReportByTaskId(taskId);
112
+ });
113
+ fastify.get("/report/history/task/:taskId", async (req) => {
114
+ const { taskId } = req.params;
115
+ return await fastify.core.task.listReportsByTaskId(taskId, limitFromQuery(req.query));
116
+ });
117
+ fastify.get("/report/history/project/:projectId", async (req) => {
118
+ const { projectId } = req.params;
119
+ return await fastify.core.task.listReportsByProjectId(projectId, limitFromQuery(req.query));
120
+ });
121
+ fastify.get("/report/summary/task/:taskId", async (req) => {
122
+ const { taskId } = req.params;
123
+ return await fastify.core.task.listReportSummariesByTaskId(taskId, limitFromQuery(req.query));
124
+ });
125
+ fastify.get("/report/summary/project/:projectId", async (req) => {
126
+ const { projectId } = req.params;
127
+ return await fastify.core.task.listReportSummariesByProjectId(projectId, limitFromQuery(req.query));
128
+ });
129
+ fastify.get("/diagnostics/run/:runId", async (req) => {
130
+ const { runId } = req.params;
131
+ return await fastify.core.task.getDiagnosticsByRunId(runId);
132
+ });
133
+ fastify.get("/diagnostics/latest/:taskId", async (req) => {
134
+ const { taskId } = req.params;
135
+ return await fastify.core.task.getLatestDiagnosticsByTaskId(taskId);
136
+ });
137
+ fastify.get("/dashboard/:taskId", async (req) => {
138
+ const { taskId } = req.params;
139
+ return await fastify.core.task.getDashboardByTaskId(taskId);
48
140
  });
49
141
  fastify.get("/log/run/:runId", async (req) => {
50
142
  const { runId } = req.params;