@primmel/primmel 1.9.0 → 1.10.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.
@@ -4411,6 +4411,9 @@ var dumpMapProfile = function(mp) {
4411
4411
  };
4412
4412
 
4413
4413
  // src/ser-des/config/viewProfile.ts
4414
+ function parseListFacet(v) {
4415
+ return v.startsWith("{") || v.startsWith("[") ? tokenizePackage(v).map(stripWrapping) : [stripWrapping(v)];
4416
+ }
4414
4417
  var parseViewProfile = function(id, data) {
4415
4418
  const result = {
4416
4419
  id,
@@ -4425,9 +4428,9 @@ var parseViewProfile = function(id, data) {
4425
4428
  if (command === "description") {
4426
4429
  result.description = unwrapped(value);
4427
4430
  } else if (command === "roles") {
4428
- result.roles = tokenizePackage(value());
4431
+ result.roles = parseListFacet(value());
4429
4432
  } else if (command === "visible") {
4430
- result.visibleElements = tokenizePackage(value());
4433
+ result.visibleElements = parseListFacet(value());
4431
4434
  } else if (command === "against") {
4432
4435
  result.against = value().trim();
4433
4436
  } else {
@@ -4445,13 +4448,13 @@ var parseViewProfile = function(id, data) {
4445
4448
  var dumpViewProfile = function(vp) {
4446
4449
  let out = "view_profile " + vp.id + " {\n";
4447
4450
  if (vp.description) {
4448
- out += ' description "' + vp.description + '"\n';
4451
+ out += ' description "' + escapeString(vp.description) + '"\n';
4449
4452
  }
4450
4453
  if (vp.roles.length > 0) {
4451
- out += " roles " + vp.roles.join(" ") + "\n";
4454
+ out += " roles { " + vp.roles.map(dumpBareSafe).join(" ") + " }\n";
4452
4455
  }
4453
4456
  if (vp.visibleElements.length > 0) {
4454
- out += " visible " + vp.visibleElements.join(" ") + "\n";
4457
+ out += " visible { " + vp.visibleElements.map(dumpBareSafe).join(" ") + " }\n";
4455
4458
  }
4456
4459
  if (vp.against) {
4457
4460
  out += " against " + vp.against + "\n";
@@ -9197,7 +9200,7 @@ function dumpLimit(limit) {
9197
9200
  line += " kind " + limit.quantity.kind;
9198
9201
  }
9199
9202
  if (limit.quantity.unit) {
9200
- line += " unit " + limit.quantity.unit;
9203
+ line += ' unit "' + escapeString(limit.quantity.unit) + '"';
9201
9204
  }
9202
9205
  out += line + " }\n";
9203
9206
  }
@@ -14578,8 +14581,36 @@ function composePackage(rootDir, options, rootManifest, withProvenance = false)
14578
14581
  provenance.get(field).set(key, order[0]);
14579
14582
  }
14580
14583
  }
14584
+ const ownedScopes = /* @__PURE__ */ new Map();
14585
+ const harvestScopes = (id, ctx) => {
14586
+ for (const key of Object.keys(ctx.requirementClasses)) {
14587
+ if (!ownedScopes.has(key)) {
14588
+ ownedScopes.set(key, id);
14589
+ }
14590
+ }
14591
+ };
14592
+ const pinGuard = (id, next) => {
14593
+ if (ownedScopes.size === 0) {
14594
+ return;
14595
+ }
14596
+ for (const field of ["requirementClasses", "requirements"]) {
14597
+ const label = field === "requirementClasses" ? "requirement class" : "requirement";
14598
+ for (const key of Object.keys(next[field])) {
14599
+ for (const [scope, owner] of ownedScopes) {
14600
+ if (key.startsWith(scope + "/")) {
14601
+ throw new CompositionError(
14602
+ "namespace-pin-violation",
14603
+ `package "${id}" declares ${label} "${key}" under the requirement namespace "${scope}" owned by package "${owner}" \u2014 a layer-owned namespace is single-sourced: a downstream package may reference its provisions, never declare scopes or requirements at or under it (namespace-pin-violation)`
14604
+ );
14605
+ }
14606
+ }
14607
+ }
14608
+ }
14609
+ };
14610
+ harvestScopes(order[0], acc);
14581
14611
  for (const id of order.slice(1)) {
14582
14612
  const next = ctxs.get(id);
14613
+ pinGuard(id, next);
14583
14614
  for (const field of MERGE_FIELDS) {
14584
14615
  const target = acc[field];
14585
14616
  const pm = provenance.get(field);
@@ -14604,6 +14635,7 @@ function composePackage(rootDir, options, rootManifest, withProvenance = false)
14604
14635
  if (!acc.metadata && next.metadata) {
14605
14636
  acc.metadata = next.metadata;
14606
14637
  }
14638
+ harvestScopes(id, next);
14607
14639
  }
14608
14640
  for (const id of order) {
14609
14641
  const m = manifests.get(id);
@@ -16395,6 +16427,19 @@ var CHECK_RULES = [
16395
16427
  "normal",
16396
16428
  "TODO.roadmap/05"
16397
16429
  ),
16430
+ // C119 (the smart AGENTS.d/07 pin doctrine, TODO.editor/05 Q3): a
16431
+ // requirement scope a composed package declares is OWNED by that
16432
+ // package — a downstream package may reference its provisions, never
16433
+ // declare a requirement class or requirement at or under the owned
16434
+ // namespace (the strict-descendant leg; the exact-id leg is C28).
16435
+ R(
16436
+ "C119",
16437
+ "namespace-pin-violation",
16438
+ "composition",
16439
+ "error",
16440
+ "normal",
16441
+ "smart AGENTS.d/07 (TODO.editor/05 Q3)"
16442
+ ),
16398
16443
  // ── quantities / time / duality (TODO.roadmap/06) ─────────────────
16399
16444
  R(
16400
16445
  "C32",
@@ -18176,7 +18221,8 @@ function checkPackage(dir, options = {}) {
18176
18221
  "uses-resolves": "C27",
18177
18222
  "uses-no-redefine": "C28",
18178
18223
  "uses-cycle": "C29",
18179
- "requires-satisfied": "C31"
18224
+ "requires-satisfied": "C31",
18225
+ "namespace-pin-violation": "C119"
18180
18226
  };
18181
18227
  let standard;
18182
18228
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primmel/primmel",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Primmel — parser, types, and serializer for the Primmel modelling language (successor to MMEL)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",