@atscript/typescript 0.0.32 → 0.1.1

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.cjs CHANGED
@@ -153,6 +153,7 @@ var BaseRenderer = class extends CodePrinter {
153
153
  }
154
154
  renderInterface(node) {}
155
155
  renderType(node) {}
156
+ renderAnnotate(node) {}
156
157
  transformFromPath(path$3) {
157
158
  return `${path$3}.as`;
158
159
  }
@@ -187,6 +188,10 @@ var BaseRenderer = class extends CodePrinter {
187
188
  this.renderImport(node);
188
189
  break;
189
190
  }
191
+ case "annotate": {
192
+ this.renderAnnotate(node);
193
+ break;
194
+ }
190
195
  default: break;
191
196
  }
192
197
  }
@@ -346,6 +351,26 @@ else this.writeln("{}");
346
351
  this.writeln();
347
352
  this.renderTypeNamespace(node);
348
353
  }
354
+ renderAnnotate(node) {
355
+ if (node.isMutating) return;
356
+ const targetName = node.targetName;
357
+ const unwound = this.doc.unwindType(targetName);
358
+ if (!unwound?.def) return;
359
+ const def = this.doc.mergeIntersection(unwound.def);
360
+ this.writeln();
361
+ const exported = node.token("export")?.text === "export";
362
+ this.renderJsDoc(node);
363
+ if ((0, __atscript_core.isStructure)(def) || (0, __atscript_core.isInterface)(def)) {
364
+ this.write(exported ? "export declare " : "declare ");
365
+ this.write(`class ${node.id} `);
366
+ this.renderStructure(def, node.id);
367
+ } else {
368
+ this.write(exported ? "export " : "declare ");
369
+ this.write(`type ${node.id} = `);
370
+ this.renderTypeDef(def);
371
+ }
372
+ this.writeln();
373
+ }
349
374
  renderTypeNamespace(node) {
350
375
  this.write(`declare namespace ${node.id} `);
351
376
  this.blockln("{}");
@@ -947,36 +972,58 @@ var JsRenderer = class extends BaseRenderer {
947
972
  if (!this.opts?.preRenderJsonSchema) imports.push("buildJsonSchema as $$");
948
973
  this.writeln(`import { ${imports.join(", ")} } from "@atscript/typescript/utils"`);
949
974
  }
975
+ buildAdHocMap(annotateNodes) {
976
+ const map = new Map();
977
+ for (const annotateNode of annotateNodes) for (const entry of annotateNode.entries) {
978
+ const path$3 = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)].join(".") : entry.id;
979
+ const anns = entry.annotations || [];
980
+ if (anns.length > 0) {
981
+ const existing = map.get(path$3);
982
+ map.set(path$3, existing ? [...existing, ...anns] : anns);
983
+ }
984
+ }
985
+ return map.size > 0 ? map : null;
986
+ }
950
987
  post() {
951
- for (const node of this.postAnnotate) {
988
+ for (const node of this.postAnnotate) if (node.entity === "annotate") {
989
+ const annotateNode = node;
990
+ const unwound = this.doc.unwindType(annotateNode.targetName);
991
+ if (unwound?.def) {
992
+ let def = this.doc.mergeIntersection(unwound.def);
993
+ if ((0, __atscript_core.isInterface)(def)) def = def.getDefinition() || def;
994
+ this._adHocAnnotations = this.buildAdHocMap([annotateNode]);
995
+ this.annotateType(def, node.id);
996
+ this._adHocAnnotations = null;
997
+ this.indent();
998
+ this.defineMetadataForAnnotateAlias(annotateNode);
999
+ this.unindent();
1000
+ this.writeln();
1001
+ }
1002
+ } else {
1003
+ const mutatingNodes = this.doc.getAnnotateNodesFor(node.id).filter((n) => n.isMutating);
1004
+ this._adHocAnnotations = this.buildAdHocMap(mutatingNodes);
952
1005
  this.annotateType(node.getDefinition(), node.id);
1006
+ this._adHocAnnotations = null;
953
1007
  this.indent().defineMetadata(node).unindent();
954
1008
  this.writeln();
955
1009
  }
1010
+ this.renderMutatingAnnotates();
956
1011
  this.writeln("// prettier-ignore-end");
957
1012
  super.post();
958
1013
  }
1014
+ renderClassStatics(node) {
1015
+ this.writeln("static __is_atscript_annotated_type = true");
1016
+ this.writeln("static type = {}");
1017
+ this.writeln("static metadata = new Map()");
1018
+ this.renderJsonSchemaMethod(node);
1019
+ }
959
1020
  renderInterface(node) {
960
1021
  this.writeln();
961
1022
  const exported = node.token("export")?.text === "export";
962
1023
  this.write(exported ? "export " : "");
963
1024
  this.write(`class ${node.id} `);
964
1025
  this.blockln("{}");
965
- this.writeln("static __is_atscript_annotated_type = true");
966
- this.writeln("static type = {}");
967
- this.writeln("static metadata = new Map()");
968
- if (this.opts?.preRenderJsonSchema) {
969
- const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
970
- this.writeln(`static _jsonSchema = ${schema}`);
971
- this.writeln("static toJsonSchema() {");
972
- this.indent().writeln("return this._jsonSchema").unindent();
973
- this.writeln("}");
974
- } else {
975
- this.writeln("static _jsonSchema");
976
- this.writeln("static toJsonSchema() {");
977
- this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
978
- this.writeln("}");
979
- }
1026
+ this.renderClassStatics(node);
980
1027
  this.popln();
981
1028
  this.postAnnotate.push(node);
982
1029
  this.writeln();
@@ -987,24 +1034,40 @@ var JsRenderer = class extends BaseRenderer {
987
1034
  this.write(exported ? "export " : "");
988
1035
  this.write(`class ${node.id} `);
989
1036
  this.blockln("{}");
990
- this.writeln("static __is_atscript_annotated_type = true");
991
- this.writeln("static type = {}");
992
- this.writeln("static metadata = new Map()");
1037
+ this.renderClassStatics(node);
1038
+ this.popln();
1039
+ this.postAnnotate.push(node);
1040
+ this.writeln();
1041
+ }
1042
+ renderAnnotate(node) {
1043
+ if (node.isMutating) {
1044
+ this.mutatingAnnotates.push(node);
1045
+ return;
1046
+ }
1047
+ const targetName = node.targetName;
1048
+ const unwound = this.doc.unwindType(targetName);
1049
+ if (!unwound?.def) return;
1050
+ this.writeln();
1051
+ const exported = node.token("export")?.text === "export";
1052
+ this.write(exported ? "export " : "");
1053
+ this.write(`class ${node.id} `);
1054
+ this.blockln("{}");
1055
+ this.renderClassStatics(node);
1056
+ this.popln();
1057
+ this.postAnnotate.push(node);
1058
+ this.writeln();
1059
+ }
1060
+ renderJsonSchemaMethod(node) {
993
1061
  if (this.opts?.preRenderJsonSchema) {
994
1062
  const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
995
- this.writeln(`static _jsonSchema = ${schema}`);
996
1063
  this.writeln("static toJsonSchema() {");
997
- this.indent().writeln("return this._jsonSchema").unindent();
1064
+ this.indent().writeln(`return ${schema}`).unindent();
998
1065
  this.writeln("}");
999
1066
  } else {
1000
- this.writeln("static _jsonSchema");
1001
1067
  this.writeln("static toJsonSchema() {");
1002
1068
  this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
1003
1069
  this.writeln("}");
1004
1070
  }
1005
- this.popln();
1006
- this.postAnnotate.push(node);
1007
- this.writeln();
1008
1071
  }
1009
1072
  toAnnotatedType(node) {
1010
1073
  return this.toAnnotatedHandle(node).$type;
@@ -1235,6 +1298,7 @@ else handle.prop(prop.id, propHandle.$type);
1235
1298
  for (const prop of props) {
1236
1299
  const pattern = prop.token("identifier")?.pattern;
1237
1300
  const optional = !!prop.token("optional");
1301
+ this._propPath.push(prop.id);
1238
1302
  if (pattern) {
1239
1303
  this.writeln(`.propPattern(`);
1240
1304
  this.indent();
@@ -1250,6 +1314,7 @@ else handle.prop(prop.id, propHandle.$type);
1250
1314
  this.writeln(" .$type");
1251
1315
  this.unindent();
1252
1316
  this.write(`)`);
1317
+ this._propPath.pop();
1253
1318
  }
1254
1319
  this.writeln();
1255
1320
  return this;
@@ -1265,12 +1330,43 @@ else handle.prop(prop.id, propHandle.$type);
1265
1330
  }
1266
1331
  defineMetadata(node) {
1267
1332
  const annotations = this.doc.evalAnnotationsForNode(node);
1333
+ let adHocNames;
1334
+ let adHoc;
1335
+ if (this._adHocAnnotations && this._propPath.length > 0) {
1336
+ const path$3 = this._propPath.join(".");
1337
+ adHoc = this._adHocAnnotations.get(path$3);
1338
+ if (adHoc) adHocNames = new Set(adHoc.map((a) => a.name));
1339
+ }
1268
1340
  annotations?.forEach((an) => {
1341
+ if (!adHocNames || !adHocNames.has(an.name)) this.resolveAnnotationValue(node, an);
1342
+ });
1343
+ adHoc?.forEach((an) => {
1269
1344
  this.resolveAnnotationValue(node, an);
1270
1345
  });
1271
1346
  return this;
1272
1347
  }
1348
+ /**
1349
+ * For non-mutating annotate aliases: merge the target's type-level annotations
1350
+ * with the annotate block's own annotations (annotate's take priority).
1351
+ */ defineMetadataForAnnotateAlias(annotateNode) {
1352
+ const annotateAnnotations = this.doc.evalAnnotationsForNode(annotateNode);
1353
+ const targetDecl = this.doc.getDeclarationOwnerNode(annotateNode.targetName);
1354
+ const targetAnnotations = targetDecl?.node ? targetDecl.doc.evalAnnotationsForNode(targetDecl.node) : undefined;
1355
+ const overriddenNames = new Set(annotateAnnotations?.map((a) => a.name));
1356
+ targetAnnotations?.forEach((an) => {
1357
+ if (!overriddenNames.has(an.name)) this.resolveAnnotationValue(annotateNode, an);
1358
+ });
1359
+ annotateAnnotations?.forEach((an) => {
1360
+ this.resolveAnnotationValue(annotateNode, an);
1361
+ });
1362
+ return this;
1363
+ }
1273
1364
  resolveAnnotationValue(node, an) {
1365
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1366
+ if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value}, true)`);
1367
+ else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
1368
+ }
1369
+ computeAnnotationValue(node, an) {
1274
1370
  const spec = this.doc.resolveAnnotation(an.name);
1275
1371
  let targetValue = "true";
1276
1372
  let multiple = false;
@@ -1282,7 +1378,6 @@ else handle.prop(prop.id, propHandle.$type);
1282
1378
  let i = 0;
1283
1379
  for (const aSpec of spec.arguments) {
1284
1380
  if (an.args[i]) targetValue += `${wrapProp(aSpec.name)}: ${aSpec.type === "string" ? `"${escapeQuotes(an.args[i]?.text)}"` : an.args[i]?.text}${i === length - 1 ? "" : ", "} `;
1285
- else {}
1286
1381
  i++;
1287
1382
  }
1288
1383
  targetValue += "}";
@@ -1295,11 +1390,52 @@ else targetValue = "true";
1295
1390
  multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
1296
1391
  if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
1297
1392
  }
1298
- if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue}, true)`);
1299
- else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue})`);
1393
+ return {
1394
+ value: targetValue,
1395
+ multiple: !!multiple
1396
+ };
1397
+ }
1398
+ renderMutatingAnnotates() {
1399
+ for (const node of this.mutatingAnnotates) {
1400
+ const targetName = node.targetName;
1401
+ for (const entry of node.entries) {
1402
+ const anns = entry.annotations;
1403
+ if (!anns || anns.length === 0) continue;
1404
+ const parts = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)] : [entry.id];
1405
+ let accessor = targetName;
1406
+ for (const part of parts) accessor += `.type.props.get("${escapeQuotes(part)}")?`;
1407
+ for (const an of anns) {
1408
+ const { value, multiple } = this.computeAnnotationValue(entry, an);
1409
+ if (multiple) {
1410
+ this.writeln(`{`);
1411
+ this.indent();
1412
+ this.writeln(`const __t = ${accessor}.metadata`);
1413
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1414
+ this.writeln(`const __v = ${value}`);
1415
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1416
+ this.unindent();
1417
+ this.writeln(`}`);
1418
+ } else this.writeln(`${accessor}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1419
+ }
1420
+ }
1421
+ const topAnnotations = node.annotations;
1422
+ if (topAnnotations && topAnnotations.length > 0) for (const an of topAnnotations) {
1423
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1424
+ if (multiple) {
1425
+ this.writeln(`{`);
1426
+ this.indent();
1427
+ this.writeln(`const __t = ${targetName}.metadata`);
1428
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1429
+ this.writeln(`const __v = ${value}`);
1430
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1431
+ this.unindent();
1432
+ this.writeln(`}`);
1433
+ } else this.writeln(`${targetName}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1434
+ }
1435
+ }
1300
1436
  }
1301
1437
  constructor(doc, opts) {
1302
- super(doc), _define_property$1(this, "opts", void 0), _define_property$1(this, "postAnnotate", void 0), this.opts = opts, this.postAnnotate = [];
1438
+ super(doc), _define_property$1(this, "opts", void 0), _define_property$1(this, "postAnnotate", void 0), _define_property$1(this, "mutatingAnnotates", void 0), _define_property$1(this, "_adHocAnnotations", void 0), _define_property$1(this, "_propPath", void 0), this.opts = opts, this.postAnnotate = [], this.mutatingAnnotates = [], this._adHocAnnotations = null, this._propPath = [];
1303
1439
  }
1304
1440
  };
1305
1441
 
@@ -1370,13 +1506,35 @@ function _ts_param(paramIndex, decorator) {
1370
1506
  };
1371
1507
  }
1372
1508
  var Commands = class {
1373
- async default(configFile, format) {
1509
+ async default(configFile, format, noEmit, skipDiag) {
1374
1510
  const config = await this.getConfig(configFile);
1375
1511
  if (format) config.format = format;
1376
1512
  this.logger.log(`Format: ${"\x1B[36m"}${config.format}${"\x1B[39m"}`);
1377
1513
  const builder = await (0, __atscript_core.build)(config);
1378
- const out = await builder.write(config);
1379
- for (const { target } of out) this.logger.log(`✅ created ${"\x1B[32m"}${target}${"\x1B[39m"}`);
1514
+ let errorCount = 0;
1515
+ let warningCount = 0;
1516
+ if (!skipDiag) {
1517
+ const diagMap = await builder.diagnostics();
1518
+ for (const [docId, messages] of diagMap) {
1519
+ const doc = builder.getDoc(docId);
1520
+ for (const m of messages) {
1521
+ if (m.severity === 1) errorCount++;
1522
+ else if (m.severity === 2) warningCount++;
1523
+ if (doc) this.logger.log(doc.renderDiagMessage(m, true, true));
1524
+ }
1525
+ }
1526
+ }
1527
+ if (!noEmit) {
1528
+ const out = await builder.write(config);
1529
+ for (const { target } of out) this.logger.log(`✅ created ${"\x1B[32m"}${target}${"\x1B[39m"}`);
1530
+ }
1531
+ if (errorCount > 0 || warningCount > 0) {
1532
+ const parts = [];
1533
+ if (errorCount > 0) parts.push(`${"\x1B[31m"}${errorCount} error${errorCount > 1 ? "s" : ""}${"\x1B[39m"}`);
1534
+ if (warningCount > 0) parts.push(`${"\x1B[33m"}${warningCount} warning${warningCount > 1 ? "s" : ""}${"\x1B[39m"}`);
1535
+ this.logger.log(`\nFound ${parts.join(" and ")}`);
1536
+ }
1537
+ if (errorCount > 0) process.exit(1);
1380
1538
  }
1381
1539
  async getConfig(configFile) {
1382
1540
  const root = process.cwd();
@@ -1411,14 +1569,27 @@ _ts_decorate([
1411
1569
  (0, moost.Description)("Builds .as files using --config and --format"),
1412
1570
  (0, __moostjs_event_cli.CliExample)("-c atscript.config.js", "Build .as files using atscript.config.js"),
1413
1571
  (0, __moostjs_event_cli.CliExample)("-f dts", "Build \"d.ts\" files for \".as\" files"),
1572
+ (0, __moostjs_event_cli.CliExample)("--noEmit", "Only check for errors, do not emit files"),
1573
+ (0, __moostjs_event_cli.CliExample)("--skipDiag", "Emit files without running diagnostics"),
1414
1574
  _ts_param(0, (0, __moostjs_event_cli.CliOption)("c", "config")),
1415
1575
  _ts_param(0, (0, moost.Optional)()),
1416
1576
  _ts_param(0, (0, moost.Description)("Path to config file")),
1417
1577
  _ts_param(1, (0, __moostjs_event_cli.CliOption)("f", "format")),
1418
1578
  _ts_param(1, (0, moost.Optional)()),
1419
1579
  _ts_param(1, (0, moost.Description)("Output format (js|dts), default: \"dts\"")),
1580
+ _ts_param(2, (0, __moostjs_event_cli.CliOption)("noEmit")),
1581
+ _ts_param(2, (0, moost.Optional)()),
1582
+ _ts_param(2, (0, moost.Description)("Only run diagnostics without emitting files")),
1583
+ _ts_param(3, (0, __moostjs_event_cli.CliOption)("skipDiag")),
1584
+ _ts_param(3, (0, moost.Optional)()),
1585
+ _ts_param(3, (0, moost.Description)("Skip diagnostics and always emit files")),
1420
1586
  _ts_metadata("design:type", Function),
1421
- _ts_metadata("design:paramtypes", [String, String]),
1587
+ _ts_metadata("design:paramtypes", [
1588
+ String,
1589
+ String,
1590
+ Boolean,
1591
+ Boolean
1592
+ ]),
1422
1593
  _ts_metadata("design:returntype", Promise)
1423
1594
  ], Commands.prototype, "default", null);
1424
1595
  Commands = _ts_decorate([
package/dist/index.cjs CHANGED
@@ -150,6 +150,7 @@ var BaseRenderer = class extends CodePrinter {
150
150
  }
151
151
  renderInterface(node) {}
152
152
  renderType(node) {}
153
+ renderAnnotate(node) {}
153
154
  transformFromPath(path$2) {
154
155
  return `${path$2}.as`;
155
156
  }
@@ -184,6 +185,10 @@ var BaseRenderer = class extends CodePrinter {
184
185
  this.renderImport(node);
185
186
  break;
186
187
  }
188
+ case "annotate": {
189
+ this.renderAnnotate(node);
190
+ break;
191
+ }
187
192
  default: break;
188
193
  }
189
194
  }
@@ -343,6 +348,26 @@ else this.writeln("{}");
343
348
  this.writeln();
344
349
  this.renderTypeNamespace(node);
345
350
  }
351
+ renderAnnotate(node) {
352
+ if (node.isMutating) return;
353
+ const targetName = node.targetName;
354
+ const unwound = this.doc.unwindType(targetName);
355
+ if (!unwound?.def) return;
356
+ const def = this.doc.mergeIntersection(unwound.def);
357
+ this.writeln();
358
+ const exported = node.token("export")?.text === "export";
359
+ this.renderJsDoc(node);
360
+ if ((0, __atscript_core.isStructure)(def) || (0, __atscript_core.isInterface)(def)) {
361
+ this.write(exported ? "export declare " : "declare ");
362
+ this.write(`class ${node.id} `);
363
+ this.renderStructure(def, node.id);
364
+ } else {
365
+ this.write(exported ? "export " : "declare ");
366
+ this.write(`type ${node.id} = `);
367
+ this.renderTypeDef(def);
368
+ }
369
+ this.writeln();
370
+ }
346
371
  renderTypeNamespace(node) {
347
372
  this.write(`declare namespace ${node.id} `);
348
373
  this.blockln("{}");
@@ -944,36 +969,58 @@ var JsRenderer = class extends BaseRenderer {
944
969
  if (!this.opts?.preRenderJsonSchema) imports.push("buildJsonSchema as $$");
945
970
  this.writeln(`import { ${imports.join(", ")} } from "@atscript/typescript/utils"`);
946
971
  }
972
+ buildAdHocMap(annotateNodes) {
973
+ const map = new Map();
974
+ for (const annotateNode of annotateNodes) for (const entry of annotateNode.entries) {
975
+ const path$2 = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)].join(".") : entry.id;
976
+ const anns = entry.annotations || [];
977
+ if (anns.length > 0) {
978
+ const existing = map.get(path$2);
979
+ map.set(path$2, existing ? [...existing, ...anns] : anns);
980
+ }
981
+ }
982
+ return map.size > 0 ? map : null;
983
+ }
947
984
  post() {
948
- for (const node of this.postAnnotate) {
985
+ for (const node of this.postAnnotate) if (node.entity === "annotate") {
986
+ const annotateNode = node;
987
+ const unwound = this.doc.unwindType(annotateNode.targetName);
988
+ if (unwound?.def) {
989
+ let def = this.doc.mergeIntersection(unwound.def);
990
+ if ((0, __atscript_core.isInterface)(def)) def = def.getDefinition() || def;
991
+ this._adHocAnnotations = this.buildAdHocMap([annotateNode]);
992
+ this.annotateType(def, node.id);
993
+ this._adHocAnnotations = null;
994
+ this.indent();
995
+ this.defineMetadataForAnnotateAlias(annotateNode);
996
+ this.unindent();
997
+ this.writeln();
998
+ }
999
+ } else {
1000
+ const mutatingNodes = this.doc.getAnnotateNodesFor(node.id).filter((n) => n.isMutating);
1001
+ this._adHocAnnotations = this.buildAdHocMap(mutatingNodes);
949
1002
  this.annotateType(node.getDefinition(), node.id);
1003
+ this._adHocAnnotations = null;
950
1004
  this.indent().defineMetadata(node).unindent();
951
1005
  this.writeln();
952
1006
  }
1007
+ this.renderMutatingAnnotates();
953
1008
  this.writeln("// prettier-ignore-end");
954
1009
  super.post();
955
1010
  }
1011
+ renderClassStatics(node) {
1012
+ this.writeln("static __is_atscript_annotated_type = true");
1013
+ this.writeln("static type = {}");
1014
+ this.writeln("static metadata = new Map()");
1015
+ this.renderJsonSchemaMethod(node);
1016
+ }
956
1017
  renderInterface(node) {
957
1018
  this.writeln();
958
1019
  const exported = node.token("export")?.text === "export";
959
1020
  this.write(exported ? "export " : "");
960
1021
  this.write(`class ${node.id} `);
961
1022
  this.blockln("{}");
962
- this.writeln("static __is_atscript_annotated_type = true");
963
- this.writeln("static type = {}");
964
- this.writeln("static metadata = new Map()");
965
- if (this.opts?.preRenderJsonSchema) {
966
- const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
967
- this.writeln(`static _jsonSchema = ${schema}`);
968
- this.writeln("static toJsonSchema() {");
969
- this.indent().writeln("return this._jsonSchema").unindent();
970
- this.writeln("}");
971
- } else {
972
- this.writeln("static _jsonSchema");
973
- this.writeln("static toJsonSchema() {");
974
- this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
975
- this.writeln("}");
976
- }
1023
+ this.renderClassStatics(node);
977
1024
  this.popln();
978
1025
  this.postAnnotate.push(node);
979
1026
  this.writeln();
@@ -984,24 +1031,40 @@ var JsRenderer = class extends BaseRenderer {
984
1031
  this.write(exported ? "export " : "");
985
1032
  this.write(`class ${node.id} `);
986
1033
  this.blockln("{}");
987
- this.writeln("static __is_atscript_annotated_type = true");
988
- this.writeln("static type = {}");
989
- this.writeln("static metadata = new Map()");
1034
+ this.renderClassStatics(node);
1035
+ this.popln();
1036
+ this.postAnnotate.push(node);
1037
+ this.writeln();
1038
+ }
1039
+ renderAnnotate(node) {
1040
+ if (node.isMutating) {
1041
+ this.mutatingAnnotates.push(node);
1042
+ return;
1043
+ }
1044
+ const targetName = node.targetName;
1045
+ const unwound = this.doc.unwindType(targetName);
1046
+ if (!unwound?.def) return;
1047
+ this.writeln();
1048
+ const exported = node.token("export")?.text === "export";
1049
+ this.write(exported ? "export " : "");
1050
+ this.write(`class ${node.id} `);
1051
+ this.blockln("{}");
1052
+ this.renderClassStatics(node);
1053
+ this.popln();
1054
+ this.postAnnotate.push(node);
1055
+ this.writeln();
1056
+ }
1057
+ renderJsonSchemaMethod(node) {
990
1058
  if (this.opts?.preRenderJsonSchema) {
991
1059
  const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
992
- this.writeln(`static _jsonSchema = ${schema}`);
993
1060
  this.writeln("static toJsonSchema() {");
994
- this.indent().writeln("return this._jsonSchema").unindent();
1061
+ this.indent().writeln(`return ${schema}`).unindent();
995
1062
  this.writeln("}");
996
1063
  } else {
997
- this.writeln("static _jsonSchema");
998
1064
  this.writeln("static toJsonSchema() {");
999
1065
  this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
1000
1066
  this.writeln("}");
1001
1067
  }
1002
- this.popln();
1003
- this.postAnnotate.push(node);
1004
- this.writeln();
1005
1068
  }
1006
1069
  toAnnotatedType(node) {
1007
1070
  return this.toAnnotatedHandle(node).$type;
@@ -1232,6 +1295,7 @@ else handle.prop(prop.id, propHandle.$type);
1232
1295
  for (const prop of props) {
1233
1296
  const pattern = prop.token("identifier")?.pattern;
1234
1297
  const optional = !!prop.token("optional");
1298
+ this._propPath.push(prop.id);
1235
1299
  if (pattern) {
1236
1300
  this.writeln(`.propPattern(`);
1237
1301
  this.indent();
@@ -1247,6 +1311,7 @@ else handle.prop(prop.id, propHandle.$type);
1247
1311
  this.writeln(" .$type");
1248
1312
  this.unindent();
1249
1313
  this.write(`)`);
1314
+ this._propPath.pop();
1250
1315
  }
1251
1316
  this.writeln();
1252
1317
  return this;
@@ -1262,12 +1327,43 @@ else handle.prop(prop.id, propHandle.$type);
1262
1327
  }
1263
1328
  defineMetadata(node) {
1264
1329
  const annotations = this.doc.evalAnnotationsForNode(node);
1330
+ let adHocNames;
1331
+ let adHoc;
1332
+ if (this._adHocAnnotations && this._propPath.length > 0) {
1333
+ const path$2 = this._propPath.join(".");
1334
+ adHoc = this._adHocAnnotations.get(path$2);
1335
+ if (adHoc) adHocNames = new Set(adHoc.map((a) => a.name));
1336
+ }
1265
1337
  annotations?.forEach((an) => {
1338
+ if (!adHocNames || !adHocNames.has(an.name)) this.resolveAnnotationValue(node, an);
1339
+ });
1340
+ adHoc?.forEach((an) => {
1266
1341
  this.resolveAnnotationValue(node, an);
1267
1342
  });
1268
1343
  return this;
1269
1344
  }
1345
+ /**
1346
+ * For non-mutating annotate aliases: merge the target's type-level annotations
1347
+ * with the annotate block's own annotations (annotate's take priority).
1348
+ */ defineMetadataForAnnotateAlias(annotateNode) {
1349
+ const annotateAnnotations = this.doc.evalAnnotationsForNode(annotateNode);
1350
+ const targetDecl = this.doc.getDeclarationOwnerNode(annotateNode.targetName);
1351
+ const targetAnnotations = targetDecl?.node ? targetDecl.doc.evalAnnotationsForNode(targetDecl.node) : undefined;
1352
+ const overriddenNames = new Set(annotateAnnotations?.map((a) => a.name));
1353
+ targetAnnotations?.forEach((an) => {
1354
+ if (!overriddenNames.has(an.name)) this.resolveAnnotationValue(annotateNode, an);
1355
+ });
1356
+ annotateAnnotations?.forEach((an) => {
1357
+ this.resolveAnnotationValue(annotateNode, an);
1358
+ });
1359
+ return this;
1360
+ }
1270
1361
  resolveAnnotationValue(node, an) {
1362
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1363
+ if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value}, true)`);
1364
+ else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
1365
+ }
1366
+ computeAnnotationValue(node, an) {
1271
1367
  const spec = this.doc.resolveAnnotation(an.name);
1272
1368
  let targetValue = "true";
1273
1369
  let multiple = false;
@@ -1279,7 +1375,6 @@ else handle.prop(prop.id, propHandle.$type);
1279
1375
  let i = 0;
1280
1376
  for (const aSpec of spec.arguments) {
1281
1377
  if (an.args[i]) targetValue += `${wrapProp(aSpec.name)}: ${aSpec.type === "string" ? `"${escapeQuotes(an.args[i]?.text)}"` : an.args[i]?.text}${i === length - 1 ? "" : ", "} `;
1282
- else {}
1283
1378
  i++;
1284
1379
  }
1285
1380
  targetValue += "}";
@@ -1292,11 +1387,52 @@ else targetValue = "true";
1292
1387
  multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
1293
1388
  if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
1294
1389
  }
1295
- if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue}, true)`);
1296
- else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue})`);
1390
+ return {
1391
+ value: targetValue,
1392
+ multiple: !!multiple
1393
+ };
1394
+ }
1395
+ renderMutatingAnnotates() {
1396
+ for (const node of this.mutatingAnnotates) {
1397
+ const targetName = node.targetName;
1398
+ for (const entry of node.entries) {
1399
+ const anns = entry.annotations;
1400
+ if (!anns || anns.length === 0) continue;
1401
+ const parts = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)] : [entry.id];
1402
+ let accessor = targetName;
1403
+ for (const part of parts) accessor += `.type.props.get("${escapeQuotes(part)}")?`;
1404
+ for (const an of anns) {
1405
+ const { value, multiple } = this.computeAnnotationValue(entry, an);
1406
+ if (multiple) {
1407
+ this.writeln(`{`);
1408
+ this.indent();
1409
+ this.writeln(`const __t = ${accessor}.metadata`);
1410
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1411
+ this.writeln(`const __v = ${value}`);
1412
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1413
+ this.unindent();
1414
+ this.writeln(`}`);
1415
+ } else this.writeln(`${accessor}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1416
+ }
1417
+ }
1418
+ const topAnnotations = node.annotations;
1419
+ if (topAnnotations && topAnnotations.length > 0) for (const an of topAnnotations) {
1420
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1421
+ if (multiple) {
1422
+ this.writeln(`{`);
1423
+ this.indent();
1424
+ this.writeln(`const __t = ${targetName}.metadata`);
1425
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1426
+ this.writeln(`const __v = ${value}`);
1427
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1428
+ this.unindent();
1429
+ this.writeln(`}`);
1430
+ } else this.writeln(`${targetName}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1431
+ }
1432
+ }
1297
1433
  }
1298
1434
  constructor(doc, opts) {
1299
- super(doc), _define_property(this, "opts", void 0), _define_property(this, "postAnnotate", void 0), this.opts = opts, this.postAnnotate = [];
1435
+ super(doc), _define_property(this, "opts", void 0), _define_property(this, "postAnnotate", void 0), _define_property(this, "mutatingAnnotates", void 0), _define_property(this, "_adHocAnnotations", void 0), _define_property(this, "_propPath", void 0), this.opts = opts, this.postAnnotate = [], this.mutatingAnnotates = [], this._adHocAnnotations = null, this._propPath = [];
1300
1436
  }
1301
1437
  };
1302
1438
 
package/dist/index.mjs CHANGED
@@ -126,6 +126,7 @@ var BaseRenderer = class extends CodePrinter {
126
126
  }
127
127
  renderInterface(node) {}
128
128
  renderType(node) {}
129
+ renderAnnotate(node) {}
129
130
  transformFromPath(path$1) {
130
131
  return `${path$1}.as`;
131
132
  }
@@ -160,6 +161,10 @@ var BaseRenderer = class extends CodePrinter {
160
161
  this.renderImport(node);
161
162
  break;
162
163
  }
164
+ case "annotate": {
165
+ this.renderAnnotate(node);
166
+ break;
167
+ }
163
168
  default: break;
164
169
  }
165
170
  }
@@ -319,6 +324,26 @@ else this.writeln("{}");
319
324
  this.writeln();
320
325
  this.renderTypeNamespace(node);
321
326
  }
327
+ renderAnnotate(node) {
328
+ if (node.isMutating) return;
329
+ const targetName = node.targetName;
330
+ const unwound = this.doc.unwindType(targetName);
331
+ if (!unwound?.def) return;
332
+ const def = this.doc.mergeIntersection(unwound.def);
333
+ this.writeln();
334
+ const exported = node.token("export")?.text === "export";
335
+ this.renderJsDoc(node);
336
+ if (isStructure(def) || isInterface(def)) {
337
+ this.write(exported ? "export declare " : "declare ");
338
+ this.write(`class ${node.id} `);
339
+ this.renderStructure(def, node.id);
340
+ } else {
341
+ this.write(exported ? "export " : "declare ");
342
+ this.write(`type ${node.id} = `);
343
+ this.renderTypeDef(def);
344
+ }
345
+ this.writeln();
346
+ }
322
347
  renderTypeNamespace(node) {
323
348
  this.write(`declare namespace ${node.id} `);
324
349
  this.blockln("{}");
@@ -920,36 +945,58 @@ var JsRenderer = class extends BaseRenderer {
920
945
  if (!this.opts?.preRenderJsonSchema) imports.push("buildJsonSchema as $$");
921
946
  this.writeln(`import { ${imports.join(", ")} } from "@atscript/typescript/utils"`);
922
947
  }
948
+ buildAdHocMap(annotateNodes) {
949
+ const map = new Map();
950
+ for (const annotateNode of annotateNodes) for (const entry of annotateNode.entries) {
951
+ const path$1 = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)].join(".") : entry.id;
952
+ const anns = entry.annotations || [];
953
+ if (anns.length > 0) {
954
+ const existing = map.get(path$1);
955
+ map.set(path$1, existing ? [...existing, ...anns] : anns);
956
+ }
957
+ }
958
+ return map.size > 0 ? map : null;
959
+ }
923
960
  post() {
924
- for (const node of this.postAnnotate) {
961
+ for (const node of this.postAnnotate) if (node.entity === "annotate") {
962
+ const annotateNode = node;
963
+ const unwound = this.doc.unwindType(annotateNode.targetName);
964
+ if (unwound?.def) {
965
+ let def = this.doc.mergeIntersection(unwound.def);
966
+ if (isInterface(def)) def = def.getDefinition() || def;
967
+ this._adHocAnnotations = this.buildAdHocMap([annotateNode]);
968
+ this.annotateType(def, node.id);
969
+ this._adHocAnnotations = null;
970
+ this.indent();
971
+ this.defineMetadataForAnnotateAlias(annotateNode);
972
+ this.unindent();
973
+ this.writeln();
974
+ }
975
+ } else {
976
+ const mutatingNodes = this.doc.getAnnotateNodesFor(node.id).filter((n) => n.isMutating);
977
+ this._adHocAnnotations = this.buildAdHocMap(mutatingNodes);
925
978
  this.annotateType(node.getDefinition(), node.id);
979
+ this._adHocAnnotations = null;
926
980
  this.indent().defineMetadata(node).unindent();
927
981
  this.writeln();
928
982
  }
983
+ this.renderMutatingAnnotates();
929
984
  this.writeln("// prettier-ignore-end");
930
985
  super.post();
931
986
  }
987
+ renderClassStatics(node) {
988
+ this.writeln("static __is_atscript_annotated_type = true");
989
+ this.writeln("static type = {}");
990
+ this.writeln("static metadata = new Map()");
991
+ this.renderJsonSchemaMethod(node);
992
+ }
932
993
  renderInterface(node) {
933
994
  this.writeln();
934
995
  const exported = node.token("export")?.text === "export";
935
996
  this.write(exported ? "export " : "");
936
997
  this.write(`class ${node.id} `);
937
998
  this.blockln("{}");
938
- this.writeln("static __is_atscript_annotated_type = true");
939
- this.writeln("static type = {}");
940
- this.writeln("static metadata = new Map()");
941
- if (this.opts?.preRenderJsonSchema) {
942
- const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
943
- this.writeln(`static _jsonSchema = ${schema}`);
944
- this.writeln("static toJsonSchema() {");
945
- this.indent().writeln("return this._jsonSchema").unindent();
946
- this.writeln("}");
947
- } else {
948
- this.writeln("static _jsonSchema");
949
- this.writeln("static toJsonSchema() {");
950
- this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
951
- this.writeln("}");
952
- }
999
+ this.renderClassStatics(node);
953
1000
  this.popln();
954
1001
  this.postAnnotate.push(node);
955
1002
  this.writeln();
@@ -960,24 +1007,40 @@ var JsRenderer = class extends BaseRenderer {
960
1007
  this.write(exported ? "export " : "");
961
1008
  this.write(`class ${node.id} `);
962
1009
  this.blockln("{}");
963
- this.writeln("static __is_atscript_annotated_type = true");
964
- this.writeln("static type = {}");
965
- this.writeln("static metadata = new Map()");
1010
+ this.renderClassStatics(node);
1011
+ this.popln();
1012
+ this.postAnnotate.push(node);
1013
+ this.writeln();
1014
+ }
1015
+ renderAnnotate(node) {
1016
+ if (node.isMutating) {
1017
+ this.mutatingAnnotates.push(node);
1018
+ return;
1019
+ }
1020
+ const targetName = node.targetName;
1021
+ const unwound = this.doc.unwindType(targetName);
1022
+ if (!unwound?.def) return;
1023
+ this.writeln();
1024
+ const exported = node.token("export")?.text === "export";
1025
+ this.write(exported ? "export " : "");
1026
+ this.write(`class ${node.id} `);
1027
+ this.blockln("{}");
1028
+ this.renderClassStatics(node);
1029
+ this.popln();
1030
+ this.postAnnotate.push(node);
1031
+ this.writeln();
1032
+ }
1033
+ renderJsonSchemaMethod(node) {
966
1034
  if (this.opts?.preRenderJsonSchema) {
967
1035
  const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
968
- this.writeln(`static _jsonSchema = ${schema}`);
969
1036
  this.writeln("static toJsonSchema() {");
970
- this.indent().writeln("return this._jsonSchema").unindent();
1037
+ this.indent().writeln(`return ${schema}`).unindent();
971
1038
  this.writeln("}");
972
1039
  } else {
973
- this.writeln("static _jsonSchema");
974
1040
  this.writeln("static toJsonSchema() {");
975
1041
  this.indent().writeln("return this._jsonSchema ?? (this._jsonSchema = $$(this))").unindent();
976
1042
  this.writeln("}");
977
1043
  }
978
- this.popln();
979
- this.postAnnotate.push(node);
980
- this.writeln();
981
1044
  }
982
1045
  toAnnotatedType(node) {
983
1046
  return this.toAnnotatedHandle(node).$type;
@@ -1208,6 +1271,7 @@ else handle.prop(prop.id, propHandle.$type);
1208
1271
  for (const prop of props) {
1209
1272
  const pattern = prop.token("identifier")?.pattern;
1210
1273
  const optional = !!prop.token("optional");
1274
+ this._propPath.push(prop.id);
1211
1275
  if (pattern) {
1212
1276
  this.writeln(`.propPattern(`);
1213
1277
  this.indent();
@@ -1223,6 +1287,7 @@ else handle.prop(prop.id, propHandle.$type);
1223
1287
  this.writeln(" .$type");
1224
1288
  this.unindent();
1225
1289
  this.write(`)`);
1290
+ this._propPath.pop();
1226
1291
  }
1227
1292
  this.writeln();
1228
1293
  return this;
@@ -1238,12 +1303,43 @@ else handle.prop(prop.id, propHandle.$type);
1238
1303
  }
1239
1304
  defineMetadata(node) {
1240
1305
  const annotations = this.doc.evalAnnotationsForNode(node);
1306
+ let adHocNames;
1307
+ let adHoc;
1308
+ if (this._adHocAnnotations && this._propPath.length > 0) {
1309
+ const path$1 = this._propPath.join(".");
1310
+ adHoc = this._adHocAnnotations.get(path$1);
1311
+ if (adHoc) adHocNames = new Set(adHoc.map((a) => a.name));
1312
+ }
1241
1313
  annotations?.forEach((an) => {
1314
+ if (!adHocNames || !adHocNames.has(an.name)) this.resolveAnnotationValue(node, an);
1315
+ });
1316
+ adHoc?.forEach((an) => {
1242
1317
  this.resolveAnnotationValue(node, an);
1243
1318
  });
1244
1319
  return this;
1245
1320
  }
1321
+ /**
1322
+ * For non-mutating annotate aliases: merge the target's type-level annotations
1323
+ * with the annotate block's own annotations (annotate's take priority).
1324
+ */ defineMetadataForAnnotateAlias(annotateNode) {
1325
+ const annotateAnnotations = this.doc.evalAnnotationsForNode(annotateNode);
1326
+ const targetDecl = this.doc.getDeclarationOwnerNode(annotateNode.targetName);
1327
+ const targetAnnotations = targetDecl?.node ? targetDecl.doc.evalAnnotationsForNode(targetDecl.node) : undefined;
1328
+ const overriddenNames = new Set(annotateAnnotations?.map((a) => a.name));
1329
+ targetAnnotations?.forEach((an) => {
1330
+ if (!overriddenNames.has(an.name)) this.resolveAnnotationValue(annotateNode, an);
1331
+ });
1332
+ annotateAnnotations?.forEach((an) => {
1333
+ this.resolveAnnotationValue(annotateNode, an);
1334
+ });
1335
+ return this;
1336
+ }
1246
1337
  resolveAnnotationValue(node, an) {
1338
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1339
+ if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value}, true)`);
1340
+ else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
1341
+ }
1342
+ computeAnnotationValue(node, an) {
1247
1343
  const spec = this.doc.resolveAnnotation(an.name);
1248
1344
  let targetValue = "true";
1249
1345
  let multiple = false;
@@ -1255,7 +1351,6 @@ else handle.prop(prop.id, propHandle.$type);
1255
1351
  let i = 0;
1256
1352
  for (const aSpec of spec.arguments) {
1257
1353
  if (an.args[i]) targetValue += `${wrapProp(aSpec.name)}: ${aSpec.type === "string" ? `"${escapeQuotes(an.args[i]?.text)}"` : an.args[i]?.text}${i === length - 1 ? "" : ", "} `;
1258
- else {}
1259
1354
  i++;
1260
1355
  }
1261
1356
  targetValue += "}";
@@ -1268,11 +1363,52 @@ else targetValue = "true";
1268
1363
  multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
1269
1364
  if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
1270
1365
  }
1271
- if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue}, true)`);
1272
- else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${targetValue})`);
1366
+ return {
1367
+ value: targetValue,
1368
+ multiple: !!multiple
1369
+ };
1370
+ }
1371
+ renderMutatingAnnotates() {
1372
+ for (const node of this.mutatingAnnotates) {
1373
+ const targetName = node.targetName;
1374
+ for (const entry of node.entries) {
1375
+ const anns = entry.annotations;
1376
+ if (!anns || anns.length === 0) continue;
1377
+ const parts = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)] : [entry.id];
1378
+ let accessor = targetName;
1379
+ for (const part of parts) accessor += `.type.props.get("${escapeQuotes(part)}")?`;
1380
+ for (const an of anns) {
1381
+ const { value, multiple } = this.computeAnnotationValue(entry, an);
1382
+ if (multiple) {
1383
+ this.writeln(`{`);
1384
+ this.indent();
1385
+ this.writeln(`const __t = ${accessor}.metadata`);
1386
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1387
+ this.writeln(`const __v = ${value}`);
1388
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1389
+ this.unindent();
1390
+ this.writeln(`}`);
1391
+ } else this.writeln(`${accessor}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1392
+ }
1393
+ }
1394
+ const topAnnotations = node.annotations;
1395
+ if (topAnnotations && topAnnotations.length > 0) for (const an of topAnnotations) {
1396
+ const { value, multiple } = this.computeAnnotationValue(node, an);
1397
+ if (multiple) {
1398
+ this.writeln(`{`);
1399
+ this.indent();
1400
+ this.writeln(`const __t = ${targetName}.metadata`);
1401
+ this.writeln(`const __k = "${escapeQuotes(an.name)}"`);
1402
+ this.writeln(`const __v = ${value}`);
1403
+ this.writeln(`if (__t) { const __e = __t.get(__k); __t.set(__k, Array.isArray(__e) ? [...__e, __v] : __e !== undefined ? [__e, __v] : [__v]) }`);
1404
+ this.unindent();
1405
+ this.writeln(`}`);
1406
+ } else this.writeln(`${targetName}.metadata.set("${escapeQuotes(an.name)}", ${value})`);
1407
+ }
1408
+ }
1273
1409
  }
1274
1410
  constructor(doc, opts) {
1275
- super(doc), _define_property(this, "opts", void 0), _define_property(this, "postAnnotate", void 0), this.opts = opts, this.postAnnotate = [];
1411
+ super(doc), _define_property(this, "opts", void 0), _define_property(this, "postAnnotate", void 0), _define_property(this, "mutatingAnnotates", void 0), _define_property(this, "_adHocAnnotations", void 0), _define_property(this, "_propPath", void 0), this.opts = opts, this.postAnnotate = [], this.mutatingAnnotates = [], this._adHocAnnotations = null, this._propPath = [];
1276
1412
  }
1277
1413
  };
1278
1414
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/typescript",
3
- "version": "0.0.32",
3
+ "version": "0.1.1",
4
4
  "description": "Atscript: typescript-gen support.",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -70,7 +70,7 @@
70
70
  "homepage": "https://github.com/moostjs/atscript/tree/main/packages/typescript#readme",
71
71
  "license": "ISC",
72
72
  "peerDependencies": {
73
- "@atscript/core": "^0.0.32"
73
+ "@atscript/core": "^0.1.1"
74
74
  },
75
75
  "dependencies": {
76
76
  "@moostjs/event-cli": "^0.5.32",