@fdm-monster/server 2.0.0-rc1 → 2.0.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.
Files changed (228) hide show
  1. package/.env.template +8 -3
  2. package/.yarn/install-state.gz +0 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +5 -4
  5. package/RELEASE_NOTES.MD +39 -0
  6. package/SECURITY.md +1 -1
  7. package/dist/consoles/download-github-releases.js +3 -3
  8. package/dist/consoles/launch-http-servers.js +4 -4
  9. package/dist/consoles/launch-http-servers.js.map +1 -1
  10. package/dist/consoles/mock-bambu.server.js +35 -16
  11. package/dist/consoles/mock-bambu.server.js.map +1 -1
  12. package/dist/consoles/mock-camera/default-image.js +13 -0
  13. package/dist/consoles/mock-camera/default-image.js.map +1 -0
  14. package/dist/consoles/mock-camera/mock-camera.server.js +160 -0
  15. package/dist/consoles/mock-camera/mock-camera.server.js.map +1 -0
  16. package/dist/consoles/mock-octoprint.server.js +281 -73
  17. package/dist/consoles/mock-octoprint.server.js.map +1 -1
  18. package/dist/consoles/mock-prusalink.server.js +11 -11
  19. package/dist/consoles/mock-prusalink.server.js.map +1 -1
  20. package/dist/consoles/typeorm-create.js +135 -0
  21. package/dist/consoles/typeorm-create.js.map +1 -0
  22. package/dist/consoles/typeorm-generate.js +8 -8
  23. package/dist/consoles/typeorm-generate.js.map +1 -1
  24. package/dist/constants/authorization.constants.js +13 -26
  25. package/dist/constants/authorization.constants.js.map +1 -1
  26. package/dist/constants/server-settings.constants.js +3 -18
  27. package/dist/constants/server-settings.constants.js.map +1 -1
  28. package/dist/container.js +18 -10
  29. package/dist/container.js.map +1 -1
  30. package/dist/container.tokens.js +9 -5
  31. package/dist/container.tokens.js.map +1 -1
  32. package/dist/controllers/batch-call.controller.js +0 -15
  33. package/dist/controllers/batch-call.controller.js.map +1 -1
  34. package/dist/controllers/file-storage.controller.js +248 -0
  35. package/dist/controllers/file-storage.controller.js.map +1 -0
  36. package/dist/controllers/first-time-setup.controller.js +2 -1
  37. package/dist/controllers/first-time-setup.controller.js.map +1 -1
  38. package/dist/controllers/floor.controller.js +12 -12
  39. package/dist/controllers/floor.controller.js.map +1 -1
  40. package/dist/controllers/print-job.controller.js +666 -0
  41. package/dist/controllers/print-job.controller.js.map +1 -0
  42. package/dist/controllers/print-queue.controller.js +375 -0
  43. package/dist/controllers/print-queue.controller.js.map +1 -0
  44. package/dist/controllers/printer-files.controller.js +86 -59
  45. package/dist/controllers/printer-files.controller.js.map +1 -1
  46. package/dist/controllers/printer-settings.controller.js +0 -21
  47. package/dist/controllers/printer-settings.controller.js.map +1 -1
  48. package/dist/controllers/{printer-group.controller.js → printer-tag.controller.js} +51 -34
  49. package/dist/controllers/printer-tag.controller.js.map +1 -0
  50. package/dist/controllers/printer.controller.js +15 -0
  51. package/dist/controllers/printer.controller.js.map +1 -1
  52. package/dist/controllers/server-private.controller.js +2 -1
  53. package/dist/controllers/server-private.controller.js.map +1 -1
  54. package/dist/controllers/server-public.controller.js +6 -2
  55. package/dist/controllers/server-public.controller.js.map +1 -1
  56. package/dist/controllers/settings.controller.js +0 -68
  57. package/dist/controllers/settings.controller.js.map +1 -1
  58. package/dist/controllers/slicer-compat.controller.js +216 -0
  59. package/dist/controllers/slicer-compat.controller.js.map +1 -0
  60. package/dist/data-source.js +20 -8
  61. package/dist/data-source.js.map +1 -1
  62. package/dist/entities/camera-stream.entity.js +2 -1
  63. package/dist/entities/camera-stream.entity.js.map +1 -1
  64. package/dist/entities/floor.entity.js +3 -5
  65. package/dist/entities/floor.entity.js.map +1 -1
  66. package/dist/entities/index.js +15 -7
  67. package/dist/entities/index.js.map +1 -1
  68. package/dist/entities/print-job.entity.js +195 -0
  69. package/dist/entities/print-job.entity.js.map +1 -0
  70. package/dist/entities/{printer-group.entity.js → printer-tag.entity.js} +17 -17
  71. package/dist/entities/printer-tag.entity.js.map +1 -0
  72. package/dist/entities/printer.entity.js +4 -10
  73. package/dist/entities/printer.entity.js.map +1 -1
  74. package/dist/entities/settings.entity.js +3 -12
  75. package/dist/entities/settings.entity.js.map +1 -1
  76. package/dist/entities/{group.entity.js → tag.entity.js} +15 -8
  77. package/dist/entities/tag.entity.js.map +1 -0
  78. package/dist/index.js +8 -2
  79. package/dist/index.js.map +1 -1
  80. package/dist/middleware/exception.filter.js +114 -90
  81. package/dist/middleware/exception.filter.js.map +1 -1
  82. package/dist/middleware/global.middleware.js +6 -6
  83. package/dist/middleware/global.middleware.js.map +1 -1
  84. package/dist/migrations/1767278216516-ChangeCameraPrinterOnDeleteSetNull.js +186 -0
  85. package/dist/migrations/1767278216516-ChangeCameraPrinterOnDeleteSetNull.js.map +1 -0
  86. package/dist/migrations/1767279607392-DropCustomGcode.js +31 -0
  87. package/dist/migrations/1767279607392-DropCustomGcode.js.map +1 -0
  88. package/dist/migrations/1767291804417-DropPrintCompletions.js +37 -0
  89. package/dist/migrations/1767291804417-DropPrintCompletions.js.map +1 -0
  90. package/dist/migrations/1767352862576-DropSettingsFileClean.js +88 -0
  91. package/dist/migrations/1767352862576-DropSettingsFileClean.js.map +1 -0
  92. package/dist/migrations/1767355639023-ChangeFloorLevelToOrder.js +107 -0
  93. package/dist/migrations/1767355639023-ChangeFloorLevelToOrder.js.map +1 -0
  94. package/dist/migrations/1767370191762-ChangeFloorNonUniqueOrder.js +62 -0
  95. package/dist/migrations/1767370191762-ChangeFloorNonUniqueOrder.js.map +1 -0
  96. package/dist/migrations/1767432108916-RenameGroupToTag.js +86 -0
  97. package/dist/migrations/1767432108916-RenameGroupToTag.js.map +1 -0
  98. package/dist/migrations/1767451444137-AddPrintJob.js +207 -0
  99. package/dist/migrations/1767451444137-AddPrintJob.js.map +1 -0
  100. package/dist/server.constants.js +9 -9
  101. package/dist/server.constants.js.map +1 -1
  102. package/dist/server.host.js +24 -32
  103. package/dist/server.host.js.map +1 -1
  104. package/dist/services/bambu/bambu-ftp.adapter.js +1 -1
  105. package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -1
  106. package/dist/services/bambu/bambu-mqtt.adapter.js +73 -76
  107. package/dist/services/bambu/bambu-mqtt.adapter.js.map +1 -1
  108. package/dist/services/core/batch-call.service.js +0 -25
  109. package/dist/services/core/batch-call.service.js.map +1 -1
  110. package/dist/services/core/multer.service.js +5 -9
  111. package/dist/services/core/multer.service.js.map +1 -1
  112. package/dist/services/core/yaml.service.js +208 -153
  113. package/dist/services/core/yaml.service.js.map +1 -1
  114. package/dist/services/file-analysis.service.js +146 -0
  115. package/dist/services/file-analysis.service.js.map +1 -0
  116. package/dist/services/file-storage.service.js +386 -0
  117. package/dist/services/file-storage.service.js.map +1 -0
  118. package/dist/services/interfaces/floor.dto.js +3 -3
  119. package/dist/services/interfaces/floor.dto.js.map +1 -1
  120. package/dist/services/interfaces/{printer-group.dto.js → printer-tag.dto.js} +9 -8
  121. package/dist/services/interfaces/printer-tag.dto.js.map +1 -0
  122. package/dist/services/interfaces/{print-completion.interface.js → printer-tag.service.interface.js} +1 -1
  123. package/dist/services/interfaces/{printer-group.service.interface.js.map → printer-tag.service.interface.js.map} +1 -1
  124. package/dist/services/interfaces/settings.dto.js +0 -1
  125. package/dist/services/interfaces/settings.dto.js.map +1 -1
  126. package/dist/services/interfaces/{group.dto.js → tag.dto.js} +1 -1
  127. package/dist/services/interfaces/tag.dto.js.map +1 -0
  128. package/dist/services/octoprint/dto/files/gcode-analysis.dto.js.map +1 -0
  129. package/dist/services/octoprint/octoprint-api.routes.js +0 -7
  130. package/dist/services/octoprint/octoprint-api.routes.js.map +1 -1
  131. package/dist/services/octoprint/octoprint.client.js +0 -4
  132. package/dist/services/octoprint/octoprint.client.js.map +1 -1
  133. package/dist/services/orm/floor.service.js +9 -16
  134. package/dist/services/orm/floor.service.js.map +1 -1
  135. package/dist/services/orm/print-job.service.js +539 -0
  136. package/dist/services/orm/print-job.service.js.map +1 -0
  137. package/dist/services/orm/printer-tag.service.js +120 -0
  138. package/dist/services/orm/printer-tag.service.js.map +1 -0
  139. package/dist/services/orm/settings.service.js +0 -8
  140. package/dist/services/orm/settings.service.js.map +1 -1
  141. package/dist/services/print-file-downloader.service.js +169 -0
  142. package/dist/services/print-file-downloader.service.js.map +1 -0
  143. package/dist/services/print-queue.service.js +268 -0
  144. package/dist/services/print-queue.service.js.map +1 -0
  145. package/dist/services/prusa-link/prusa-link-http-polling.adapter.js +1 -3
  146. package/dist/services/prusa-link/prusa-link-http-polling.adapter.js.map +1 -1
  147. package/dist/services/validators/floor-service.validation.js +10 -10
  148. package/dist/services/validators/floor-service.validation.js.map +1 -1
  149. package/dist/services/validators/print-job.validation.js +31 -0
  150. package/dist/services/validators/print-job.validation.js.map +1 -0
  151. package/dist/services/validators/settings-service.validation.js +0 -22
  152. package/dist/services/validators/settings-service.validation.js.map +1 -1
  153. package/dist/services/validators/yaml-service.validation.js +7 -13
  154. package/dist/services/validators/yaml-service.validation.js.map +1 -1
  155. package/dist/shared/load-controllers.js +2 -1
  156. package/dist/shared/load-controllers.js.map +1 -1
  157. package/dist/shared/runtime-settings.migration.js +1 -11
  158. package/dist/shared/runtime-settings.migration.js.map +1 -1
  159. package/dist/state/floor.store.js +2 -9
  160. package/dist/state/floor.store.js.map +1 -1
  161. package/dist/state/printer-events.cache.js +179 -19
  162. package/dist/state/printer-events.cache.js.map +1 -1
  163. package/dist/state/printer-thumbnail.cache.js +98 -183
  164. package/dist/state/printer-thumbnail.cache.js.map +1 -1
  165. package/dist/state/settings.store.js +2 -33
  166. package/dist/state/settings.store.js.map +1 -1
  167. package/dist/state/socket-io.gateway.js +1 -1
  168. package/dist/state/socket-io.gateway.js.map +1 -1
  169. package/dist/tasks/boot.task.js +7 -5
  170. package/dist/tasks/boot.task.js.map +1 -1
  171. package/dist/tasks/print-job-analysis.task.js +116 -0
  172. package/dist/tasks/print-job-analysis.task.js.map +1 -0
  173. package/dist/tasks/printer-files-load.task.js +29 -0
  174. package/dist/tasks/printer-files-load.task.js.map +1 -0
  175. package/dist/tasks/socketio.task.js +1 -1
  176. package/dist/tasks/socketio.task.js.map +1 -1
  177. package/dist/tasks.js +3 -2
  178. package/dist/tasks.js.map +1 -1
  179. package/dist/utils/parsers/3mf.parser.js +337 -0
  180. package/dist/utils/parsers/3mf.parser.js.map +1 -0
  181. package/dist/utils/parsers/bgcode.parser.js +223 -0
  182. package/dist/utils/parsers/bgcode.parser.js.map +1 -0
  183. package/dist/utils/parsers/gcode.parser.js +254 -0
  184. package/dist/utils/parsers/gcode.parser.js.map +1 -0
  185. package/dist/utils/swagger/decorators.js +39 -0
  186. package/dist/utils/swagger/decorators.js.map +1 -0
  187. package/dist/utils/swagger/generator.js +196 -0
  188. package/dist/utils/swagger/generator.js.map +1 -0
  189. package/dist/utils/swagger/swagger.js +93 -0
  190. package/dist/utils/swagger/swagger.js.map +1 -0
  191. package/package.json +19 -15
  192. package/dist/controllers/custom-gcode.controller.js +0 -147
  193. package/dist/controllers/custom-gcode.controller.js.map +0 -1
  194. package/dist/controllers/print-completion.controller.js +0 -118
  195. package/dist/controllers/print-completion.controller.js.map +0 -1
  196. package/dist/controllers/printer-group.controller.js.map +0 -1
  197. package/dist/entities/custom-gcode.entity.js +0 -49
  198. package/dist/entities/custom-gcode.entity.js.map +0 -1
  199. package/dist/entities/group.entity.js.map +0 -1
  200. package/dist/entities/print-completion.entity.js +0 -90
  201. package/dist/entities/print-completion.entity.js.map +0 -1
  202. package/dist/entities/printer-group.entity.js.map +0 -1
  203. package/dist/services/interfaces/custom-gcode.dto.js +0 -18
  204. package/dist/services/interfaces/custom-gcode.dto.js.map +0 -1
  205. package/dist/services/interfaces/custom-gcode.service.interface.js +0 -6
  206. package/dist/services/interfaces/custom-gcode.service.interface.js.map +0 -1
  207. package/dist/services/interfaces/gcode-analysis.dto.js.map +0 -1
  208. package/dist/services/interfaces/group.dto.js.map +0 -1
  209. package/dist/services/interfaces/print-completion-context.dto.js +0 -6
  210. package/dist/services/interfaces/print-completion-context.dto.js.map +0 -1
  211. package/dist/services/interfaces/print-completion.dto.js +0 -38
  212. package/dist/services/interfaces/print-completion.dto.js.map +0 -1
  213. package/dist/services/interfaces/print-completion.interface.js.map +0 -1
  214. package/dist/services/interfaces/printer-group.dto.js.map +0 -1
  215. package/dist/services/interfaces/printer-group.service.interface.js +0 -6
  216. package/dist/services/orm/custom-gcode.service.js +0 -42
  217. package/dist/services/orm/custom-gcode.service.js.map +0 -1
  218. package/dist/services/orm/print-completion.service.js +0 -87
  219. package/dist/services/orm/print-completion.service.js.map +0 -1
  220. package/dist/services/orm/print-completion.shared.js +0 -59
  221. package/dist/services/orm/print-completion.shared.js.map +0 -1
  222. package/dist/services/orm/printer-group.service.js +0 -109
  223. package/dist/services/orm/printer-group.service.js.map +0 -1
  224. package/dist/tasks/print-completion.socketio.task.js +0 -91
  225. package/dist/tasks/print-completion.socketio.task.js.map +0 -1
  226. package/dist/tasks/printer-file-clean.task.js +0 -74
  227. package/dist/tasks/printer-file-clean.task.js.map +0 -1
  228. /package/dist/services/{interfaces → octoprint/dto/files}/gcode-analysis.dto.js +0 -0
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "PrintJobAnalysisTask", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return PrintJobAnalysisTask;
9
+ }
10
+ });
11
+ const _printjobentity = require("../entities/print-job.entity");
12
+ class PrintJobAnalysisTask {
13
+ printJobService;
14
+ fileAnalysisService;
15
+ fileStorageService;
16
+ logger;
17
+ printJobRepository;
18
+ constructor(loggerFactory, printJobService, fileAnalysisService, fileStorageService, typeormService){
19
+ this.printJobService = printJobService;
20
+ this.fileAnalysisService = fileAnalysisService;
21
+ this.fileStorageService = fileStorageService;
22
+ this.logger = loggerFactory(PrintJobAnalysisTask.name);
23
+ this.printJobRepository = typeormService.getDataSource().getRepository(_printjobentity.PrintJob);
24
+ }
25
+ async run() {
26
+ try {
27
+ const pendingJobs = await this.printJobRepository.find({
28
+ where: [
29
+ {
30
+ analysisState: "NOT_ANALYZED",
31
+ status: "PENDING"
32
+ },
33
+ {
34
+ analysisState: "ANALYZING"
35
+ }
36
+ ],
37
+ take: 10
38
+ });
39
+ if (pendingJobs.length === 0) {
40
+ this.logger.debug("No pending print jobs to analyze");
41
+ return;
42
+ }
43
+ this.logger.log(`Found ${pendingJobs.length} print job(s) to analyze`);
44
+ for (const job of pendingJobs){
45
+ try {
46
+ await this.analyzeJob(job);
47
+ } catch (error) {
48
+ this.logger.error(`Failed to analyze job ${job.id}: ${job.fileName}`, error);
49
+ job.analysisState = "FAILED";
50
+ job.statusReason = `Analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`;
51
+ await this.printJobRepository.save(job);
52
+ }
53
+ }
54
+ this.logger.log(`Completed analysis of ${pendingJobs.length} print job(s)`);
55
+ } catch (error) {
56
+ this.logger.error("Failed to run print job analysis task", error);
57
+ }
58
+ }
59
+ async analyzeJob(job) {
60
+ this.logger.log(`Analyzing print job ${job.id}: ${job.fileName}`);
61
+ job.analysisState = "ANALYZING";
62
+ await this.printJobRepository.save(job);
63
+ if (!job.fileStorageId) {
64
+ throw new Error("Job has no fileStorageId - cannot analyze");
65
+ }
66
+ const cachedMetadata = await this.fileStorageService.loadMetadata(job.fileStorageId);
67
+ let metadata;
68
+ let thumbnails = [];
69
+ if (cachedMetadata) {
70
+ this.logger.log(`Using cached metadata for job ${job.id} (storageId: ${job.fileStorageId})`);
71
+ metadata = cachedMetadata;
72
+ thumbnails = [];
73
+ } else {
74
+ const filePath = await this.resolveFilePath(job);
75
+ if (!filePath) {
76
+ throw new Error("File path could not be resolved");
77
+ }
78
+ const exists = await this.fileAnalysisService.needsAnalysis(filePath);
79
+ if (!exists) {
80
+ throw new Error(`File not found: ${filePath}`);
81
+ }
82
+ const analysisResult = await this.fileAnalysisService.analyzeFile(filePath);
83
+ metadata = analysisResult.metadata;
84
+ thumbnails = analysisResult.thumbnails;
85
+ let thumbnailMetadata = [];
86
+ if (thumbnails && thumbnails.length > 0) {
87
+ thumbnailMetadata = await this.fileStorageService.saveThumbnails(job.fileStorageId, thumbnails);
88
+ this.logger.log(`Saved ${thumbnailMetadata.length} thumbnail(s) for job ${job.id}`);
89
+ }
90
+ const fileHash = job.fileHash || undefined;
91
+ await this.fileStorageService.saveMetadata(job.fileStorageId, metadata, fileHash, job.fileName, thumbnailMetadata);
92
+ this.logger.log(`Cached metadata JSON for job ${job.id}`);
93
+ }
94
+ await this.printJobService.handleFileAnalyzed(job.id, metadata, thumbnails);
95
+ this.logger.log(`Successfully analyzed job ${job.id}: ${job.fileName}`);
96
+ }
97
+ async resolveFilePath(job) {
98
+ if (job.fileStorageId) {
99
+ try {
100
+ const exists = await this.fileStorageService.fileExists(job.fileStorageId);
101
+ if (!exists) {
102
+ this.logger.warn(`File ${job.fileStorageId} not found in storage for job ${job.id}`);
103
+ return null;
104
+ }
105
+ return this.fileStorageService.getFilePath(job.fileStorageId);
106
+ } catch (error) {
107
+ this.logger.error(`Failed to resolve file path for job ${job.id}: ${error}`);
108
+ return null;
109
+ }
110
+ }
111
+ this.logger.debug(`Job ${job.id} has no fileStorageId - cannot analyze remotely stored file`);
112
+ return null;
113
+ }
114
+ }
115
+
116
+ //# sourceMappingURL=print-job-analysis.task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tasks/print-job-analysis.task.ts"],"names":["PrintJobAnalysisTask","logger","printJobRepository","loggerFactory","printJobService","fileAnalysisService","fileStorageService","typeormService","name","getDataSource","getRepository","PrintJob","run","pendingJobs","find","where","analysisState","status","take","length","debug","log","job","analyzeJob","error","id","fileName","statusReason","Error","message","save","fileStorageId","cachedMetadata","loadMetadata","metadata","thumbnails","filePath","resolveFilePath","exists","needsAnalysis","analysisResult","analyzeFile","thumbnailMetadata","saveThumbnails","fileHash","undefined","saveMetadata","handleFileAnalyzed","fileExists","warn","getFilePath"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "PrinterFilesLoadTask", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return PrinterFilesLoadTask;
9
+ }
10
+ });
11
+ class PrinterFilesLoadTask {
12
+ printerFilesStore;
13
+ logger;
14
+ constructor(loggerFactory, printerFilesStore){
15
+ this.printerFilesStore = printerFilesStore;
16
+ this.logger = loggerFactory(PrinterFilesLoadTask.name);
17
+ }
18
+ async run() {
19
+ this.logger.log("Loading files store in background");
20
+ try {
21
+ await this.printerFilesStore.loadFilesStore();
22
+ this.logger.log("Files store loaded successfully in background");
23
+ } catch (error) {
24
+ this.logger.error("Failed to load files store in background", error);
25
+ }
26
+ }
27
+ }
28
+
29
+ //# sourceMappingURL=printer-files-load.task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tasks/printer-files-load.task.ts"],"names":["PrinterFilesLoadTask","logger","loggerFactory","printerFilesStore","name","run","log","loadFilesStore","error"],"mappings":";;;;+BAQaA;;;eAAAA;;;AAAN,MAAMA;;IACXC,OAAsB;IAEtB,YACEC,aAA6B,EAC7B,AAAiBC,iBAAoC,CACrD;aADiBA,oBAAAA;QAEjB,IAAI,CAACF,MAAM,GAAGC,cAAcF,qBAAqBI,IAAI;IACvD;IAEA,MAAMC,MAAM;QACV,IAAI,CAACJ,MAAM,CAACK,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACH,iBAAiB,CAACI,cAAc;YAC3C,IAAI,CAACN,MAAM,CAACK,GAAG,CAAC;QAClB,EAAE,OAAOE,OAAO;YACd,IAAI,CAACP,MAAM,CAACO,KAAK,CAAC,4CAA4CA;QAChE;IACF;AACF"}
@@ -48,7 +48,7 @@ class SocketIoTask {
48
48
  printerEvents,
49
49
  trackedUploads
50
50
  };
51
- this.socketIoGateway.send(_socketiogateway.IO_MESSAGES.LegacyUpdate, socketIoData);
51
+ this.socketIoGateway.send(_socketiogateway.IO_MESSAGES.Update, socketIoData);
52
52
  }
53
53
  }
54
54
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tasks/socketio.task.ts"],"names":["SocketIoTask","logger","loggerFactory","socketIoGateway","floorStore","printerSocketStore","printerEventsCache","printerCache","fileUploadTrackerCache","eventEmitter2","name","on","socketIoConnectedEvent","sendUpdate","run","floors","listCache","printers","listCachedPrinters","socketStates","getSocketStatesById","printerEvents","getAllKeyValues","trackedUploads","getUploads","socketIoData","send","IO_MESSAGES","LegacyUpdate"],"mappings":";;;;+BAWaA;;;eAAAA;;;iCAXgC;gCACN;AAUhC,MAAMA;;;;;;;;IACXC,OAAsB;IAEtB,YACEC,aAA6B,EAC7B,AAAiBC,eAAgC,EACjD,AAAiBC,UAAsB,EACvC,AAAiBC,kBAAsC,EACvD,AAAiBC,kBAAsC,EACvD,AAAiBC,YAA0B,EAC3C,AAAiBC,sBAA8C,EAC/D,AAAiBC,aAA4B,CAC7C;aAPiBN,kBAAAA;aACAC,aAAAA;aACAC,qBAAAA;aACAC,qBAAAA;aACAC,eAAAA;aACAC,yBAAAA;aACAC,gBAAAA;QAEjB,IAAI,CAACR,MAAM,GAAGC,cAAcF,aAAaU,IAAI;QAE7C,IAAI,CAACD,aAAa,CAACE,EAAE,CAACC,sCAAsB,EAAE;YAC5C,MAAM,IAAI,CAACC,UAAU;QACvB;IACF;IAEA,MAAMC,MAAM;QACV,MAAM,IAAI,CAACD,UAAU;IACvB;IAEA,MAAMA,aAAa;QACjB,MAAME,SAAS,MAAM,IAAI,CAACX,UAAU,CAACY,SAAS;QAC9C,MAAMC,WAAW,MAAM,IAAI,CAACV,YAAY,CAACW,kBAAkB,CAAC;QAC5D,MAAMC,eAAe,IAAI,CAACd,kBAAkB,CAACe,mBAAmB;QAChE,MAAMC,gBAAgB,MAAM,IAAI,CAACf,kBAAkB,CAACgB,eAAe;QACnE,MAAMC,iBAAiB,IAAI,CAACf,sBAAsB,CAACgB,UAAU;QAE7D,MAAMC,eAAe;YACnBR;YACAF;YACAI;YACAE;YACAE;QACF;QAEA,IAAI,CAACpB,eAAe,CAACuB,IAAI,CAACC,4BAAW,CAACC,YAAY,EAAEH;IACtD;AACF"}
1
+ {"version":3,"sources":["../../src/tasks/socketio.task.ts"],"names":["SocketIoTask","logger","loggerFactory","socketIoGateway","floorStore","printerSocketStore","printerEventsCache","printerCache","fileUploadTrackerCache","eventEmitter2","name","on","socketIoConnectedEvent","sendUpdate","run","floors","listCache","printers","listCachedPrinters","socketStates","getSocketStatesById","printerEvents","getAllKeyValues","trackedUploads","getUploads","socketIoData","send","IO_MESSAGES","Update"],"mappings":";;;;+BAWaA;;;eAAAA;;;iCAXgC;gCACN;AAUhC,MAAMA;;;;;;;;IACXC,OAAsB;IAEtB,YACEC,aAA6B,EAC7B,AAAiBC,eAAgC,EACjD,AAAiBC,UAAsB,EACvC,AAAiBC,kBAAsC,EACvD,AAAiBC,kBAAsC,EACvD,AAAiBC,YAA0B,EAC3C,AAAiBC,sBAA8C,EAC/D,AAAiBC,aAA4B,CAC7C;aAPiBN,kBAAAA;aACAC,aAAAA;aACAC,qBAAAA;aACAC,qBAAAA;aACAC,eAAAA;aACAC,yBAAAA;aACAC,gBAAAA;QAEjB,IAAI,CAACR,MAAM,GAAGC,cAAcF,aAAaU,IAAI;QAE7C,IAAI,CAACD,aAAa,CAACE,EAAE,CAACC,sCAAsB,EAAE;YAC5C,MAAM,IAAI,CAACC,UAAU;QACvB;IACF;IAEA,MAAMC,MAAM;QACV,MAAM,IAAI,CAACD,UAAU;IACvB;IAEA,MAAMA,aAAa;QACjB,MAAME,SAAS,MAAM,IAAI,CAACX,UAAU,CAACY,SAAS;QAC9C,MAAMC,WAAW,MAAM,IAAI,CAACV,YAAY,CAACW,kBAAkB,CAAC;QAC5D,MAAMC,eAAe,IAAI,CAACd,kBAAkB,CAACe,mBAAmB;QAChE,MAAMC,gBAAgB,MAAM,IAAI,CAACf,kBAAkB,CAACgB,eAAe;QACnE,MAAMC,iBAAiB,IAAI,CAACf,sBAAsB,CAACgB,UAAU;QAE7D,MAAMC,eAAe;YACnBR;YACAF;YACAI;YACAE;YACAE;QACF;QAEA,IAAI,CAACpB,eAAe,CAACuB,IAAI,CAACC,4BAAW,CAACC,MAAM,EAAEH;IAChD;AACF"}
package/dist/tasks.js CHANGED
@@ -36,9 +36,10 @@ class ServerTasks {
36
36
  registerTask(_containertokens.DITokens.softwareUpdateTask, _taskpresets.TASK_PRESETS.RUNDELAYED, 1500),
37
37
  registerTask(_containertokens.DITokens.clientDistDownloadTask, _taskpresets.TASK_PRESETS.RUNONCE),
38
38
  registerTask(_containertokens.DITokens.socketIoTask, _taskpresets.TASK_PRESETS.PERIODIC, 500),
39
- registerTask(_containertokens.DITokens.printerFileCleanTask, _taskpresets.TASK_PRESETS.RUNONCE, 60 * 1000, true),
40
39
  registerTask(_containertokens.DITokens.printerWebsocketTask, _taskpresets.TASK_PRESETS.PERIODIC, 2000, true),
41
- registerTask(_containertokens.DITokens.printerWebsocketRestoreTask, _taskpresets.TASK_PRESETS.PERIODIC, 15 * 1000, false)
40
+ registerTask(_containertokens.DITokens.printerWebsocketRestoreTask, _taskpresets.TASK_PRESETS.PERIODIC, 15 * 1000, false),
41
+ registerTask(_containertokens.DITokens.printerFilesLoadTask, _taskpresets.TASK_PRESETS.RUNDELAYED, 1000),
42
+ registerTask(_containertokens.DITokens.printJobAnalysisTask, _taskpresets.TASK_PRESETS.PERIODIC, 30 * 1000, false)
42
43
  ];
43
44
  }
44
45
 
package/dist/tasks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tasks.ts"],"names":["ServerTasks","registerTask","task","preset","milliseconds","runImmediately","timingPreset","id","name","SERVER_BOOT_TASK","DITokens","bootTask","TaskPresets","PERIODIC_DISABLED","BOOT_TASKS","softwareUpdateTask","RUNDELAYED","clientDistDownloadTask","RUNONCE","socketIoTask","PERIODIC","printerFileCleanTask","printerWebsocketTask","printerWebsocketRestoreTask"],"mappings":";;;;;;;;;;;QAkBaA;eAAAA;;QAXGC;eAAAA;;;6BAP4B;iCACnB;AAMlB,SAASA,aAAaC,IAAS,EAAEC,MAAoB,EAAEC,eAAe,CAAC,EAAEC,iBAAiB,KAAK;IACpG,IAAIC,eAAe;QAAE,GAAGH,MAAM;IAAC;IAC/BG,aAAaF,YAAY,GAAGD,OAAOC,YAAY,IAAIA;IACnDE,aAAaD,cAAc,GAAGA,kBAAkB;IAChD,OAAO;QACLE,IAAIL,KAAKM,IAAI,IAAIN;QACjBA;QACAC,QAAQG;IACV;AACF;AAEO,MAAMN;IACX,OAAcS,mBAAmBR,aAAaS,yBAAQ,CAACC,QAAQ,EAAEC,yBAAW,CAACC,iBAAiB,EAAE,MAAM,OAAO;IAC7G,OAAcC,aAAa;QACzBb,aAAaS,yBAAQ,CAACK,kBAAkB,EAAEH,yBAAW,CAACI,UAAU,EAAE;QAClEf,aAAaS,yBAAQ,CAACO,sBAAsB,EAAEL,yBAAW,CAACM,OAAO;QACjEjB,aAAaS,yBAAQ,CAACS,YAAY,EAAEP,yBAAW,CAACQ,QAAQ,EAAE;QAC1DnB,aAAaS,yBAAQ,CAACW,oBAAoB,EAAET,yBAAW,CAACM,OAAO,EAAE,KAAK,MAAM;QAE5EjB,aAAaS,yBAAQ,CAACY,oBAAoB,EAAEV,yBAAW,CAACQ,QAAQ,EAAE,MAAM;QAExEnB,aAAaS,yBAAQ,CAACa,2BAA2B,EAAEX,yBAAW,CAACQ,QAAQ,EAAE,KAAK,MAAM;KACrF,CAAC;AACJ"}
1
+ {"version":3,"sources":["../src/tasks.ts"],"names":["ServerTasks","registerTask","task","preset","milliseconds","runImmediately","timingPreset","id","name","SERVER_BOOT_TASK","DITokens","bootTask","TaskPresets","PERIODIC_DISABLED","BOOT_TASKS","softwareUpdateTask","RUNDELAYED","clientDistDownloadTask","RUNONCE","socketIoTask","PERIODIC","printerWebsocketTask","printerWebsocketRestoreTask","printerFilesLoadTask","printJobAnalysisTask"],"mappings":";;;;;;;;;;;QAkBaA;eAAAA;;QAXGC;eAAAA;;;6BAP4B;iCACnB;AAMlB,SAASA,aAAaC,IAAS,EAAEC,MAAoB,EAAEC,eAAe,CAAC,EAAEC,iBAAiB,KAAK;IACpG,IAAIC,eAAe;QAAE,GAAGH,MAAM;IAAC;IAC/BG,aAAaF,YAAY,GAAGD,OAAOC,YAAY,IAAIA;IACnDE,aAAaD,cAAc,GAAGA,kBAAkB;IAChD,OAAO;QACLE,IAAIL,KAAKM,IAAI,IAAIN;QACjBA;QACAC,QAAQG;IACV;AACF;AAEO,MAAMN;IACX,OAAuBS,mBAAmBR,aAAaS,yBAAQ,CAACC,QAAQ,EAAEC,yBAAW,CAACC,iBAAiB,EAAE,MAAM,OAAO;IACtH,OAAuBC,aAAa;QAClCb,aAAaS,yBAAQ,CAACK,kBAAkB,EAAEH,yBAAW,CAACI,UAAU,EAAE;QAClEf,aAAaS,yBAAQ,CAACO,sBAAsB,EAAEL,yBAAW,CAACM,OAAO;QACjEjB,aAAaS,yBAAQ,CAACS,YAAY,EAAEP,yBAAW,CAACQ,QAAQ,EAAE;QAE1DnB,aAAaS,yBAAQ,CAACW,oBAAoB,EAAET,yBAAW,CAACQ,QAAQ,EAAE,MAAM;QAExEnB,aAAaS,yBAAQ,CAACY,2BAA2B,EAAEV,yBAAW,CAACQ,QAAQ,EAAE,KAAK,MAAM;QAEpFnB,aAAaS,yBAAQ,CAACa,oBAAoB,EAAEX,yBAAW,CAACI,UAAU,EAAE;QAEpEf,aAAaS,yBAAQ,CAACc,oBAAoB,EAAEZ,yBAAW,CAACQ,QAAQ,EAAE,KAAK,MAAM;KAC9E,CAAC;AACJ"}
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ThreeMFParser", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ThreeMFParser;
9
+ }
10
+ });
11
+ const _promises = /*#__PURE__*/ _interop_require_wildcard(require("node:fs/promises"));
12
+ const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
13
+ const _admzip = /*#__PURE__*/ _interop_require_default(require("adm-zip"));
14
+ function _interop_require_default(obj) {
15
+ return obj && obj.__esModule ? obj : {
16
+ default: obj
17
+ };
18
+ }
19
+ function _getRequireWildcardCache(nodeInterop) {
20
+ if (typeof WeakMap !== "function") return null;
21
+ var cacheBabelInterop = new WeakMap();
22
+ var cacheNodeInterop = new WeakMap();
23
+ return (_getRequireWildcardCache = function(nodeInterop) {
24
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
25
+ })(nodeInterop);
26
+ }
27
+ function _interop_require_wildcard(obj, nodeInterop) {
28
+ if (!nodeInterop && obj && obj.__esModule) {
29
+ return obj;
30
+ }
31
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
32
+ return {
33
+ default: obj
34
+ };
35
+ }
36
+ var cache = _getRequireWildcardCache(nodeInterop);
37
+ if (cache && cache.has(obj)) {
38
+ return cache.get(obj);
39
+ }
40
+ var newObj = {
41
+ __proto__: null
42
+ };
43
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
44
+ for(var key in obj){
45
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
46
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
47
+ if (desc && (desc.get || desc.set)) {
48
+ Object.defineProperty(newObj, key, desc);
49
+ } else {
50
+ newObj[key] = obj[key];
51
+ }
52
+ }
53
+ }
54
+ newObj.default = obj;
55
+ if (cache) {
56
+ cache.set(obj, newObj);
57
+ }
58
+ return newObj;
59
+ }
60
+ class ThreeMFParser {
61
+ async parse(filePath) {
62
+ const stats = await _promises.stat(filePath);
63
+ const fileName = _nodepath.basename(filePath);
64
+ const zip = new _admzip.default(filePath);
65
+ const zipEntries = zip.getEntries();
66
+ const metadataJsonEntry = zipEntries.find((e)=>e.entryName === "metadata.json");
67
+ let metadata = {};
68
+ if (metadataJsonEntry) {
69
+ const jsonContent = metadataJsonEntry.getData().toString("utf8");
70
+ const jsonData = JSON.parse(jsonContent);
71
+ metadata = this.normalizeJsonMetadata(jsonData);
72
+ } else {
73
+ const modelEntry = zipEntries.find((e)=>e.entryName === "3D/3dmodel.model" || e.entryName === "Metadata/model_settings.config");
74
+ metadata = modelEntry ? this.extractMetadataFromXML(modelEntry.getData().toString("utf8")) : {};
75
+ }
76
+ const plates = this.extractPlates(zipEntries);
77
+ const isMultiPlate = plates.length > 1;
78
+ const thumbnails = this.extractThumbnails(zipEntries);
79
+ let topLevelPrintTime = this.parseTime(metadata.printTime);
80
+ let topLevelFilamentWeight = this.parseFloat(metadata.totalFilamentWeight || metadata.filamentWeight);
81
+ let topLevelLayers = this.parseInt(metadata.layerCount);
82
+ let topLevelFilamentUsedMm = this.parseFloat(metadata.filamentUsed);
83
+ let topLevelFilamentUsedCm3 = this.parseFloat(metadata.filamentVolume);
84
+ let topLevelFilamentDensity = this.parseFloat(metadata.filamentDensity);
85
+ let topLevelMaxZ = this.parseFloat(metadata.maxZ);
86
+ let topLevelSlicerVersion = metadata.slicerVersion || metadata.generator;
87
+ let topLevelNozzleDiameter = this.parseFloat(metadata.nozzleDiameter);
88
+ let topLevelLayerHeight = this.parseFloat(metadata.layerHeight || metadata.layer_height);
89
+ let topLevelFirstLayerHeight = this.parseFloat(metadata.firstLayerHeight || metadata.first_layer_height);
90
+ let topLevelBedTemp = this.parseFloat(metadata.bedTemp || metadata.bed_temperature);
91
+ let topLevelNozzleTemp = this.parseFloat(metadata.nozzleTemp || metadata.nozzle_temperature);
92
+ let topLevelFillDensity = metadata.infillDensity || metadata.infill_density || metadata.fill_density || null;
93
+ let topLevelFilamentType = metadata.filamentType || metadata.filament_type || null;
94
+ let topLevelPrinterModel = metadata.printerModel || metadata.printer_model || null;
95
+ let topLevelFilamentDiameter = this.parseFloat(metadata.filamentDiameter || metadata.filament_diameter) || 1.75;
96
+ if (plates.length >= 1 && plates[0]) {
97
+ if (plates.length === 1) {
98
+ const plate = plates[0];
99
+ topLevelPrintTime = plate.gcodePrintTimeSeconds ?? topLevelPrintTime;
100
+ topLevelFilamentWeight = plate.filamentUsedGrams ?? topLevelFilamentWeight;
101
+ topLevelLayers = plate.totalLayers ?? topLevelLayers;
102
+ topLevelFilamentUsedMm = plate.filamentUsedMm ?? topLevelFilamentUsedMm;
103
+ topLevelFilamentUsedCm3 = plate.filamentUsedCm3 ?? topLevelFilamentUsedCm3;
104
+ topLevelFilamentDensity = plate.filamentDensityGramsCm3 ?? topLevelFilamentDensity;
105
+ topLevelMaxZ = plate.maxLayerZ ?? topLevelMaxZ;
106
+ topLevelSlicerVersion = plate.slicerVersion ?? topLevelSlicerVersion;
107
+ topLevelNozzleDiameter = plate.nozzleDiameterMm ?? topLevelNozzleDiameter;
108
+ topLevelLayerHeight = plate.layerHeight ?? topLevelLayerHeight;
109
+ topLevelFirstLayerHeight = plate.firstLayerHeight ?? topLevelFirstLayerHeight;
110
+ topLevelBedTemp = plate.bedTemperature ?? topLevelBedTemp;
111
+ topLevelNozzleTemp = plate.nozzleTemperature ?? topLevelNozzleTemp;
112
+ topLevelFillDensity = plate.fillDensity ?? topLevelFillDensity;
113
+ topLevelFilamentType = plate.filamentType ?? topLevelFilamentType;
114
+ topLevelPrinterModel = plate.printerModel ?? topLevelPrinterModel;
115
+ topLevelFilamentDiameter = plate.filamentDiameterMm ?? topLevelFilamentDiameter;
116
+ } else {
117
+ topLevelPrintTime = plates.reduce((sum, p)=>sum + (p.gcodePrintTimeSeconds || 0), 0);
118
+ topLevelFilamentWeight = plates.reduce((sum, p)=>sum + (p.filamentUsedGrams || 0), 0);
119
+ topLevelFilamentUsedMm = plates.reduce((sum, p)=>sum + (p.filamentUsedMm || 0), 0);
120
+ topLevelFilamentUsedCm3 = plates.reduce((sum, p)=>sum + (p.filamentUsedCm3 || 0), 0);
121
+ topLevelLayers = Math.max(...plates.map((p)=>p.totalLayers || 0));
122
+ topLevelMaxZ = Math.max(...plates.map((p)=>p.maxLayerZ || 0));
123
+ const firstPlate = plates[0];
124
+ topLevelFilamentDensity = firstPlate.filamentDensityGramsCm3 ?? topLevelFilamentDensity;
125
+ topLevelSlicerVersion = firstPlate.slicerVersion ?? topLevelSlicerVersion;
126
+ topLevelNozzleDiameter = firstPlate.nozzleDiameterMm ?? topLevelNozzleDiameter;
127
+ topLevelLayerHeight = firstPlate.layerHeight ?? topLevelLayerHeight;
128
+ topLevelFirstLayerHeight = firstPlate.firstLayerHeight ?? topLevelFirstLayerHeight;
129
+ topLevelBedTemp = firstPlate.bedTemperature ?? topLevelBedTemp;
130
+ topLevelNozzleTemp = firstPlate.nozzleTemperature ?? topLevelNozzleTemp;
131
+ topLevelFillDensity = firstPlate.fillDensity ?? topLevelFillDensity;
132
+ topLevelFilamentType = firstPlate.filamentType ?? topLevelFilamentType;
133
+ topLevelPrinterModel = firstPlate.printerModel ?? topLevelPrinterModel;
134
+ topLevelFilamentDiameter = firstPlate.filamentDiameterMm ?? topLevelFilamentDiameter;
135
+ }
136
+ }
137
+ const normalized = {
138
+ fileName,
139
+ fileFormat: "3mf",
140
+ fileSize: stats.size,
141
+ isMultiPlate,
142
+ totalPlates: plates.length || 1,
143
+ gcodePrintTimeSeconds: topLevelPrintTime,
144
+ nozzleDiameterMm: topLevelNozzleDiameter,
145
+ filamentDiameterMm: topLevelFilamentDiameter,
146
+ filamentDensityGramsCm3: topLevelFilamentDensity,
147
+ filamentUsedMm: topLevelFilamentUsedMm,
148
+ filamentUsedCm3: topLevelFilamentUsedCm3,
149
+ filamentUsedGrams: topLevelFilamentWeight,
150
+ totalFilamentUsedGrams: topLevelFilamentWeight,
151
+ layerHeight: topLevelLayerHeight,
152
+ firstLayerHeight: topLevelFirstLayerHeight,
153
+ bedTemperature: topLevelBedTemp,
154
+ nozzleTemperature: topLevelNozzleTemp,
155
+ fillDensity: topLevelFillDensity,
156
+ filamentType: topLevelFilamentType,
157
+ printerModel: topLevelPrinterModel,
158
+ slicerVersion: topLevelSlicerVersion,
159
+ maxLayerZ: topLevelMaxZ,
160
+ totalLayers: topLevelLayers,
161
+ plates: plates.length > 0 ? plates : undefined
162
+ };
163
+ return {
164
+ raw: {
165
+ _thumbnails: thumbnails,
166
+ plates: plates.length > 0 ? plates : undefined
167
+ },
168
+ normalized,
169
+ plates: plates.length > 0 ? plates : undefined
170
+ };
171
+ }
172
+ normalizeJsonMetadata(jsonData) {
173
+ const metadata = {};
174
+ if (jsonData.nozzleDiameter !== undefined) metadata.nozzleDiameter = String(jsonData.nozzleDiameter);
175
+ if (jsonData.estimatedPrintTimeSec !== undefined) metadata.printTime = String(jsonData.estimatedPrintTimeSec);
176
+ if (jsonData.filamentDiameter !== undefined) metadata.filamentDiameter = String(jsonData.filamentDiameter);
177
+ if (jsonData.filamentDensity !== undefined) metadata.filamentDensity = String(jsonData.filamentDensity);
178
+ if (jsonData.filamentUsedGrams !== undefined) metadata.filamentWeight = String(jsonData.filamentUsedGrams);
179
+ if (jsonData.layerHeight !== undefined) metadata.layerHeight = String(jsonData.layerHeight);
180
+ if (jsonData.firstLayerHeight !== undefined) metadata.firstLayerHeight = String(jsonData.firstLayerHeight);
181
+ if (jsonData.bedTemp !== undefined) metadata.bedTemp = String(jsonData.bedTemp);
182
+ if (jsonData.nozzleTemp !== undefined) metadata.nozzleTemp = String(jsonData.nozzleTemp);
183
+ if (jsonData.fillDensity !== undefined) metadata.infillDensity = String(jsonData.fillDensity);
184
+ if (jsonData.filamentType !== undefined) metadata.filamentType = jsonData.filamentType;
185
+ if (jsonData.printerModel !== undefined) metadata.printerModel = jsonData.printerModel;
186
+ return metadata;
187
+ }
188
+ extractMetadataFromXML(xml) {
189
+ const metadata = {};
190
+ const patterns = [
191
+ /<printtime>([^<]+)<\/printtime>/i,
192
+ /<layerheight>([^<]+)<\/layerheight>/i,
193
+ /<filamentused>([^<]+)<\/filamentused>/i,
194
+ /<filamenttype>([^<]+)<\/filamenttype>/i,
195
+ /<nozzlediameter>([^<]+)<\/nozzlediameter>/i,
196
+ /<bedtemperature>([^<]+)<\/bedtemperature>/i,
197
+ /<nozzletemperature>([^<]+)<\/nozzletemperature>/i
198
+ ];
199
+ for (const pattern of patterns){
200
+ const match = xml.match(pattern);
201
+ if (match) {
202
+ const key = pattern.source.match(/<([^>]+)>/)?.[1] || "";
203
+ metadata[key] = match[1];
204
+ }
205
+ }
206
+ const generatorMatch = xml.match(/generator="([^"]+)"/);
207
+ if (generatorMatch) {
208
+ metadata.generator = generatorMatch[1];
209
+ metadata.slicerVersion = generatorMatch[1];
210
+ }
211
+ return metadata;
212
+ }
213
+ extractPlates(zipEntries) {
214
+ const plates = [];
215
+ const plateEntries = zipEntries.filter((e)=>e.entryName.match(/Metadata\/plate_\d+\.gcode$/) && !e.entryName.endsWith('.md5'));
216
+ if (plateEntries.length === 0) {
217
+ return [];
218
+ }
219
+ for (const entry of plateEntries){
220
+ const plateMatch = entry.entryName.match(/plate_(\d+)\.gcode/);
221
+ if (!plateMatch) continue;
222
+ const plateNumber = Number.parseInt(plateMatch[1]);
223
+ const gcodeContent = entry.getData().toString("utf8", 0, Math.min(50000, entry.getData().length));
224
+ const metadata = this.parseGCodeHeader(gcodeContent);
225
+ const plateThumbs = zipEntries.filter((e)=>e.entryName.includes(`plate_${plateMatch[1]}`) && (e.entryName.endsWith(".png") || e.entryName.endsWith(".jpg")));
226
+ const printTime = this.parseTime(metadata.model_printing_time || metadata.total_estimated_time || metadata.print_time);
227
+ const filamentWeight = this.parseFloat(metadata.total_filament_weight_g || metadata.filament_weight || metadata.total_filament_weight);
228
+ const layerCount = this.parseInt(metadata.total_layer_number || metadata.layer_count || metadata.total_layers);
229
+ const plateMetadata = {
230
+ plateNumber,
231
+ gcodePrintTimeSeconds: printTime,
232
+ filamentUsedGrams: filamentWeight,
233
+ totalLayers: layerCount,
234
+ filamentUsedMm: this.parseFloat(metadata.total_filament_length_mm || metadata.filament_length_mm || metadata.filament_used_mm),
235
+ filamentUsedCm3: this.parseFloat(metadata.total_filament_volume_cm3 || metadata.filament_volume_cm3),
236
+ filamentDensityGramsCm3: this.parseFloat(metadata.filament_density),
237
+ filamentDiameterMm: this.parseFloat(metadata.filament_diameter) || 1.75,
238
+ maxLayerZ: this.parseFloat(metadata.max_z_height || metadata.max_layer_z),
239
+ slicerVersion: metadata.bambustudio || metadata.slicer_version || metadata.slicer || null,
240
+ nozzleDiameterMm: this.parseFloat(metadata.nozzle_diameter),
241
+ layerHeight: this.parseFloat(metadata.layer_height),
242
+ firstLayerHeight: this.parseFloat(metadata.first_layer_height || metadata.initial_layer_height || metadata.initial_layer_print_height),
243
+ bedTemperature: this.parseFloat(metadata.bed_temperature_actual || metadata.bed_temperature || metadata.bed_temp || metadata.bed_temperature_initial_layer),
244
+ nozzleTemperature: this.parseFloat(metadata.nozzle_temperature || metadata.nozzle_temp || metadata.nozzle_temperature_initial_layer),
245
+ fillDensity: metadata.sparse_infill_density || metadata.infill_density || metadata.fill_density || null,
246
+ filamentType: metadata.filament_type || null,
247
+ printerModel: metadata.printer_model || null,
248
+ objects: [],
249
+ thumbnails: plateThumbs.map((t)=>({
250
+ path: t.entryName,
251
+ size: t.getData().length,
252
+ type: t.entryName.endsWith(".png") ? "PNG" : "JPG"
253
+ }))
254
+ };
255
+ plates.push(plateMetadata);
256
+ }
257
+ return plates.sort((a, b)=>a.plateNumber - b.plateNumber);
258
+ }
259
+ parseGCodeHeader(gcode) {
260
+ const metadata = {};
261
+ const lines = gcode.split("\n").slice(0, 1000);
262
+ for (const line of lines){
263
+ if (line.startsWith(";")) {
264
+ if (line.includes("_BLOCK_START") || line.includes("_BLOCK_END")) continue;
265
+ const bambuMatch = line.match(/;\s*BambuStudio\s+([\d.]+)/i);
266
+ if (bambuMatch) {
267
+ metadata.bambustudio = `BambuStudio ${bambuMatch[1]}`;
268
+ continue;
269
+ }
270
+ const match = line.match(/;\s*([^=:]+?)\s*[:=]\s*(.+)/);
271
+ if (match) {
272
+ let key = match[1].trim().toLowerCase().replace(/\s+/g, "_");
273
+ let value = match[2].trim();
274
+ key = key.replace(/\[([^\]]+)\]/g, (_, unit)=>unit.replace(/\^/g, ''));
275
+ value = value.split(';')[0].trim();
276
+ value = value.replace(/\s*\[.*?\]\s*/g, '');
277
+ if (!metadata[key]) {
278
+ metadata[key] = value;
279
+ }
280
+ }
281
+ } else {
282
+ if (!metadata.bed_temperature_actual) {
283
+ const bedTempMatch = line.match(/^M1(40|90)\s+S(\d+)/);
284
+ if (bedTempMatch && Number.parseInt(bedTempMatch[2]) > 0) {
285
+ metadata.bed_temperature_actual = bedTempMatch[2];
286
+ }
287
+ }
288
+ }
289
+ }
290
+ return metadata;
291
+ }
292
+ extractThumbnails(zipEntries) {
293
+ const thumbnails = [];
294
+ const thumbEntries = zipEntries.filter((e)=>e.entryName.match(/Metadata\/.*\.(png|jpg|jpeg)/i) || e.entryName.match(/Thumbnails\/.*/i));
295
+ for (const entry of thumbEntries){
296
+ const sizeMatch = entry.entryName.match(/(\d+)x(\d+)/);
297
+ const width = sizeMatch ? Number.parseInt(sizeMatch[1]) : 0;
298
+ const height = sizeMatch ? Number.parseInt(sizeMatch[2]) : 0;
299
+ const format = entry.entryName.match(/\.(png|jpg|jpeg)$/i)?.[1].toUpperCase() || "PNG";
300
+ const imageData = entry.getData();
301
+ const base64Data = imageData.toString("base64");
302
+ thumbnails.push({
303
+ width,
304
+ height,
305
+ format,
306
+ path: entry.entryName,
307
+ data: base64Data
308
+ });
309
+ }
310
+ return thumbnails;
311
+ }
312
+ parseFloat(value) {
313
+ if (!value) return null;
314
+ const num = Number.parseFloat(value);
315
+ return Number.isNaN(num) ? null : num;
316
+ }
317
+ parseInt(value) {
318
+ if (!value) return null;
319
+ const num = Number.parseInt(value, 10);
320
+ return Number.isNaN(num) ? null : num;
321
+ }
322
+ parseTime(value) {
323
+ if (!value) return null;
324
+ const match = value.match(/(?:(\d+)h)?(?:\s*(\d+)m)?(?:\s*(\d+)s)?/);
325
+ if (match && (match[1] || match[2] || match[3])) {
326
+ const hours = Number.parseInt(match[1] || "0");
327
+ const minutes = Number.parseInt(match[2] || "0");
328
+ const secs = Number.parseInt(match[3] || "0");
329
+ return hours * 3600 + minutes * 60 + secs;
330
+ }
331
+ const seconds = Number.parseFloat(value);
332
+ if (!Number.isNaN(seconds)) return seconds;
333
+ return null;
334
+ }
335
+ }
336
+
337
+ //# sourceMappingURL=3mf.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/parsers/3mf.parser.ts"],"names":["ThreeMFParser","parse","filePath","stats","fs","stat","fileName","path","basename","zip","AdmZip","zipEntries","getEntries","metadataJsonEntry","find","e","entryName","metadata","jsonContent","getData","toString","jsonData","JSON","normalizeJsonMetadata","modelEntry","extractMetadataFromXML","plates","extractPlates","isMultiPlate","length","thumbnails","extractThumbnails","topLevelPrintTime","parseTime","printTime","topLevelFilamentWeight","parseFloat","totalFilamentWeight","filamentWeight","topLevelLayers","parseInt","layerCount","topLevelFilamentUsedMm","filamentUsed","topLevelFilamentUsedCm3","filamentVolume","topLevelFilamentDensity","filamentDensity","topLevelMaxZ","maxZ","topLevelSlicerVersion","slicerVersion","generator","topLevelNozzleDiameter","nozzleDiameter","topLevelLayerHeight","layerHeight","layer_height","topLevelFirstLayerHeight","firstLayerHeight","first_layer_height","topLevelBedTemp","bedTemp","bed_temperature","topLevelNozzleTemp","nozzleTemp","nozzle_temperature","topLevelFillDensity","infillDensity","infill_density","fill_density","topLevelFilamentType","filamentType","filament_type","topLevelPrinterModel","printerModel","printer_model","topLevelFilamentDiameter","filamentDiameter","filament_diameter","plate","gcodePrintTimeSeconds","filamentUsedGrams","totalLayers","filamentUsedMm","filamentUsedCm3","filamentDensityGramsCm3","maxLayerZ","nozzleDiameterMm","bedTemperature","nozzleTemperature","fillDensity","filamentDiameterMm","reduce","sum","p","Math","max","map","firstPlate","normalized","fileFormat","fileSize","size","totalPlates","totalFilamentUsedGrams","undefined","raw","_thumbnails","String","estimatedPrintTimeSec","xml","patterns","pattern","match","key","source","generatorMatch","plateEntries","filter","endsWith","entry","plateMatch","plateNumber","Number","gcodeContent","min","parseGCodeHeader","plateThumbs","includes","model_printing_time","total_estimated_time","print_time","total_filament_weight_g","filament_weight","total_filament_weight","total_layer_number","layer_count","total_layers","plateMetadata","total_filament_length_mm","filament_length_mm","filament_used_mm","total_filament_volume_cm3","filament_volume_cm3","filament_density","max_z_height","max_layer_z","bambustudio","slicer_version","slicer","nozzle_diameter","initial_layer_height","initial_layer_print_height","bed_temperature_actual","bed_temp","bed_temperature_initial_layer","nozzle_temp","nozzle_temperature_initial_layer","sparse_infill_density","objects","t","type","push","sort","a","b","gcode","lines","split","slice","line","startsWith","bambuMatch","trim","toLowerCase","replace","value","_","unit","bedTempMatch","thumbEntries","sizeMatch","width","height","format","toUpperCase","imageData","base64Data","data","num","isNaN","hours","minutes","secs","seconds"],"mappings":"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"}