@ifc-lite/codegen 1.0.0 ā 1.1.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/cli.js +23 -5
- package/dist/cli.js.map +1 -1
- package/dist/crc32.d.ts +16 -0
- package/dist/crc32.d.ts.map +1 -0
- package/dist/crc32.js +69 -0
- package/dist/crc32.js.map +1 -0
- package/dist/generator.d.ts +20 -4
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +175 -19
- package/dist/generator.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/rust-generator.d.ts +20 -0
- package/dist/rust-generator.d.ts.map +1 -0
- package/dist/rust-generator.js +640 -0
- package/dist/rust-generator.js.map +1 -0
- package/dist/serialization-generator.d.ts +11 -0
- package/dist/serialization-generator.d.ts.map +1 -0
- package/dist/serialization-generator.js +333 -0
- package/dist/serialization-generator.js.map +1 -0
- package/dist/type-ids-generator.d.ts +11 -0
- package/dist/type-ids-generator.d.ts.map +1 -0
- package/dist/type-ids-generator.js +153 -0
- package/dist/type-ids-generator.js.map +1 -0
- package/generated/ifc4x3/entities.ts +9 -13
- package/generated/ifc4x3/enums.ts +0 -4
- package/generated/ifc4x3/index.ts +4 -2
- package/generated/ifc4x3/schema-registry.ts +326 -2718
- package/generated/ifc4x3/selects.ts +0 -4
- package/generated/ifc4x3/serializers.ts +322 -0
- package/generated/ifc4x3/test-compile.ts +49 -0
- package/generated/ifc4x3/type-ids.ts +1882 -0
- package/generated/ifc4x3/types.ts +0 -4
- package/package.json +1 -1
- package/src/cli.ts +49 -18
- package/src/crc32.ts +77 -0
- package/src/generator.ts +213 -21
- package/src/index.ts +28 -2
- package/src/rust-generator.ts +715 -0
- package/src/serialization-generator.ts +343 -0
- package/src/type-ids-generator.ts +166 -0
- package/tsconfig.json +1 -0
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
-
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
-
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* IFC Type Aliases
|
|
7
3
|
* Generated from EXPRESS schema: IFC4X3_DEV_923b0514
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -5,37 +5,68 @@
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* CLI for IFC code generation
|
|
8
|
+
*
|
|
9
|
+
* Generates TypeScript and optionally Rust code from IFC EXPRESS schemas.
|
|
8
10
|
*/
|
|
9
11
|
|
|
10
12
|
import { Command } from 'commander';
|
|
11
|
-
import { generateFromFile } from './generator.js';
|
|
13
|
+
import { generateFromFile, type GeneratorOptions } from './generator.js';
|
|
12
14
|
|
|
13
15
|
const program = new Command();
|
|
14
16
|
|
|
15
17
|
program
|
|
16
18
|
.name('ifc-codegen')
|
|
17
|
-
.description('Generate TypeScript code from IFC EXPRESS schemas')
|
|
18
|
-
.version('0.
|
|
19
|
+
.description('Generate TypeScript and Rust code from IFC EXPRESS schemas')
|
|
20
|
+
.version('0.2.0');
|
|
19
21
|
|
|
20
22
|
program
|
|
21
23
|
.argument('<schema>', 'Path to EXPRESS schema file (.exp)')
|
|
22
24
|
.option('-o, --output <dir>', 'Output directory', './generated')
|
|
25
|
+
.option('-r, --rust', 'Generate Rust code', false)
|
|
26
|
+
.option('--rust-dir <dir>', 'Rust output subdirectory (relative to output)', 'rust')
|
|
27
|
+
.option('--skip-collision-check', 'Skip CRC32 collision check', false)
|
|
23
28
|
.option('-v, --verbose', 'Verbose output', false)
|
|
24
|
-
.action(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
.action(
|
|
30
|
+
(
|
|
31
|
+
schemaPath: string,
|
|
32
|
+
options: {
|
|
33
|
+
output: string;
|
|
34
|
+
rust: boolean;
|
|
35
|
+
rustDir: string;
|
|
36
|
+
skipCollisionCheck: boolean;
|
|
37
|
+
verbose: boolean;
|
|
38
|
+
}
|
|
39
|
+
) => {
|
|
40
|
+
try {
|
|
41
|
+
console.log('š IFC Code Generator\n');
|
|
42
|
+
console.log(`Schema: ${schemaPath}`);
|
|
43
|
+
console.log(`Output: ${options.output}`);
|
|
44
|
+
if (options.rust) {
|
|
45
|
+
// Check if rustDir is absolute or relative for display
|
|
46
|
+
const rustDisplay = options.rustDir.startsWith('/')
|
|
47
|
+
? options.rustDir
|
|
48
|
+
: `${options.output}/${options.rustDir}`;
|
|
49
|
+
console.log(`Rust: ${rustDisplay}`);
|
|
50
|
+
}
|
|
51
|
+
console.log();
|
|
52
|
+
|
|
53
|
+
const start = Date.now();
|
|
54
|
+
|
|
55
|
+
const genOptions: GeneratorOptions = {
|
|
56
|
+
rust: options.rust,
|
|
57
|
+
rustDir: options.rustDir,
|
|
58
|
+
skipCollisionCheck: options.skipCollisionCheck,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
generateFromFile(schemaPath, options.output, genOptions);
|
|
62
|
+
|
|
63
|
+
const elapsed = Date.now() - start;
|
|
64
|
+
console.log(`\nā±ļø Completed in ${elapsed}ms`);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('\nā Error:', error instanceof Error ? error.message : error);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
38
69
|
}
|
|
39
|
-
|
|
70
|
+
);
|
|
40
71
|
|
|
41
72
|
program.parse();
|
package/src/crc32.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CRC32 Type ID Generator
|
|
7
|
+
*
|
|
8
|
+
* Generates consistent CRC32 hashes for IFC type names.
|
|
9
|
+
* Used for fast O(1) type lookup in both TypeScript and Rust.
|
|
10
|
+
*
|
|
11
|
+
* This matches the algorithm used by web-ifc for compatibility.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Pre-computed CRC32 lookup table (IEEE polynomial)
|
|
15
|
+
const CRC32_TABLE = buildCRC32Table();
|
|
16
|
+
|
|
17
|
+
function buildCRC32Table(): Uint32Array {
|
|
18
|
+
const table = new Uint32Array(256);
|
|
19
|
+
for (let i = 0; i < 256; i++) {
|
|
20
|
+
let c = i;
|
|
21
|
+
for (let j = 0; j < 8; j++) {
|
|
22
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
23
|
+
}
|
|
24
|
+
table[i] = c >>> 0;
|
|
25
|
+
}
|
|
26
|
+
return table;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Calculate CRC32 hash for a string
|
|
31
|
+
* @param str Input string (will be uppercased)
|
|
32
|
+
* @returns 32-bit unsigned integer hash
|
|
33
|
+
*/
|
|
34
|
+
export function crc32(str: string): number {
|
|
35
|
+
const upper = str.toUpperCase();
|
|
36
|
+
let crc = 0xffffffff;
|
|
37
|
+
for (let i = 0; i < upper.length; i++) {
|
|
38
|
+
crc = CRC32_TABLE[(crc ^ upper.charCodeAt(i)) & 0xff] ^ (crc >>> 8);
|
|
39
|
+
}
|
|
40
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Generate type IDs for all entities in a schema
|
|
45
|
+
*/
|
|
46
|
+
export function generateTypeIds(entityNames: string[]): Map<string, number> {
|
|
47
|
+
const ids = new Map<string, number>();
|
|
48
|
+
for (const name of entityNames) {
|
|
49
|
+
ids.set(name, crc32(name));
|
|
50
|
+
}
|
|
51
|
+
return ids;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Check for CRC32 collisions in a list of names
|
|
56
|
+
* @returns Map of hash -> names[] for any collisions
|
|
57
|
+
*/
|
|
58
|
+
export function findCollisions(names: string[]): Map<number, string[]> {
|
|
59
|
+
const hashToNames = new Map<number, string[]>();
|
|
60
|
+
|
|
61
|
+
for (const name of names) {
|
|
62
|
+
const hash = crc32(name);
|
|
63
|
+
const existing = hashToNames.get(hash) || [];
|
|
64
|
+
existing.push(name);
|
|
65
|
+
hashToNames.set(hash, existing);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Filter to only collisions
|
|
69
|
+
const collisions = new Map<number, string[]>();
|
|
70
|
+
for (const [hash, nameList] of hashToNames) {
|
|
71
|
+
if (nameList.length > 1) {
|
|
72
|
+
collisions.set(hash, nameList);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return collisions;
|
|
77
|
+
}
|
package/src/generator.ts
CHANGED
|
@@ -3,29 +3,61 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* High-level
|
|
6
|
+
* High-level Code Generator
|
|
7
|
+
*
|
|
8
|
+
* Orchestrates code generation from EXPRESS schemas to:
|
|
9
|
+
* - TypeScript interfaces and types
|
|
10
|
+
* - TypeScript type IDs (CRC32)
|
|
11
|
+
* - TypeScript serialization helpers
|
|
12
|
+
* - Rust types and type IDs
|
|
7
13
|
*/
|
|
8
14
|
|
|
9
|
-
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
10
|
-
import {
|
|
11
|
-
import { parseExpressSchema } from './express-parser.js';
|
|
15
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
16
|
+
import { join, isAbsolute } from 'node:path';
|
|
17
|
+
import { parseExpressSchema, type ExpressSchema } from './express-parser.js';
|
|
12
18
|
import { generateTypeScript, type GeneratedCode } from './typescript-generator.js';
|
|
19
|
+
import { generateTypeIds } from './type-ids-generator.js';
|
|
20
|
+
import { generateSerializers } from './serialization-generator.js';
|
|
21
|
+
import { generateRust, type RustGeneratedCode } from './rust-generator.js';
|
|
22
|
+
import { findCollisions } from './crc32.js';
|
|
23
|
+
|
|
24
|
+
export interface FullGeneratedCode extends GeneratedCode {
|
|
25
|
+
typeIds: string;
|
|
26
|
+
serializers: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface GeneratorOptions {
|
|
30
|
+
/** Generate Rust output */
|
|
31
|
+
rust?: boolean;
|
|
32
|
+
/** Rust output directory (relative to outputDir or absolute) */
|
|
33
|
+
rustDir?: string;
|
|
34
|
+
/** Skip type ID collision check */
|
|
35
|
+
skipCollisionCheck?: boolean;
|
|
36
|
+
}
|
|
13
37
|
|
|
14
38
|
/**
|
|
15
|
-
* Generate
|
|
39
|
+
* Generate all code from an EXPRESS schema file
|
|
16
40
|
*/
|
|
17
|
-
export function generateFromFile(
|
|
41
|
+
export function generateFromFile(
|
|
42
|
+
schemaPath: string,
|
|
43
|
+
outputDir: string,
|
|
44
|
+
options: GeneratorOptions = {}
|
|
45
|
+
): FullGeneratedCode {
|
|
18
46
|
// Read schema file
|
|
19
47
|
const content = readFileSync(schemaPath, 'utf-8');
|
|
20
48
|
|
|
21
49
|
// Generate code
|
|
22
|
-
return generateFromSchema(content, outputDir);
|
|
50
|
+
return generateFromSchema(content, outputDir, options);
|
|
23
51
|
}
|
|
24
52
|
|
|
25
53
|
/**
|
|
26
|
-
* Generate
|
|
54
|
+
* Generate all code from EXPRESS schema content
|
|
27
55
|
*/
|
|
28
|
-
export function generateFromSchema(
|
|
56
|
+
export function generateFromSchema(
|
|
57
|
+
schemaContent: string,
|
|
58
|
+
outputDir: string,
|
|
59
|
+
options: GeneratorOptions = {}
|
|
60
|
+
): FullGeneratedCode {
|
|
29
61
|
console.log('š Parsing EXPRESS schema...');
|
|
30
62
|
const schema = parseExpressSchema(schemaContent);
|
|
31
63
|
|
|
@@ -35,35 +67,62 @@ export function generateFromSchema(schemaContent: string, outputDir: string): Ge
|
|
|
35
67
|
console.log(` - ${schema.enums.length} enums`);
|
|
36
68
|
console.log(` - ${schema.selects.length} selects`);
|
|
37
69
|
|
|
70
|
+
// Check for CRC32 collisions
|
|
71
|
+
if (!options.skipCollisionCheck) {
|
|
72
|
+
console.log('\nš Checking for CRC32 collisions...');
|
|
73
|
+
const entityNames = schema.entities.map((e) => e.name);
|
|
74
|
+
const collisions = findCollisions(entityNames);
|
|
75
|
+
if (collisions.size > 0) {
|
|
76
|
+
console.warn('ā ļø CRC32 collisions detected:');
|
|
77
|
+
for (const [hash, names] of collisions) {
|
|
78
|
+
console.warn(` ${hash}: ${names.join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
console.log(' ā No collisions');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
38
85
|
console.log('\nšØ Generating TypeScript code...');
|
|
39
|
-
const
|
|
86
|
+
const tsCode = generateTypeScript(schema);
|
|
87
|
+
const typeIds = generateTypeIds(schema);
|
|
88
|
+
const serializers = generateSerializers(schema);
|
|
40
89
|
|
|
41
|
-
console.log('š¾ Writing
|
|
90
|
+
console.log('š¾ Writing TypeScript files...');
|
|
42
91
|
|
|
43
92
|
// Create output directory
|
|
44
93
|
mkdirSync(outputDir, { recursive: true });
|
|
45
94
|
|
|
46
|
-
// Write files
|
|
47
|
-
writeFileSync(`${outputDir}/entities.ts`,
|
|
95
|
+
// Write TypeScript files
|
|
96
|
+
writeFileSync(`${outputDir}/entities.ts`, tsCode.entities);
|
|
48
97
|
console.log(` ā ${outputDir}/entities.ts`);
|
|
49
98
|
|
|
50
|
-
writeFileSync(`${outputDir}/types.ts`,
|
|
99
|
+
writeFileSync(`${outputDir}/types.ts`, tsCode.types);
|
|
51
100
|
console.log(` ā ${outputDir}/types.ts`);
|
|
52
101
|
|
|
53
|
-
writeFileSync(`${outputDir}/enums.ts`,
|
|
102
|
+
writeFileSync(`${outputDir}/enums.ts`, tsCode.enums);
|
|
54
103
|
console.log(` ā ${outputDir}/enums.ts`);
|
|
55
104
|
|
|
56
|
-
writeFileSync(`${outputDir}/selects.ts`,
|
|
105
|
+
writeFileSync(`${outputDir}/selects.ts`, tsCode.selects);
|
|
57
106
|
console.log(` ā ${outputDir}/selects.ts`);
|
|
58
107
|
|
|
59
|
-
writeFileSync(`${outputDir}/schema-registry.ts`,
|
|
108
|
+
writeFileSync(`${outputDir}/schema-registry.ts`, tsCode.schemaRegistry);
|
|
60
109
|
console.log(` ā ${outputDir}/schema-registry.ts`);
|
|
61
110
|
|
|
111
|
+
writeFileSync(`${outputDir}/type-ids.ts`, typeIds);
|
|
112
|
+
console.log(` ā ${outputDir}/type-ids.ts`);
|
|
113
|
+
|
|
114
|
+
writeFileSync(`${outputDir}/serializers.ts`, serializers);
|
|
115
|
+
console.log(` ā ${outputDir}/serializers.ts`);
|
|
116
|
+
|
|
62
117
|
// Write index file
|
|
63
|
-
const indexContent =
|
|
64
|
-
*
|
|
118
|
+
const indexContent = `/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
119
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
120
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generated IFC Schema: ${schema.name}
|
|
65
124
|
*
|
|
66
|
-
* DO NOT EDIT - This file is auto-generated
|
|
125
|
+
* DO NOT EDIT - This file is auto-generated by @ifc-lite/codegen
|
|
67
126
|
*/
|
|
68
127
|
|
|
69
128
|
export * from './entities.js';
|
|
@@ -71,11 +130,144 @@ export * from './types.js';
|
|
|
71
130
|
export * from './enums.js';
|
|
72
131
|
export * from './selects.js';
|
|
73
132
|
export * from './schema-registry.js';
|
|
133
|
+
export * from './type-ids.js';
|
|
134
|
+
export * from './serializers.js';
|
|
74
135
|
`;
|
|
75
136
|
writeFileSync(`${outputDir}/index.ts`, indexContent);
|
|
76
137
|
console.log(` ā ${outputDir}/index.ts`);
|
|
77
138
|
|
|
139
|
+
// Generate Rust code if requested
|
|
140
|
+
if (options.rust) {
|
|
141
|
+
console.log('\nš¦ Generating Rust code...');
|
|
142
|
+
const rustCode = generateRust(schema);
|
|
143
|
+
// Use absolute path directly, or join relative path with outputDir
|
|
144
|
+
const rustDir = options.rustDir
|
|
145
|
+
? isAbsolute(options.rustDir)
|
|
146
|
+
? options.rustDir
|
|
147
|
+
: join(outputDir, options.rustDir)
|
|
148
|
+
: join(outputDir, 'rust');
|
|
149
|
+
|
|
150
|
+
mkdirSync(rustDir, { recursive: true });
|
|
151
|
+
|
|
152
|
+
writeFileSync(`${rustDir}/type_ids.rs`, rustCode.typeIds);
|
|
153
|
+
console.log(` ā ${rustDir}/type_ids.rs`);
|
|
154
|
+
|
|
155
|
+
writeFileSync(`${rustDir}/schema.rs`, rustCode.schema);
|
|
156
|
+
console.log(` ā ${rustDir}/schema.rs`);
|
|
157
|
+
|
|
158
|
+
writeFileSync(`${rustDir}/geometry_categories.rs`, rustCode.geometryCategories);
|
|
159
|
+
console.log(` ā ${rustDir}/geometry_categories.rs`);
|
|
160
|
+
|
|
161
|
+
// Write mod.rs
|
|
162
|
+
const modContent = `// This Source Code Form is subject to the terms of the Mozilla Public
|
|
163
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
164
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
165
|
+
|
|
166
|
+
//! Auto-generated IFC Schema Types
|
|
167
|
+
//!
|
|
168
|
+
//! Generated from EXPRESS schema: ${schema.name}
|
|
169
|
+
//!
|
|
170
|
+
//! DO NOT EDIT - This file is auto-generated by @ifc-lite/codegen
|
|
171
|
+
|
|
172
|
+
mod type_ids;
|
|
173
|
+
mod schema;
|
|
174
|
+
mod geometry_categories;
|
|
175
|
+
|
|
176
|
+
pub use type_ids::*;
|
|
177
|
+
pub use schema::*;
|
|
178
|
+
pub use geometry_categories::*;
|
|
179
|
+
`;
|
|
180
|
+
writeFileSync(`${rustDir}/mod.rs`, modContent);
|
|
181
|
+
console.log(` ā ${rustDir}/mod.rs`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Write test-compile file
|
|
185
|
+
const testCompileContent = `/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
186
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
187
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Type-check test file
|
|
191
|
+
* This file is used to verify the generated types compile correctly.
|
|
192
|
+
*
|
|
193
|
+
* DO NOT EDIT - This file is auto-generated
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
import type { IfcWall, IfcProject, IfcExtrudedAreaSolid } from './entities.js';
|
|
197
|
+
import { TYPE_IDS, getTypeId, getTypeName } from './type-ids.js';
|
|
198
|
+
import { SCHEMA_REGISTRY, getEntityMetadata } from './schema-registry.js';
|
|
199
|
+
import { toStepLine, serializeValue, ref, enumVal, type StepEntity } from './serializers.js';
|
|
200
|
+
|
|
201
|
+
// Test type IDs
|
|
202
|
+
const wallId: number = TYPE_IDS.IfcWall;
|
|
203
|
+
const projectId: number = TYPE_IDS.IfcProject;
|
|
204
|
+
|
|
205
|
+
// Test ID lookup
|
|
206
|
+
const wallIdFromName = getTypeId('IfcWall');
|
|
207
|
+
const nameFromId = getTypeName(wallId);
|
|
208
|
+
|
|
209
|
+
// Test schema registry
|
|
210
|
+
const wallMeta = getEntityMetadata('IfcWall');
|
|
211
|
+
const wallAttrs = wallMeta?.allAttributes;
|
|
212
|
+
|
|
213
|
+
// Test serialization
|
|
214
|
+
const testEntity: StepEntity = {
|
|
215
|
+
expressId: 1,
|
|
216
|
+
type: 'IfcProject',
|
|
217
|
+
GlobalId: '0YvctVUKr0kugbFTf53O9L',
|
|
218
|
+
OwnerHistory: ref(2),
|
|
219
|
+
Name: 'Test Project',
|
|
220
|
+
Description: null,
|
|
221
|
+
ObjectType: null,
|
|
222
|
+
LongName: null,
|
|
223
|
+
Phase: null,
|
|
224
|
+
RepresentationContexts: [ref(3)],
|
|
225
|
+
UnitsInContext: ref(4),
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const stepLine = toStepLine(testEntity);
|
|
229
|
+
|
|
230
|
+
console.log('ā All types compile correctly');
|
|
231
|
+
console.log(' Wall ID:', wallId);
|
|
232
|
+
console.log(' Project ID:', projectId);
|
|
233
|
+
console.log(' STEP line:', stepLine);
|
|
234
|
+
`;
|
|
235
|
+
writeFileSync(`${outputDir}/test-compile.ts`, testCompileContent);
|
|
236
|
+
console.log(` ā ${outputDir}/test-compile.ts`);
|
|
237
|
+
|
|
78
238
|
console.log('\n⨠Code generation complete!');
|
|
79
239
|
|
|
80
|
-
return
|
|
240
|
+
return {
|
|
241
|
+
...tsCode,
|
|
242
|
+
typeIds,
|
|
243
|
+
serializers,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Generate code for both IFC4 and IFC4X3 schemas
|
|
249
|
+
*/
|
|
250
|
+
export function generateAll(
|
|
251
|
+
schemasDir: string,
|
|
252
|
+
outputBaseDir: string,
|
|
253
|
+
options: GeneratorOptions = {}
|
|
254
|
+
): void {
|
|
255
|
+
const schemas = [
|
|
256
|
+
{ name: 'IFC4', file: 'IFC4_ADD2_TC1.exp', dir: 'ifc4' },
|
|
257
|
+
{ name: 'IFC4X3', file: 'IFC4X3_ADD2.exp', dir: 'ifc4x3' },
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
for (const schema of schemas) {
|
|
261
|
+
const schemaPath = join(schemasDir, schema.file);
|
|
262
|
+
if (existsSync(schemaPath)) {
|
|
263
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
264
|
+
console.log(`Processing ${schema.name}...`);
|
|
265
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
266
|
+
|
|
267
|
+
const outputDir = join(outputBaseDir, schema.dir);
|
|
268
|
+
generateFromFile(schemaPath, outputDir, options);
|
|
269
|
+
} else {
|
|
270
|
+
console.warn(`ā ļø Schema file not found: ${schemaPath}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
81
273
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @ifc-lite/codegen
|
|
7
7
|
*
|
|
8
|
-
* TypeScript
|
|
8
|
+
* IFC Code Generator - TypeScript and Rust from EXPRESS schemas
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - TypeScript interfaces from EXPRESS entities
|
|
12
|
+
* - CRC32 type IDs for fast O(1) lookup
|
|
13
|
+
* - Serialization support for IFC writing
|
|
14
|
+
* - Rust type generation
|
|
15
|
+
* - Schema metadata registry
|
|
9
16
|
*/
|
|
10
17
|
|
|
18
|
+
// Core parser
|
|
11
19
|
export {
|
|
12
20
|
parseExpressSchema,
|
|
13
21
|
getAllAttributes,
|
|
@@ -22,10 +30,28 @@ export {
|
|
|
22
30
|
type InverseAttribute,
|
|
23
31
|
} from './express-parser.js';
|
|
24
32
|
|
|
33
|
+
// TypeScript generation
|
|
25
34
|
export {
|
|
26
35
|
generateTypeScript,
|
|
27
36
|
writeGeneratedFiles,
|
|
28
37
|
type GeneratedCode,
|
|
29
38
|
} from './typescript-generator.js';
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
// Type IDs (CRC32)
|
|
41
|
+
export { generateTypeIds } from './type-ids-generator.js';
|
|
42
|
+
export { crc32, generateTypeIds as generateTypeIdMap, findCollisions } from './crc32.js';
|
|
43
|
+
|
|
44
|
+
// Serialization
|
|
45
|
+
export { generateSerializers } from './serialization-generator.js';
|
|
46
|
+
|
|
47
|
+
// Rust generation
|
|
48
|
+
export { generateRust, type RustGeneratedCode } from './rust-generator.js';
|
|
49
|
+
|
|
50
|
+
// High-level generator
|
|
51
|
+
export {
|
|
52
|
+
generateFromFile,
|
|
53
|
+
generateFromSchema,
|
|
54
|
+
generateAll,
|
|
55
|
+
type FullGeneratedCode,
|
|
56
|
+
type GeneratorOptions,
|
|
57
|
+
} from './generator.js';
|