@needle-tools/needle-component-compiler 3.0.3-f6b855c → 3.0.4-9debd7d

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/Changelog.md CHANGED
@@ -15,11 +15,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
15
15
 
16
16
  ### Added
17
17
  - `@type` override on methods: `// @type ReturnType` overrides the return type, `// @type paramName ParamType` overrides a specific parameter's type
18
- - C# enum generation: exported enums are now generated as separate `.cs` files in the `Needle.Typescript.GeneratedComponents` namespace
19
- - Supports numeric enums (with explicit or auto-incremented values) and string enums
20
- - Lowercase enum names are automatically PascalCased (e.g. `lightType` → `LightType`)
21
- - Non-exported enums are registered for type resolution but not generated as files
22
- - Opt out per enum with `// @dont-generate-enum`
23
18
 
24
19
  ## [3.0.1] - 2026-03-04
25
20
 
@@ -14,8 +14,6 @@ export declare abstract class BaseWriter implements IWriter {
14
14
  abstract writeMember(visibility: Visibility, name: string, isArray: boolean, type: string, initialValue?: string, comments?: string[]): void;
15
15
  abstract writeMethod(visibility: Visibility, name: string, returnType: string, args: Argument[], comments: string[]): void;
16
16
  abstract writeNewTypeExpression(typeName: string, args?: string[]): void;
17
- /** Override to generate enum output. Default is no-op. */
18
- writeEnum(name: string, members: EnumMember[], comments?: string[]): void;
19
17
  private _currentlyProcessingFiles;
20
18
  get outputInfo(): TypeSourceInformation;
21
19
  private _createdSchemesPerFile;
@@ -23,10 +23,6 @@ var BaseWriter = /** @class */ (function () {
23
23
  BaseWriter.prototype.registerEnum = function (name, members) {
24
24
  this._enumRegistry.set(name.toLowerCase(), members);
25
25
  };
26
- /** Override to generate enum output. Default is no-op. */
27
- BaseWriter.prototype.writeEnum = function (name, members, comments) {
28
- // no-op by default — subclasses can override
29
- };
30
26
  Object.defineProperty(BaseWriter.prototype, "outputInfo", {
31
27
  get: function () {
32
28
  return this._createdSchemesPerFile;
@@ -7,6 +7,10 @@ export declare class Compiler {
7
7
  private visit;
8
8
  private visitClassDeclaration;
9
9
  private visitPropertyDeclaration;
10
+ private hasSerializableDecorator;
11
+ /** Track accessor names already emitted per class to avoid duplicates when both getter and setter have @serializable() */
12
+ private _emittedAccessors;
13
+ private visitAccessorDeclaration;
10
14
  private visitMethodDeclaration;
11
15
  private resolveParameters;
12
16
  private debugLog;
package/dist/Compiler.js CHANGED
@@ -6,6 +6,8 @@ var base_compiler_1 = require("./base-compiler");
6
6
  /** Typescript Walker */
7
7
  var Compiler = /** @class */ (function () {
8
8
  function Compiler() {
9
+ /** Track accessor names already emitted per class to avoid duplicates when both getter and setter have @serializable() */
10
+ this._emittedAccessors = new Set();
9
11
  }
10
12
  Compiler.prototype.compile = function (writer, code, sourceFilePath) {
11
13
  var file = "needle_compiled.ts";
@@ -29,12 +31,11 @@ var Compiler = /** @class */ (function () {
29
31
  writer.end(filePath);
30
32
  };
31
33
  Compiler.prototype.visitEnumDeclaration = function (node, writer) {
32
- var _a;
33
34
  var name = node.name.getText();
34
35
  var members = [];
35
36
  var nextValue = 0;
36
- for (var _i = 0, _b = node.members; _i < _b.length; _i++) {
37
- var member = _b[_i];
37
+ for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
38
+ var member = _a[_i];
38
39
  var memberName = member.name.getText();
39
40
  var value = void 0;
40
41
  if (member.initializer) {
@@ -62,13 +63,7 @@ var Compiler = /** @class */ (function () {
62
63
  members.push({ name: memberName, value: value });
63
64
  }
64
65
  this.debugLog("[COMPILER] ENUM", name, members);
65
- // Always register for type resolution
66
66
  writer.registerEnum(name, members);
67
- // Only generate enum file for exported enums
68
- var isExported = (_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.some(function (m) { return m.kind === ts.SyntaxKind.ExportKeyword; });
69
- if (isExported) {
70
- writer.writeEnum(name, members, this.getComments(node));
71
- }
72
67
  };
73
68
  Compiler.prototype.visit = function (filePath, node, writer) {
74
69
  var _this = this;
@@ -81,6 +76,9 @@ var Compiler = /** @class */ (function () {
81
76
  else if (ts.isMethodDeclaration(node)) {
82
77
  this.visitMethodDeclaration(node, writer);
83
78
  }
79
+ else if (ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node)) {
80
+ this.visitAccessorDeclaration(node, writer);
81
+ }
84
82
  else {
85
83
  ts.forEachChild(node, function (node) {
86
84
  _this.visit(filePath, node, writer);
@@ -110,6 +108,7 @@ var Compiler = /** @class */ (function () {
110
108
  this.debugLog("CLASS SKIPPED", name);
111
109
  return;
112
110
  }
111
+ this._emittedAccessors.clear();
113
112
  ts.forEachChild(node, function (node) {
114
113
  _this.visit(filePath, node, writer);
115
114
  });
@@ -140,6 +139,38 @@ var Compiler = /** @class */ (function () {
140
139
  return; // cannot determine type — skip the field
141
140
  writer.writeMember(visibility, name, isArray, type, initialValue, this.getComments(node));
142
141
  };
142
+ Compiler.prototype.hasSerializableDecorator = function (node) {
143
+ var _a;
144
+ var decorators = node.decorators;
145
+ return (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some(function (d) { return d.expression.getText().startsWith("serializable"); })) !== null && _a !== void 0 ? _a : false;
146
+ };
147
+ Compiler.prototype.visitAccessorDeclaration = function (node, writer) {
148
+ var _a, _b;
149
+ // Only emit if the accessor has a @serializable() decorator
150
+ if (!this.hasSerializableDecorator(node))
151
+ return;
152
+ var name = node.name.getText();
153
+ // Deduplicate: if both getter and setter are decorated, only emit once
154
+ if (this._emittedAccessors.has(name))
155
+ return;
156
+ this._emittedAccessors.add(name);
157
+ var type;
158
+ var typeNode;
159
+ if (ts.isGetAccessorDeclaration(node)) {
160
+ typeNode = node.type;
161
+ }
162
+ else {
163
+ // Setter: get type from the first parameter
164
+ typeNode = (_b = (_a = node.parameters) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.type;
165
+ }
166
+ type = this.resolveType(typeNode, writer);
167
+ this.debugLog("[COMPILER] ACCESSOR (serializable)", name, type);
168
+ if (!type)
169
+ return;
170
+ var isArray = typeNode ? this.isArrayType(typeNode) : false;
171
+ var visibility = this.getVisibility(node);
172
+ writer.writeMember(visibility, name, isArray, type, undefined, this.getComments(node));
173
+ };
143
174
  Compiler.prototype.visitMethodDeclaration = function (node, writer) {
144
175
  var _a;
145
176
  var name = node.name.getText();
@@ -52,6 +52,5 @@ export interface IWriter {
52
52
  writeMethod(visibility: Visibility, name: string, returnType: string | undefined, args: Argument[], comments: string[]): void;
53
53
  writeNewTypeExpression(typeName: string, args?: string[]): void;
54
54
  registerEnum(name: string, members: EnumMember[]): void;
55
- writeEnum(name: string, members: EnumMember[], comments?: string[]): void;
56
55
  }
57
56
  export declare function runFromFile(writer: IWriter, path: string): Compiler;
@@ -1,9 +1,6 @@
1
1
  import { Argument, Visibility } from "../base-compiler";
2
2
  import { BaseWriter } from "../BaseWriter";
3
3
  export declare class CSharpWriter extends BaseWriter {
4
- /** Buffered enum outputs — flushed after all classes in end() */
5
- private _pendingEnums;
6
- end(filePath: string | null): void;
7
4
  resolveCSharpTypeName(typescriptTypeName: string): string | void;
8
5
  /** Tries to resolve a C# type name; returns undefined if the type is not known.
9
6
  * Checks TYPE_MAP keys/values and the enum registry. */
@@ -13,7 +10,6 @@ export declare class CSharpWriter extends BaseWriter {
13
10
  writeMember(visibility: Visibility, name: string, isArray: boolean, type: string, initialValue?: string, comments?: string[]): void;
14
11
  writeMethod(visibility: Visibility, name: string, returnType: string, args: Argument[], comments: string[]): void;
15
12
  writeNewTypeExpression(typeName: string, args?: string[]): void;
16
- writeEnum(name: string, members: import("../base-compiler").EnumMember[], comments?: string[]): void;
17
13
  /** Converts camelCase to PascalCase for method names */
18
14
  private toPascalCase;
19
15
  /** Resolve a "new Type(args)" expression: map TS types to C# qualified types */
@@ -123,20 +123,8 @@ function isEditorType(typeName) {
123
123
  var CSharpWriter = /** @class */ (function (_super) {
124
124
  __extends(CSharpWriter, _super);
125
125
  function CSharpWriter() {
126
- var _this = _super !== null && _super.apply(this, arguments) || this;
127
- /** Buffered enum outputs — flushed after all classes in end() */
128
- _this._pendingEnums = [];
129
- return _this;
126
+ return _super !== null && _super.apply(this, arguments) || this;
130
127
  }
131
- CSharpWriter.prototype.end = function (filePath) {
132
- // Flush buffered enums AFTER all class outputs
133
- for (var _i = 0, _a = this._pendingEnums; _i < _a.length; _i++) {
134
- var pending = _a[_i];
135
- this.sink.flush(pending.name + ".cs", pending.content);
136
- }
137
- this._pendingEnums.length = 0;
138
- _super.prototype.end.call(this, filePath);
139
- };
140
128
  CSharpWriter.prototype.resolveCSharpTypeName = function (typescriptTypeName) {
141
129
  var _a, _b;
142
130
  if (!typescriptTypeName)
@@ -335,29 +323,6 @@ var CSharpWriter = /** @class */ (function (_super) {
335
323
  CSharpWriter.prototype.writeNewTypeExpression = function (typeName, args) {
336
324
  // no-op for C# output
337
325
  };
338
- CSharpWriter.prototype.writeEnum = function (name, members, comments) {
339
- // @dont-generate-enum → skip
340
- if (comments === null || comments === void 0 ? void 0 : comments.some(function (c) { return c.startsWith("@dont-generate-enum"); }))
341
- return;
342
- // PascalCase: ensure first letter is uppercase
343
- var pascalName = name.charAt(0).toUpperCase() + name.slice(1);
344
- this.writer.beginBlock("namespace Needle.Typescript.GeneratedComponents\n{");
345
- this.writer.beginBlock("public enum ".concat(pascalName, "\n{"));
346
- for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
347
- var member = members_1[_i];
348
- if (typeof member.value === "string") {
349
- // String enums can't have values in C# — emit name only
350
- this.writer.writeLine("".concat(member.name, ","));
351
- }
352
- else {
353
- this.writer.writeLine("".concat(member.name, " = ").concat(member.value, ","));
354
- }
355
- }
356
- this.writer.endBlock("}");
357
- this.writer.endBlock("}");
358
- // Buffer the output — flush after all classes in end()
359
- this._pendingEnums.push({ name: pascalName, content: this.writer.flush() });
360
- };
361
326
  // ── Helpers ────────────────────────────────────────────────────────────
362
327
  /** Converts camelCase to PascalCase for method names */
363
328
  CSharpWriter.prototype.toPascalCase = function (name) {
@@ -17,5 +17,4 @@ export declare class ReactThreeFiberCompiler implements IWriter {
17
17
  }[], comments: string[]): void;
18
18
  writeNewTypeExpression(typeName: string, args?: string[]): void;
19
19
  registerEnum(name: string, members: import("../base-compiler").EnumMember[]): void;
20
- writeEnum(name: string, members: import("../base-compiler").EnumMember[], comments?: string[]): void;
21
20
  }
@@ -31,8 +31,6 @@ var ReactThreeFiberCompiler = /** @class */ (function () {
31
31
  };
32
32
  ReactThreeFiberCompiler.prototype.registerEnum = function (name, members) {
33
33
  };
34
- ReactThreeFiberCompiler.prototype.writeEnum = function (name, members, comments) {
35
- };
36
34
  return ReactThreeFiberCompiler;
37
35
  }());
38
36
  exports.ReactThreeFiberCompiler = ReactThreeFiberCompiler;
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "@needle-tools/needle-component-compiler",
3
- "version": "3.0.3-f6b855c",
3
+ "version": "3.0.4-9debd7d",
4
4
  "description": "Compile Editor components for Needle Engine for C# and Blender",
5
5
  "main": "dist/index.js",
6
- "bin": {
7
- "needle-component-compiler": "dist/cli.js"
8
- },
6
+ "bin": "dist/cli.js",
9
7
  "scripts": {
10
- "tsc": "tsc",
8
+ "tsc": "tsc -p tsconfig.build.json",
11
9
  "dev": "npm-watch compile",
12
- "compile": "tsc",
10
+ "compile": "tsc -p tsconfig.build.json",
13
11
  "prepublishOnly": "npm run compile",
14
12
  "test": "npm run test:csharp && npm run test:blender",
15
13
  "test:csharp": "mocha -r ts-node/register 'test/csharp/**/*.test.ts'",
@@ -28,7 +26,7 @@
28
26
  },
29
27
  "devDependencies": {
30
28
  "@types/chai": "^4.3.3",
31
- "@types/mocha": "^9.1.1",
29
+ "@types/mocha": "^10",
32
30
  "@types/node": "^18.7.18",
33
31
  "chai": "^4.3.6",
34
32
  "mocha": "^10.0.0",