proschi 0.5.0 → 0.6.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.
package/dist/cli.cjs CHANGED
@@ -15479,22 +15479,30 @@ function stripTrailingComment(text) {
15479
15479
  }
15480
15480
  return text;
15481
15481
  }
15482
- function bracketDepth(text) {
15483
- let depth = 0;
15484
- let inString = false;
15485
- for (let i = 0; i < text.length; i++) {
15486
- const ch = text[i];
15487
- if (inString) {
15488
- if (ch === "\\") i++;
15489
- else if (ch === '"') inString = false;
15490
- continue;
15482
+ var BracketCounter = class {
15483
+ depth = 0;
15484
+ inString = false;
15485
+ escaped = false;
15486
+ /** Adds `text` and returns the depth so far. */
15487
+ feed(text) {
15488
+ for (let i = 0; i < text.length; i++) {
15489
+ const ch = text[i];
15490
+ if (this.escaped) {
15491
+ this.escaped = false;
15492
+ continue;
15493
+ }
15494
+ if (this.inString) {
15495
+ if (ch === "\\") this.escaped = true;
15496
+ else if (ch === '"') this.inString = false;
15497
+ continue;
15498
+ }
15499
+ if (ch === '"') this.inString = true;
15500
+ else if (ch === "{" || ch === "[") this.depth++;
15501
+ else if (ch === "}" || ch === "]") this.depth--;
15491
15502
  }
15492
- if (ch === '"') inString = true;
15493
- else if (ch === "{" || ch === "[") depth++;
15494
- else if (ch === "}" || ch === "]") depth--;
15503
+ return this.depth;
15495
15504
  }
15496
- return depth;
15497
- }
15505
+ };
15498
15506
 
15499
15507
  // ../frontend/src/dsl/paths.ts
15500
15508
  var PARAM2 = /^\{[^{}/]+\}$/;
@@ -15677,6 +15685,7 @@ var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
15677
15685
  var DEFAULT_TECH = "Rectangle";
15678
15686
  var DEFAULT_GROUP_TECH = "Logical Group";
15679
15687
  var MAX_SCENARIOS = 32;
15688
+ var MAX_ALT_DEPTH = 16;
15680
15689
  var REPLICAS = /^x(\d+)$/;
15681
15690
  var PERCENTILES = { p50: 50, p90: 90, p95: 95, p99: 99, p999: 99.9 };
15682
15691
  var FIELD_FLAGS = ["key", "index", "unique", "optional"];
@@ -15704,8 +15713,12 @@ var Parser = class {
15704
15713
  file;
15705
15714
  stack = [];
15706
15715
  diagnostics = [];
15716
+ /** Warnings reported so far (see `warning`). */
15717
+ warned = /* @__PURE__ */ new Set();
15707
15718
  nodes = /* @__PURE__ */ new Map();
15708
15719
  edges = [];
15720
+ /** Connections so far per `from->to`, for the ids of repeated ones. */
15721
+ edgeCount = /* @__PURE__ */ new Map();
15709
15722
  useCases = [];
15710
15723
  references = [];
15711
15724
  imports = [];
@@ -15782,6 +15795,17 @@ var Parser = class {
15782
15795
  const loc = (t) => this.locOf(t, line);
15783
15796
  const top = this.top();
15784
15797
  if (top?.kind === "section") {
15798
+ if (top.skipped !== void 0) {
15799
+ const opens = tokens[tokens.length - 1].kind === "lbrace";
15800
+ if (first.kind !== "rbrace") top.nested = (top.nested ?? 0) + (opens ? 1 : 0);
15801
+ else if (top.nested) top.nested += opens ? 0 : -1;
15802
+ else {
15803
+ this.stack.pop();
15804
+ if (second?.kind === "ident" && second.value === "alt") this.parseAlt(tokens.slice(1), line);
15805
+ else if (second) this.error("Unexpected input after }", loc(second));
15806
+ }
15807
+ return index;
15808
+ }
15785
15809
  if (first.kind === "rbrace") {
15786
15810
  this.stack.pop();
15787
15811
  if (!top.discard) this.closeSection(top);
@@ -16006,6 +16030,12 @@ var Parser = class {
16006
16030
  return;
16007
16031
  }
16008
16032
  this.expectEnd(tokens, i + 1, line);
16033
+ if (this.stack.filter((f) => f.kind === "alt").length >= MAX_ALT_DEPTH) {
16034
+ const loc2 = this.locOf(keyword, line);
16035
+ this.error(`alt blocks can nest at most ${MAX_ALT_DEPTH} deep; this one is skipped`, loc2);
16036
+ this.stack.push({ kind: "section", section: "test", discard: true, skipped: `alt '${nameToken.value}'`, loc: loc2 });
16037
+ return;
16038
+ }
16009
16039
  const owner = top.body;
16010
16040
  let set = owner.openAlt;
16011
16041
  if (!set) {
@@ -16099,12 +16129,16 @@ var Parser = class {
16099
16129
  }
16100
16130
  let label = labelToken?.value ?? "";
16101
16131
  let lastLine = index;
16102
- if (bracketDepth(label) > 0) {
16103
- while (bracketDepth(label) > 0 && lastLine + 1 < this.lines.length) {
16132
+ const brackets = new BracketCounter();
16133
+ let depth = brackets.feed(label);
16134
+ if (depth > 0) {
16135
+ while (depth > 0 && lastLine + 1 < this.lines.length) {
16104
16136
  lastLine++;
16105
- label += "\n" + this.lines[lastLine];
16137
+ const more = "\n" + this.lines[lastLine];
16138
+ label += more;
16139
+ depth = brackets.feed(more);
16106
16140
  }
16107
- if (bracketDepth(label) > 0) this.error("Unclosed { or [ in payload", this.locOf(labelToken, line));
16141
+ if (depth > 0) this.error("Unclosed { or [ in payload", this.locOf(labelToken, line));
16108
16142
  label = label.trimEnd();
16109
16143
  }
16110
16144
  const loc = {
@@ -16139,7 +16173,8 @@ var Parser = class {
16139
16173
  this.error("'-x' marks a failed call and is only allowed in use case steps", this.locOf(arrowToken, line));
16140
16174
  } else {
16141
16175
  const base = `${from}->${to}`;
16142
- const count = this.edges.filter((e) => e.id === base || e.id.startsWith(`${base}#`)).length;
16176
+ const count = this.edgeCount.get(base) ?? 0;
16177
+ this.edgeCount.set(base, count + 1);
16143
16178
  this.edges.push({ id: count ? `${base}#${count + 1}` : base, source: from, target: to, label: unquote(label) || void 0, loc });
16144
16179
  }
16145
16180
  return lastLine;
@@ -17065,7 +17100,12 @@ var Parser = class {
17065
17100
  this.diagnostics.push({ severity: "error", message, ...loc });
17066
17101
  }
17067
17102
  warning(message, loc) {
17068
- if (this.diagnostics.some((d) => d.message === message && d.line === loc.line && d.col === loc.col && d.file === loc.file)) return;
17103
+ const key = `${loc.file ?? ""}
17104
+ ${loc.line}
17105
+ ${loc.col}
17106
+ ${message}`;
17107
+ if (this.warned.has(key)) return;
17108
+ this.warned.add(key);
17069
17109
  this.diagnostics.push({ severity: "warning", message, ...loc });
17070
17110
  }
17071
17111
  };
@@ -17098,6 +17138,7 @@ function isWord(token, word) {
17098
17138
  return token?.kind === "ident" && token.value === word;
17099
17139
  }
17100
17140
  function sectionName(frame) {
17141
+ if (frame.skipped) return frame.skipped;
17101
17142
  if (frame.entity) return `entity '${frame.entity.name}'`;
17102
17143
  if (frame.decision) return `decision '${frame.decision.title}'`;
17103
17144
  if (frame.test) return `test '${frame.test.name}'`;
@@ -17238,13 +17279,13 @@ function classify(lines) {
17238
17279
  }
17239
17280
  if (!inSection && first.kind === "ident" && second?.kind === "arrow" && third?.kind === "ident" && tokens.length <= 4 && (!fourth || fourth.kind === "label")) {
17240
17281
  const entry = { ...base, kind: "connection", from: first.value, arrow: second.value, to: third.value, label: fourth?.value, continuation: [] };
17241
- if (fourth && bracketDepth(fourth.value) > 0) {
17242
- const delta = depth * INDENT.length - width(leadingSpace(raw));
17243
- let label = fourth.value;
17244
- while (bracketDepth(label) > 0 && i + 1 < lines.length) {
17282
+ const brackets = new BracketCounter();
17283
+ if (fourth && brackets.feed(fourth.value) > 0) {
17284
+ const delta = indent(depth).length - width(leadingSpace(raw));
17285
+ while (i + 1 < lines.length) {
17245
17286
  const next = lines[++i];
17246
- label += "\n" + next;
17247
17287
  entry.continuation.push(reindent(next, delta));
17288
+ if (brackets.feed("\n" + next) <= 0) break;
17248
17289
  }
17249
17290
  while (entry.continuation[entry.continuation.length - 1] === "") entry.continuation.pop();
17250
17291
  }
@@ -17385,7 +17426,8 @@ var source = (raw, t) => {
17385
17426
  var withComment = (code, comment) => comment ? code + " " + comment : code;
17386
17427
  var leadingSpace = (line) => /^[ \t]*/.exec(line)[0];
17387
17428
  var width = (space) => [...space].reduce((n, ch) => n + (ch === " " ? INDENT.length : 1), 0);
17388
- var indent = (depth) => INDENT.repeat(depth);
17429
+ var MAX_INDENT = 32;
17430
+ var indent = (depth) => INDENT.repeat(Math.min(depth, MAX_INDENT));
17389
17431
  var len = (s) => [...s].length;
17390
17432
  var pad = (s, to) => s + " ".repeat(Math.max(0, to - len(s)));
17391
17433
 
@@ -19444,7 +19486,7 @@ ${PROBLEM_USAGE}`);
19444
19486
  }
19445
19487
 
19446
19488
  // src/cli.ts
19447
- var VERSION = true ? "0.5.0" : "dev";
19489
+ var VERSION = true ? "0.6.0" : "dev";
19448
19490
  var USAGE = `Usage:
19449
19491
  proschi check [--strict] [--format text|github|json] [--openapi <node>=<spec>]... <file|dir>...
19450
19492
  proschi parse <file>