breeze-bindgen 1.1.34 → 1.1.35

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.mjs CHANGED
@@ -152,6 +152,8 @@ var CTypeParser = class {
152
152
  const ignoreTypes = ["std.variant", "std.shared_ptr", "std.function"];
153
153
  if (ignoreTypes.includes(node.type)) {
154
154
  tsBasicType = node.argsTemplate.map((a) => this.formatToTypeScript(a, namespace)).join(" | ");
155
+ } else if (node.type === "qjs.rest") {
156
+ tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)}[]`;
155
157
  } else if (node.type === "std.optional") {
156
158
  tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)} | undefined`;
157
159
  } else if (node.type === "std.pair" || node.type === "std.tuple") {
@@ -228,6 +230,15 @@ function processAstAndGenerateCode(astArr, originalCppFilePath, nameFilter, addi
228
230
  const origFileContent = readFileSync(originalCppFilePath, "utf-8").split("\n").map((v) => v.trim());
229
231
  const structNames = [];
230
232
  const enumNames = [];
233
+ const formatTsParam = (cppType, name, ns) => {
234
+ const restMatch = cppType.match(/^(?:qjs::)?rest<(.+)>$/);
235
+ if (restMatch) {
236
+ const innerTs = cTypeToTypeScript(restMatch[1], ns);
237
+ return `...${name}: ${innerTs}[]`;
238
+ }
239
+ const isOpt = cppType.startsWith("std::optional");
240
+ return `${name}${isOpt ? "?" : ""}: ${cTypeToTypeScript(cppType, ns)}`;
241
+ };
231
242
  const resolveUnderPath = (path, resolveName) => {
232
243
  const ns = path.join("::");
233
244
  const fullName = `${ns}::${resolveName}`;
@@ -271,6 +282,7 @@ declare module '${tsModuleName}' {
271
282
  access: base.access,
272
283
  type: ctypeToQualified(base.type.qualType, path)
273
284
  })) || [];
285
+ const ctors = [];
274
286
  if (!node_struct.inner) return;
275
287
  for (const node of node_struct.inner) {
276
288
  if (node.name?.startsWith("$")) continue;
@@ -316,6 +328,20 @@ declare module '${tsModuleName}' {
316
328
  }
317
329
  comment = comment.trim();
318
330
  }
331
+ if (node.kind === "CXXConstructorDecl") {
332
+ if (node.implicit || node.explicitlyDeleted) continue;
333
+ const parsed = parseFunctionQualType(node.type.qualType);
334
+ const argNames = [];
335
+ if (node.inner) {
336
+ for (const arg of node.inner) {
337
+ if (arg.kind === "ParmVarDecl") argNames.push(arg.name);
338
+ }
339
+ }
340
+ ctors.push({
341
+ args: parsed.args.map((arg) => ctypeToQualified(arg, [...path, node_struct.name])),
342
+ argNames
343
+ });
344
+ }
319
345
  if (node.kind === "FieldDecl") {
320
346
  fields.push({
321
347
  name: node.name,
@@ -405,8 +431,18 @@ template <> struct qjs::js_traits<${fullName}> {
405
431
  binding += `
406
432
  template<> struct js_bind<${fullName}> {
407
433
  static void bind(qjs::Context::Module &mod) {
408
- mod.class_<${fullName}>("${jsNamespaceName}")
434
+ mod.class_<${fullName}>("${jsNamespaceName}")`;
435
+ if (ctors.length > 1) {
436
+ warn(`Class "${fullName}" has ${ctors.length} constructors. Only the first will be bound.`);
437
+ }
438
+ const ctor = ctors[0];
439
+ if (ctor && ctor.args.length > 0) {
440
+ binding += `
441
+ .constructor<${ctor.args.join(", ")}>()`;
442
+ } else {
443
+ binding += `
409
444
  .constructor<>()`;
445
+ }
410
446
  if (bases.length > 0) {
411
447
  binding += `
412
448
  .base<${bases[0].type}>()`;
@@ -470,6 +506,13 @@ template<> struct js_bind<${fullName}> {
470
506
  namespace ${tsNamespace} {`;
471
507
  typescriptDef += `
472
508
  export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) => base.type.split("::").pop() ?? base.type).join(", ")}` : ""} {`;
509
+ if (ctors.length > 0 && ctors[0].args.length > 0) {
510
+ const ctorArgs = ctors[0].args.map(
511
+ (arg, i) => formatTsParam(arg, ctors[0].argNames[i] || `arg${i}`, nameFilter)
512
+ ).join(", ");
513
+ typescriptDef += `
514
+ constructor(${ctorArgs});`;
515
+ }
473
516
  fields.forEach((field) => {
474
517
  let fieldDef = `${field.name}${field.type.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(field.type, nameFilter)}`;
475
518
  if (field.comment) {
@@ -518,7 +561,7 @@ export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) =>
518
561
  }
519
562
  methods.forEach((method) => {
520
563
  if (method.isGetter || method.isSetter) return;
521
- let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => `${method.argNames[i] || `arg${i}`}${arg.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(arg, nameFilter)}`).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
564
+ let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => formatTsParam(arg, method.argNames[i] || `arg${i}`, nameFilter)).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
522
565
  let comments = "";
523
566
  if (method.comment) comments += method.comment;
524
567
  if (comments || method.argNames && method.argNames.length > 0) {
package/dist/core.cjs CHANGED
@@ -362,6 +362,8 @@ var CTypeParser = class {
362
362
  const ignoreTypes = ["std.variant", "std.shared_ptr", "std.function"];
363
363
  if (ignoreTypes.includes(node.type)) {
364
364
  tsBasicType = node.argsTemplate.map((a) => this.formatToTypeScript(a, namespace)).join(" | ");
365
+ } else if (node.type === "qjs.rest") {
366
+ tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)}[]`;
365
367
  } else if (node.type === "std.optional") {
366
368
  tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)} | undefined`;
367
369
  } else if (node.type === "std.pair" || node.type === "std.tuple") {
@@ -438,6 +440,15 @@ function processAstAndGenerateCode(astArr, originalCppFilePath, nameFilter, addi
438
440
  const origFileContent = (0, import_node_fs.readFileSync)(originalCppFilePath, "utf-8").split("\n").map((v) => v.trim());
439
441
  const structNames = [];
440
442
  const enumNames = [];
443
+ const formatTsParam = (cppType, name, ns) => {
444
+ const restMatch = cppType.match(/^(?:qjs::)?rest<(.+)>$/);
445
+ if (restMatch) {
446
+ const innerTs = cTypeToTypeScript(restMatch[1], ns);
447
+ return `...${name}: ${innerTs}[]`;
448
+ }
449
+ const isOpt = cppType.startsWith("std::optional");
450
+ return `${name}${isOpt ? "?" : ""}: ${cTypeToTypeScript(cppType, ns)}`;
451
+ };
441
452
  const resolveUnderPath = (path, resolveName) => {
442
453
  const ns = path.join("::");
443
454
  const fullName = `${ns}::${resolveName}`;
@@ -481,6 +492,7 @@ declare module '${tsModuleName}' {
481
492
  access: base.access,
482
493
  type: ctypeToQualified(base.type.qualType, path)
483
494
  })) || [];
495
+ const ctors = [];
484
496
  if (!node_struct.inner) return;
485
497
  for (const node of node_struct.inner) {
486
498
  if (node.name?.startsWith("$")) continue;
@@ -526,6 +538,20 @@ declare module '${tsModuleName}' {
526
538
  }
527
539
  comment = comment.trim();
528
540
  }
541
+ if (node.kind === "CXXConstructorDecl") {
542
+ if (node.implicit || node.explicitlyDeleted) continue;
543
+ const parsed = parseFunctionQualType(node.type.qualType);
544
+ const argNames = [];
545
+ if (node.inner) {
546
+ for (const arg of node.inner) {
547
+ if (arg.kind === "ParmVarDecl") argNames.push(arg.name);
548
+ }
549
+ }
550
+ ctors.push({
551
+ args: parsed.args.map((arg) => ctypeToQualified(arg, [...path, node_struct.name])),
552
+ argNames
553
+ });
554
+ }
529
555
  if (node.kind === "FieldDecl") {
530
556
  fields.push({
531
557
  name: node.name,
@@ -615,8 +641,18 @@ template <> struct qjs::js_traits<${fullName}> {
615
641
  binding += `
616
642
  template<> struct js_bind<${fullName}> {
617
643
  static void bind(qjs::Context::Module &mod) {
618
- mod.class_<${fullName}>("${jsNamespaceName}")
644
+ mod.class_<${fullName}>("${jsNamespaceName}")`;
645
+ if (ctors.length > 1) {
646
+ (0, import_fancy_log.warn)(`Class "${fullName}" has ${ctors.length} constructors. Only the first will be bound.`);
647
+ }
648
+ const ctor = ctors[0];
649
+ if (ctor && ctor.args.length > 0) {
650
+ binding += `
651
+ .constructor<${ctor.args.join(", ")}>()`;
652
+ } else {
653
+ binding += `
619
654
  .constructor<>()`;
655
+ }
620
656
  if (bases.length > 0) {
621
657
  binding += `
622
658
  .base<${bases[0].type}>()`;
@@ -680,6 +716,13 @@ template<> struct js_bind<${fullName}> {
680
716
  namespace ${tsNamespace} {`;
681
717
  typescriptDef += `
682
718
  export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) => base.type.split("::").pop() ?? base.type).join(", ")}` : ""} {`;
719
+ if (ctors.length > 0 && ctors[0].args.length > 0) {
720
+ const ctorArgs = ctors[0].args.map(
721
+ (arg, i) => formatTsParam(arg, ctors[0].argNames[i] || `arg${i}`, nameFilter)
722
+ ).join(", ");
723
+ typescriptDef += `
724
+ constructor(${ctorArgs});`;
725
+ }
683
726
  fields.forEach((field) => {
684
727
  let fieldDef = `${field.name}${field.type.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(field.type, nameFilter)}`;
685
728
  if (field.comment) {
@@ -728,7 +771,7 @@ export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) =>
728
771
  }
729
772
  methods.forEach((method) => {
730
773
  if (method.isGetter || method.isSetter) return;
731
- let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => `${method.argNames[i] || `arg${i}`}${arg.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(arg, nameFilter)}`).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
774
+ let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => formatTsParam(arg, method.argNames[i] || `arg${i}`, nameFilter)).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
732
775
  let comments = "";
733
776
  if (method.comment) comments += method.comment;
734
777
  if (comments || method.argNames && method.argNames.length > 0) {
package/dist/core.mjs CHANGED
@@ -358,6 +358,8 @@ var CTypeParser = class {
358
358
  const ignoreTypes = ["std.variant", "std.shared_ptr", "std.function"];
359
359
  if (ignoreTypes.includes(node.type)) {
360
360
  tsBasicType = node.argsTemplate.map((a) => this.formatToTypeScript(a, namespace)).join(" | ");
361
+ } else if (node.type === "qjs.rest") {
362
+ tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)}[]`;
361
363
  } else if (node.type === "std.optional") {
362
364
  tsBasicType = `${this.formatToTypeScript(node.argsTemplate[0], namespace)} | undefined`;
363
365
  } else if (node.type === "std.pair" || node.type === "std.tuple") {
@@ -434,6 +436,15 @@ function processAstAndGenerateCode(astArr, originalCppFilePath, nameFilter, addi
434
436
  const origFileContent = readFileSync(originalCppFilePath, "utf-8").split("\n").map((v) => v.trim());
435
437
  const structNames = [];
436
438
  const enumNames = [];
439
+ const formatTsParam = (cppType, name, ns) => {
440
+ const restMatch = cppType.match(/^(?:qjs::)?rest<(.+)>$/);
441
+ if (restMatch) {
442
+ const innerTs = cTypeToTypeScript(restMatch[1], ns);
443
+ return `...${name}: ${innerTs}[]`;
444
+ }
445
+ const isOpt = cppType.startsWith("std::optional");
446
+ return `${name}${isOpt ? "?" : ""}: ${cTypeToTypeScript(cppType, ns)}`;
447
+ };
437
448
  const resolveUnderPath = (path, resolveName) => {
438
449
  const ns = path.join("::");
439
450
  const fullName = `${ns}::${resolveName}`;
@@ -477,6 +488,7 @@ declare module '${tsModuleName}' {
477
488
  access: base.access,
478
489
  type: ctypeToQualified(base.type.qualType, path)
479
490
  })) || [];
491
+ const ctors = [];
480
492
  if (!node_struct.inner) return;
481
493
  for (const node of node_struct.inner) {
482
494
  if (node.name?.startsWith("$")) continue;
@@ -522,6 +534,20 @@ declare module '${tsModuleName}' {
522
534
  }
523
535
  comment = comment.trim();
524
536
  }
537
+ if (node.kind === "CXXConstructorDecl") {
538
+ if (node.implicit || node.explicitlyDeleted) continue;
539
+ const parsed = parseFunctionQualType(node.type.qualType);
540
+ const argNames = [];
541
+ if (node.inner) {
542
+ for (const arg of node.inner) {
543
+ if (arg.kind === "ParmVarDecl") argNames.push(arg.name);
544
+ }
545
+ }
546
+ ctors.push({
547
+ args: parsed.args.map((arg) => ctypeToQualified(arg, [...path, node_struct.name])),
548
+ argNames
549
+ });
550
+ }
525
551
  if (node.kind === "FieldDecl") {
526
552
  fields.push({
527
553
  name: node.name,
@@ -611,8 +637,18 @@ template <> struct qjs::js_traits<${fullName}> {
611
637
  binding += `
612
638
  template<> struct js_bind<${fullName}> {
613
639
  static void bind(qjs::Context::Module &mod) {
614
- mod.class_<${fullName}>("${jsNamespaceName}")
640
+ mod.class_<${fullName}>("${jsNamespaceName}")`;
641
+ if (ctors.length > 1) {
642
+ (0, import_fancy_log.warn)(`Class "${fullName}" has ${ctors.length} constructors. Only the first will be bound.`);
643
+ }
644
+ const ctor = ctors[0];
645
+ if (ctor && ctor.args.length > 0) {
646
+ binding += `
647
+ .constructor<${ctor.args.join(", ")}>()`;
648
+ } else {
649
+ binding += `
615
650
  .constructor<>()`;
651
+ }
616
652
  if (bases.length > 0) {
617
653
  binding += `
618
654
  .base<${bases[0].type}>()`;
@@ -676,6 +712,13 @@ template<> struct js_bind<${fullName}> {
676
712
  namespace ${tsNamespace} {`;
677
713
  typescriptDef += `
678
714
  export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) => base.type.split("::").pop() ?? base.type).join(", ")}` : ""} {`;
715
+ if (ctors.length > 0 && ctors[0].args.length > 0) {
716
+ const ctorArgs = ctors[0].args.map(
717
+ (arg, i) => formatTsParam(arg, ctors[0].argNames[i] || `arg${i}`, nameFilter)
718
+ ).join(", ");
719
+ typescriptDef += `
720
+ constructor(${ctorArgs});`;
721
+ }
679
722
  fields.forEach((field) => {
680
723
  let fieldDef = `${field.name}${field.type.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(field.type, nameFilter)}`;
681
724
  if (field.comment) {
@@ -724,7 +767,7 @@ export class ${tsClassName}${bases.length > 0 ? ` extends ${bases.map((base) =>
724
767
  }
725
768
  methods.forEach((method) => {
726
769
  if (method.isGetter || method.isSetter) return;
727
- let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => `${method.argNames[i] || `arg${i}`}${arg.startsWith("std::optional") ? "?" : ""}: ${cTypeToTypeScript(arg, nameFilter)}`).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
770
+ let methodDef = `${method.static ? "static " : ""}${method.name}(${method.argNames && method.argNames.length > 0 ? method.args.map((arg, i) => formatTsParam(arg, method.argNames[i] || `arg${i}`, nameFilter)).join(", ") : ""}): ${cTypeToTypeScript(method.returnType, nameFilter)}`;
728
771
  let comments = "";
729
772
  if (method.comment) comments += method.comment;
730
773
  if (comments || method.argNames && method.argNames.length > 0) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
3
3
  "name": "breeze-bindgen",
4
- "version": "1.1.34",
4
+ "version": "1.1.35",
5
5
  "main": "dist/core.cjs",
6
6
  "module": "dist/core.mjs",
7
7
  "types": "dist/core.d.ts",