Skip to content

Commit 722f8be

Browse files
committed
Support regular FlashPrint GX format
1 parent ccef54e commit 722f8be

8 files changed

Lines changed: 383 additions & 226 deletions

File tree

__tests__/fixtures/FlashPrint.gx

135 KB
Binary file not shown.

__tests__/parser.test.ts

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import * as fs from 'fs';
66
const fixturesDir = path.join(__dirname, 'fixtures');
77
const gcodeFilePath = path.join(fixturesDir, 'test.gcode');
88
const orcaGcodeFilePath = path.join(fixturesDir, 'regular_orca_test.gcode');
9-
const legacyGxFilePath = path.join(fixturesDir, 'legacy.gx');
10-
const threeMfFilePath = path.join(fixturesDir, 'test.3mf');
9+
const convertedGxFilePath = path.join(fixturesDir, 'converted.gx');
10+
const flashPrintGxFilePath = path.join(fixturesDir, 'FlashPrint.gx');
11+
const orcaFFthreeMfFilePath = path.join(fixturesDir, 'orca-flashforge.3mf');
1112
const nonExistentFilePath = path.join(fixturesDir, 'nonexistent.file');
1213
const unsupportedFilePath = path.join(fixturesDir, 'test.txt');
1314

@@ -25,7 +26,7 @@ describe('Slicer File Parser', () => {
2526
// Increase timeout slightly for parsing complex files if needed
2627
// jest.setTimeout(10000);
2728

28-
describe('G-Code Parsing (test.gcode)', () => {
29+
describe('FlashPrint G-Code Parsing (test.gcode)', () => {
2930
let gcodeResult: Awaited<ReturnType<typeof parseSlicerFile>>; // Store result for logging
3031

3132
// Use beforeAll to parse once per describe block
@@ -81,12 +82,12 @@ describe('Slicer File Parser', () => {
8182
});
8283
});
8384

84-
describe('Legacy GX Parsing (legacy.gx)', () => {
85+
describe('FlashPrint Converted GX Parsing (converted.gx)', () => {
8586
let gxResult: Awaited<ReturnType<typeof parseSlicerFile>>; // Store result for logging
8687

8788
// Use beforeAll to parse once per describe block
8889
beforeAll(async () => {
89-
gxResult = await parseSlicerFile(legacyGxFilePath);
90+
gxResult = await parseSlicerFile(convertedGxFilePath);
9091
});
9192

9293
it('should parse the file without error', () => {
@@ -107,7 +108,6 @@ describe('Slicer File Parser', () => {
107108
const slicer = gxResult.slicer;
108109
expect(slicer).toBeDefined();
109110

110-
// values from legacy.gx
111111
expect(slicer?.slicer).toBe(SlicerType.LegacyGX);
112112
expect(slicer?.slicerName).toEqual('OrcaSlicer');
113113
expect(slicer?.slicerVersion).toEqual('2.3.1-dev');
@@ -132,12 +132,60 @@ describe('Slicer File Parser', () => {
132132
});
133133
});
134134

135-
describe('3MF Parsing (test.3mf)', () => {
135+
describe('Standard FlashPrint GX Parsing (FlashPrint.gx)', () => {
136+
let flashprintGxResult: Awaited<ReturnType<typeof parseSlicerFile>>; // Store result for logging
137+
138+
// Use beforeAll to parse once per describe block
139+
beforeAll(async () => {
140+
flashprintGxResult = await parseSlicerFile(flashPrintGxFilePath);
141+
});
142+
143+
it('should parse the file without error', () => {
144+
expect(flashprintGxResult).toBeDefined();
145+
});
146+
147+
it('should work with parseSlicerFile', () => {
148+
expect(flashprintGxResult).toHaveProperty('slicer');
149+
expect(flashprintGxResult).toHaveProperty('file');
150+
expect(flashprintGxResult).toHaveProperty('threeMf');
151+
expect(flashprintGxResult.threeMf).toBeNull();
152+
expect(flashprintGxResult.slicer).toBeDefined();
153+
expect(flashprintGxResult.file).toBeDefined();
154+
});
155+
156+
it('should parse slicer metadata', () => {
157+
const slicer = flashprintGxResult.slicer;
158+
expect(slicer).toBeDefined();
159+
160+
// Test for values from the generator line in the FlashPrint GX format
161+
expect(slicer?.slicer).toBe(SlicerType.LegacyGX);
162+
expect(slicer?.slicerName).toEqual('ffslicer');
163+
expect(slicer?.slicerVersion).toEqual('2.4.4');
164+
expect(slicer?.sliceDate).toEqual('05/13/25');
165+
expect(slicer?.sliceTime).not.toEqual('Error');
166+
});
167+
168+
it('should parse file metadata', () => {
169+
const file = flashprintGxResult.file;
170+
expect(file).toBeDefined();
171+
172+
// Only test for values we know are available from the file
173+
expect(file?.sliceSoft).toBe(SlicerType.LegacyGX);
174+
expect(file?.filamentType).toEqual('PLA');
175+
expect(file?.printerModel).toEqual('Adventurer 4 Series');
176+
177+
// Check thumbnail extraction
178+
expect(file?.thumbnail).toBeDefined();
179+
expect(file?.thumbnail).toEqual(expect.stringContaining('data:image/png;base64,'));
180+
});
181+
});
182+
183+
describe('Orca-FlashForge 3MF Parsing (orca-flashforge.3mf)', () => {
136184
let threeMfResult: Awaited<ReturnType<typeof parseSlicerFile>>; // Store result
137185

138186
beforeAll(async () => {
139187
// 3MF parsing within parseSlicerFile is sync *after* file read, but await the promise
140-
threeMfResult = await parseSlicerFile(threeMfFilePath);
188+
threeMfResult = await parseSlicerFile(orcaFFthreeMfFilePath);
141189
});
142190

143191
it('should parse the file without error', () => {
@@ -155,7 +203,7 @@ describe('Slicer File Parser', () => {
155203
const threeMf = threeMfResult.threeMf;
156204
expect(threeMf).toBeDefined();
157205

158-
// values from test.3mf
206+
// values from orca-flashforge.3mf
159207
expect(threeMf?.printerModelId).toEqual('Flashforge-Adventurer-5M-Pro');
160208
expect(threeMf?.supportUsed).toEqual(false);
161209
expect(threeMf?.fileNames).toEqual(['SunluHSOrange.stl']);
@@ -210,7 +258,7 @@ describe('Slicer File Parser', () => {
210258

211259
});
212260

213-
describe('Standard OrcaSlicer Parsing', () => {
261+
describe('Standard OrcaSlicer Parsing (regular_orca_test.gcode)', () => {
214262
let orcaGcodeResult: Awaited<ReturnType<typeof parseSlicerFile>>; // Store result for logging
215263

216264
// Use beforeAll to parse once per describe block

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export type { FilamentInfo } from './FilamentInfo';
1414
export { GCodeParser } from './parser/gcode/GCodeParser';
1515
export { FlashPrintParser } from './parser/gcode/FlashPrintParser';
1616
export { OrcaFlashForgeParser } from './parser/gcode/OrcaFlashForgeParser';
17-
export { LegacyGXParser } from './parser/gcode/LegacyGXParser';
17+
export { GXParser } from './parser/gcode/GXParser';
1818
export { ThreeMfParser } from './parser/threemf/ThreeMfParser';
1919

2020

src/parser/gcode/GCodeParser.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { SlicerFileMeta } from '../../SlicerFileMeta';
55
import { SlicerType } from '../../SlicerType';
66
import { FlashPrintParser } from './FlashPrintParser';
77
import { OrcaFlashForgeParser } from './OrcaFlashForgeParser';
8-
import { LegacyGXParser } from './LegacyGXParser';
8+
import { GXParser } from './GXParser';
99

1010
/**
1111
* AIO GCode Parser
@@ -54,7 +54,7 @@ export class GCodeParser {
5454
this.fileInfo = result.fileMeta;
5555
break;
5656
case SlicerType.LegacyGX:
57-
result = LegacyGXParser.parse(filePath);
57+
result = GXParser.parse(filePath);
5858
this.slicerInfo = result.slicerMeta;
5959
this.fileInfo = result.fileMeta;
6060
break;
@@ -95,7 +95,7 @@ export class GCodeParser {
9595
this.fileInfo = result.fileMeta;
9696
break;
9797
case SlicerType.LegacyGX:
98-
result = LegacyGXParser.parseFromContent(content);
98+
result = GXParser.parseFromContent(content);
9999
this.slicerInfo = result.slicerMeta;
100100
this.fileInfo = result.fileMeta;
101101
break;

0 commit comments

Comments
 (0)