@neocompose/cli 0.19.2 → 0.19.3

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.
Files changed (2) hide show
  1. package/dist/neo.mjs +149 -5
  2. package/package.json +1 -1
package/dist/neo.mjs CHANGED
@@ -21593,6 +21593,14 @@ var init_project_source_type_checker = __esm({
21593
21593
  });
21594
21594
 
21595
21595
  // ../packages/neoscript-language/src/project-source-analysis.ts
21596
+ function isSystemReservedRecordId(id2) {
21597
+ if (id2 === null) return false;
21598
+ if (id2.startsWith(SYSTEM_RECORD_ID_PREFIX)) return true;
21599
+ if (QUARANTINED_LEGACY_SYSTEM_RECORD_IDS.has(id2)) return true;
21600
+ return QUARANTINED_LEGACY_SYSTEM_ID_PREFIXES.some(
21601
+ (prefix) => id2.startsWith(prefix)
21602
+ );
21603
+ }
21596
21604
  function isEnumOptionId(id2) {
21597
21605
  if (isPendingId(id2)) return true;
21598
21606
  if (id2.startsWith(SYSTEM_RECORD_ID_PREFIX)) {
@@ -21637,6 +21645,7 @@ function analyzeNeoProjectSources(inputs) {
21637
21645
  }
21638
21646
  }
21639
21647
  validateSymbolUniqueness(symbols, diagnostics);
21648
+ validateSystemAnnotationAuthoring(documents, diagnostics);
21640
21649
  validateTypeReferences(documents, symbols, diagnostics);
21641
21650
  diagnostics.push(...validateProjectSourceTypes(documents));
21642
21651
  diagnostics.push(...validateProjectSourceSettlement(documents));
@@ -21930,6 +21939,124 @@ function sourceId(uri, annotations, diagnostics) {
21930
21939
  }
21931
21940
  return id2;
21932
21941
  }
21942
+ function declaredIdValue(annotations) {
21943
+ const annotation2 = annotations.find((entry) => entry.name === "id");
21944
+ if (annotation2 === void 0) return null;
21945
+ if (annotation2.arguments.length !== 1) return null;
21946
+ const id2 = decodeStringLiteral(annotation2.arguments[0].text);
21947
+ if (id2 === null || id2.length === 0) return null;
21948
+ return id2;
21949
+ }
21950
+ function systemAnnotation(annotations) {
21951
+ return annotations.find((entry) => entry.name === "system");
21952
+ }
21953
+ function validateSystemAnnotationAuthoring(documents, diagnostics) {
21954
+ const owners = /* @__PURE__ */ new Map();
21955
+ for (const [uri, document] of documents) {
21956
+ for (const declaration of document.declarations) {
21957
+ if (declaration.kind !== "class" && declaration.kind !== "interface") {
21958
+ continue;
21959
+ }
21960
+ const key = declaration.name.toLowerCase();
21961
+ if (!owners.has(key)) owners.set(key, { uri, declaration });
21962
+ }
21963
+ }
21964
+ for (const [uri, document] of documents) {
21965
+ for (const declaration of document.declarations) {
21966
+ const declarationAnnotation = systemAnnotation(declaration.annotations);
21967
+ const declarationId = declaredIdValue(declaration.annotations);
21968
+ if (declarationAnnotation !== void 0 && !isSystemReservedRecordId(declarationId)) {
21969
+ diagnostics.push(
21970
+ authoredSystemDiagnostic(
21971
+ uri,
21972
+ declarationAnnotation,
21973
+ declaration.name,
21974
+ declarationId
21975
+ )
21976
+ );
21977
+ }
21978
+ if (declaration.kind !== "class" && declaration.kind !== "interface") {
21979
+ continue;
21980
+ }
21981
+ for (const member of declaration.members) {
21982
+ const annotation2 = systemAnnotation(member.annotations);
21983
+ if (annotation2 === void 0) continue;
21984
+ const memberId = declaredIdValue(member.annotations);
21985
+ if (isSystemReservedRecordId(memberId)) continue;
21986
+ const label = `${declaration.name}.${member.name}`;
21987
+ const inherited = inheritedSystemMember(
21988
+ declaration,
21989
+ member.name,
21990
+ owners
21991
+ );
21992
+ if (inherited === null) {
21993
+ diagnostics.push(
21994
+ authoredSystemDiagnostic(uri, annotation2, label, memberId)
21995
+ );
21996
+ continue;
21997
+ }
21998
+ diagnostics.push({
21999
+ uri,
22000
+ range: annotation2.range,
22001
+ severity: "error",
22002
+ source: "neo-project",
22003
+ code: "authored-system-annotation-on-override",
22004
+ message: `@system on '${label}' is platform protection metadata Neo Compose sets on its own records. '${inherited.site.declaration.name}.${inherited.member.name}' carries it because the platform owns that record; carrying it on your own override would lock you out of editing or deleting it. Remove @system from the override.`,
22005
+ relatedInformation: [
22006
+ {
22007
+ location: {
22008
+ uri: inherited.site.uri,
22009
+ range: inherited.member.nameRange
22010
+ },
22011
+ message: "The protected base member is declared here."
22012
+ }
22013
+ ]
22014
+ });
22015
+ }
22016
+ }
22017
+ }
22018
+ }
22019
+ function authoredSystemDiagnostic(uri, annotation2, label, id2) {
22020
+ return {
22021
+ uri,
22022
+ range: annotation2.range,
22023
+ severity: "error",
22024
+ source: "neo-project",
22025
+ code: "authored-system-annotation",
22026
+ message: `@system on '${label}' is platform protection metadata Neo Compose sets on its own records, and ${systemIdentityClause(label, id2)}. Remove @system.`
22027
+ };
22028
+ }
22029
+ function systemIdentityClause(label, id2) {
22030
+ if (id2 === null) {
22031
+ return `'${label}' declares no @id, so it is a project record this push would create`;
22032
+ }
22033
+ return `@id '${id2}' is not in the reserved '${SYSTEM_RECORD_ID_PREFIX}' namespace`;
22034
+ }
22035
+ function inheritedSystemMember(declaration, memberName, owners) {
22036
+ const target = memberName.toLowerCase();
22037
+ const seen = /* @__PURE__ */ new Set([declaration.name.toLowerCase()]);
22038
+ const queue = baseSites(declaration, owners);
22039
+ while (queue.length > 0) {
22040
+ const site = queue.shift();
22041
+ const key = site.declaration.name.toLowerCase();
22042
+ if (seen.has(key)) continue;
22043
+ seen.add(key);
22044
+ const member = site.declaration.members.find(
22045
+ (entry) => entry.name.toLowerCase() === target && systemAnnotation(entry.annotations) !== void 0
22046
+ );
22047
+ if (member !== void 0) return { site, member };
22048
+ queue.push(...baseSites(site.declaration, owners));
22049
+ }
22050
+ return null;
22051
+ }
22052
+ function baseSites(declaration, owners) {
22053
+ const sites = [];
22054
+ for (const base of declaration.baseTypes) {
22055
+ const site = owners.get(base.name.toLowerCase());
22056
+ if (site !== void 0) sites.push(site);
22057
+ }
22058
+ return sites;
22059
+ }
21933
22060
  function validateSymbolUniqueness(symbols, diagnostics) {
21934
22061
  const names = /* @__PURE__ */ new Map();
21935
22062
  const ids = /* @__PURE__ */ new Map();
@@ -22115,7 +22242,7 @@ function emptyRange2() {
22115
22242
  end: { line: 0, character: 0 }
22116
22243
  };
22117
22244
  }
22118
- var BUILTIN_TYPE_NAMES, RESERVED_NAMES3, SYSTEM_RECORD_ID_PREFIX, RFC_4122_UUID;
22245
+ var BUILTIN_TYPE_NAMES, RESERVED_NAMES3, SYSTEM_RECORD_ID_PREFIX, RFC_4122_UUID, QUARANTINED_LEGACY_SYSTEM_ID_PREFIXES, QUARANTINED_LEGACY_SYSTEM_RECORD_IDS;
22119
22246
  var init_project_source_analysis = __esm({
22120
22247
  "../packages/neoscript-language/src/project-source-analysis.ts"() {
22121
22248
  "use strict";
@@ -22150,6 +22277,23 @@ var init_project_source_analysis = __esm({
22150
22277
  RESERVED_NAMES3 = new Set(NEOSCRIPT_KEYWORDS);
22151
22278
  SYSTEM_RECORD_ID_PREFIX = "system_";
22152
22279
  RFC_4122_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
22280
+ QUARANTINED_LEGACY_SYSTEM_ID_PREFIXES = [
22281
+ "neo-tile-grid-record-relations-v1-member-"
22282
+ ];
22283
+ QUARANTINED_LEGACY_SYSTEM_RECORD_IDS = /* @__PURE__ */ new Set([
22284
+ "430fca56-b45a-4896-9ab2-795a3faf57f6",
22285
+ // VaultPlaqueObject.PlacementTiles
22286
+ "47c21aa5-e852-41d2-882c-b4f555aee9dd",
22287
+ // PlayerSpawnObject.PlacementTiles
22288
+ "571a0e0b-b36c-45f3-ae9a-5fde39045c11",
22289
+ // ExitPromptObject.PlacementTiles
22290
+ "8e8c5ddf-6273-4440-869e-f1f9ca5dc51b",
22291
+ // ExitPromptObject.Size
22292
+ "94472662-a3a9-4c02-8abb-6229442e1e49",
22293
+ // RecoveryCacheObject.Collider
22294
+ "d8e9ad0e-157f-4709-96a7-8775efa3dd11"
22295
+ // RecoveryCacheObject.PlacementTiles
22296
+ ]);
22153
22297
  }
22154
22298
  });
22155
22299
 
@@ -45118,7 +45262,7 @@ ${namedArguments(
45118
45262
  function emitLocalizationStatus(status, identifier2, names) {
45119
45263
  const annotations = [
45120
45264
  id(status.id).trimEnd(),
45121
- ...status.system ? [systemAnnotation(status.system)] : []
45265
+ ...status.system ? [systemAnnotation2(status.system)] : []
45122
45266
  ];
45123
45267
  const statusReference = (value) => value === null ? "null" : names.get(value) ?? `Reference<LocalizationStatus>(id: ${quote(value)})`;
45124
45268
  return `${annotations.join("\n")}
@@ -45162,7 +45306,7 @@ function emitClass(context, schemaClass2, memberIds) {
45162
45306
  ...schemaClass2.targetMemberId ? [
45163
45307
  `@settings(target: ${qualifiedMember(context, schemaClass2.targetMemberId)})`
45164
45308
  ] : [],
45165
- ...schemaClass2.system ? [systemAnnotation(schemaClass2.system)] : [],
45309
+ ...schemaClass2.system ? [systemAnnotation2(schemaClass2.system)] : [],
45166
45310
  ...relationsAnnotations(context, schemaClass2)
45167
45311
  ];
45168
45312
  const modifier = schemaClass2.declarationModifier === "abstract" ? "abstract " : "";
@@ -45377,7 +45521,7 @@ function emitMember(context, member, enclosingClassId) {
45377
45521
  ] : [],
45378
45522
  ...memberSettings(context, member),
45379
45523
  ...listAnnotations(member),
45380
- ...member.system ? [systemAnnotation(member.system)] : []
45524
+ ...member.system ? [systemAnnotation2(member.system)] : []
45381
45525
  ];
45382
45526
  const prefix = memberModifier3(member);
45383
45527
  if (member.kind === "computed") {
@@ -46177,7 +46321,7 @@ function genericName(context, idValue) {
46177
46321
  }
46178
46322
  throw new Error(`Unknown generic parameter ${quote(idValue)}.`);
46179
46323
  }
46180
- function systemAnnotation(system) {
46324
+ function systemAnnotation2(system) {
46181
46325
  const args = [
46182
46326
  `kind: .${enumCase(system.kind)}`,
46183
46327
  ...system.worldKind ? [`worldKind: .${enumCase(system.worldKind)}`] : []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.19.2",
3
+ "version": "0.19.3",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",