webpipe-js 2.0.11 → 2.0.12

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/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  formatPipelineStep: () => formatPipelineStep,
26
26
  formatStepConfig: () => formatStepConfig,
27
27
  formatTag: () => formatTag,
28
+ formatTagExpr: () => formatTagExpr,
28
29
  formatTags: () => formatTags,
29
30
  formatWhen: () => formatWhen,
30
31
  getPipelineRanges: () => getPipelineRanges,
@@ -609,11 +610,69 @@ var Parser = class {
609
610
  this.skipSpaces();
610
611
  this.expect("case");
611
612
  this.skipInlineSpaces();
612
- const tag = this.parseTag();
613
+ const condition = this.parseTagExpr();
614
+ this.skipInlineSpaces();
613
615
  this.expect(":");
614
616
  this.skipSpaces();
615
617
  const pipeline = this.parseIfPipeline("case", "default:", "end");
616
- return { tag, pipeline };
618
+ return { condition, pipeline };
619
+ }
620
+ /**
621
+ * Parse a tag expression with boolean operators (and, or) and grouping
622
+ * Grammar (precedence: AND > OR):
623
+ * tag_expr := or_expr
624
+ * or_expr := and_expr ("or" and_expr)*
625
+ * and_expr := primary ("and" primary)*
626
+ * primary := tag | "(" tag_expr ")"
627
+ */
628
+ parseTagExpr() {
629
+ return this.parseOrExpr();
630
+ }
631
+ parseOrExpr() {
632
+ let left = this.parseAndExpr();
633
+ while (true) {
634
+ const saved = this.pos;
635
+ this.skipInlineSpaces();
636
+ if (this.text.startsWith("or", this.pos) && !this.isIdentCont(this.text[this.pos + 2] || "")) {
637
+ this.pos += 2;
638
+ this.skipInlineSpaces();
639
+ const right = this.parseAndExpr();
640
+ left = { kind: "Or", left, right };
641
+ } else {
642
+ this.pos = saved;
643
+ break;
644
+ }
645
+ }
646
+ return left;
647
+ }
648
+ parseAndExpr() {
649
+ let left = this.parseTagPrimary();
650
+ while (true) {
651
+ const saved = this.pos;
652
+ this.skipInlineSpaces();
653
+ if (this.text.startsWith("and", this.pos) && !this.isIdentCont(this.text[this.pos + 3] || "")) {
654
+ this.pos += 3;
655
+ this.skipInlineSpaces();
656
+ const right = this.parseTagPrimary();
657
+ left = { kind: "And", left, right };
658
+ } else {
659
+ this.pos = saved;
660
+ break;
661
+ }
662
+ }
663
+ return left;
664
+ }
665
+ parseTagPrimary() {
666
+ if (this.cur() === "(") {
667
+ this.pos++;
668
+ this.skipInlineSpaces();
669
+ const expr = this.parseTagExpr();
670
+ this.skipInlineSpaces();
671
+ this.expect(")");
672
+ return expr;
673
+ }
674
+ const tag = this.parseTag();
675
+ return { kind: "Tag", tag };
617
676
  }
618
677
  parseIfPipeline(...stopKeywords) {
619
678
  const steps = [];
@@ -1167,7 +1226,7 @@ function formatPipelineStep(step, indent = " ") {
1167
1226
  } else if (step.kind === "Dispatch") {
1168
1227
  const lines = [`${indent}|> dispatch`];
1169
1228
  step.branches.forEach((branch) => {
1170
- lines.push(`${indent} case ${formatTag(branch.tag)}:`);
1229
+ lines.push(`${indent} case ${formatTagExpr(branch.condition)}:`);
1171
1230
  branch.pipeline.steps.forEach((branchStep) => {
1172
1231
  lines.push(formatPipelineStep(branchStep, indent + " "));
1173
1232
  });
@@ -1206,6 +1265,19 @@ function formatTag(tag) {
1206
1265
  const args = tag.args.length > 0 ? `(${tag.args.join(",")})` : "";
1207
1266
  return `@${negation}${tag.name}${args}`;
1208
1267
  }
1268
+ function formatTagExpr(expr) {
1269
+ switch (expr.kind) {
1270
+ case "Tag":
1271
+ return formatTag(expr.tag);
1272
+ case "And": {
1273
+ const leftStr = expr.left.kind === "Or" ? `(${formatTagExpr(expr.left)})` : formatTagExpr(expr.left);
1274
+ const rightStr = expr.right.kind === "Or" ? `(${formatTagExpr(expr.right)})` : formatTagExpr(expr.right);
1275
+ return `${leftStr} and ${rightStr}`;
1276
+ }
1277
+ case "Or":
1278
+ return `${formatTagExpr(expr.left)} or ${formatTagExpr(expr.right)}`;
1279
+ }
1280
+ }
1209
1281
  function formatPipelineRef(ref) {
1210
1282
  if (ref.kind === "Named") {
1211
1283
  return [` |> pipeline: ${ref.name}`];
@@ -1234,6 +1306,7 @@ function formatWhen(when) {
1234
1306
  formatPipelineStep,
1235
1307
  formatStepConfig,
1236
1308
  formatTag,
1309
+ formatTagExpr,
1237
1310
  formatTags,
1238
1311
  formatWhen,
1239
1312
  getPipelineRanges,
package/dist/index.d.cts CHANGED
@@ -93,6 +93,19 @@ interface Tag {
93
93
  negated: boolean;
94
94
  args: string[];
95
95
  }
96
+ /** A boolean expression of tags for dispatch routing */
97
+ type TagExpr = {
98
+ kind: 'Tag';
99
+ tag: Tag;
100
+ } | {
101
+ kind: 'And';
102
+ left: TagExpr;
103
+ right: TagExpr;
104
+ } | {
105
+ kind: 'Or';
106
+ left: TagExpr;
107
+ right: TagExpr;
108
+ };
96
109
  type PipelineStep = {
97
110
  kind: 'Regular';
98
111
  name: string;
@@ -118,7 +131,7 @@ type PipelineStep = {
118
131
  pipeline: Pipeline;
119
132
  };
120
133
  interface DispatchBranch {
121
- tag: Tag;
134
+ condition: TagExpr;
122
135
  pipeline: Pipeline;
123
136
  }
124
137
  interface ResultBranch {
@@ -209,7 +222,8 @@ declare function formatPipelineStep(step: PipelineStep, indent?: string): string
209
222
  declare function formatStepConfig(config: string, configType: ConfigType): string;
210
223
  declare function formatTags(tags: Tag[]): string;
211
224
  declare function formatTag(tag: Tag): string;
225
+ declare function formatTagExpr(expr: TagExpr): string;
212
226
  declare function formatPipelineRef(ref: PipelineRef): string[];
213
227
  declare function formatWhen(when: When): string;
214
228
 
215
- export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
229
+ export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
package/dist/index.d.ts CHANGED
@@ -93,6 +93,19 @@ interface Tag {
93
93
  negated: boolean;
94
94
  args: string[];
95
95
  }
96
+ /** A boolean expression of tags for dispatch routing */
97
+ type TagExpr = {
98
+ kind: 'Tag';
99
+ tag: Tag;
100
+ } | {
101
+ kind: 'And';
102
+ left: TagExpr;
103
+ right: TagExpr;
104
+ } | {
105
+ kind: 'Or';
106
+ left: TagExpr;
107
+ right: TagExpr;
108
+ };
96
109
  type PipelineStep = {
97
110
  kind: 'Regular';
98
111
  name: string;
@@ -118,7 +131,7 @@ type PipelineStep = {
118
131
  pipeline: Pipeline;
119
132
  };
120
133
  interface DispatchBranch {
121
- tag: Tag;
134
+ condition: TagExpr;
122
135
  pipeline: Pipeline;
123
136
  }
124
137
  interface ResultBranch {
@@ -209,7 +222,8 @@ declare function formatPipelineStep(step: PipelineStep, indent?: string): string
209
222
  declare function formatStepConfig(config: string, configType: ConfigType): string;
210
223
  declare function formatTags(tags: Tag[]): string;
211
224
  declare function formatTag(tag: Tag): string;
225
+ declare function formatTagExpr(expr: TagExpr): string;
212
226
  declare function formatPipelineRef(ref: PipelineRef): string[];
213
227
  declare function formatWhen(when: When): string;
214
228
 
215
- export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
229
+ export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
package/dist/index.mjs CHANGED
@@ -560,11 +560,69 @@ var Parser = class {
560
560
  this.skipSpaces();
561
561
  this.expect("case");
562
562
  this.skipInlineSpaces();
563
- const tag = this.parseTag();
563
+ const condition = this.parseTagExpr();
564
+ this.skipInlineSpaces();
564
565
  this.expect(":");
565
566
  this.skipSpaces();
566
567
  const pipeline = this.parseIfPipeline("case", "default:", "end");
567
- return { tag, pipeline };
568
+ return { condition, pipeline };
569
+ }
570
+ /**
571
+ * Parse a tag expression with boolean operators (and, or) and grouping
572
+ * Grammar (precedence: AND > OR):
573
+ * tag_expr := or_expr
574
+ * or_expr := and_expr ("or" and_expr)*
575
+ * and_expr := primary ("and" primary)*
576
+ * primary := tag | "(" tag_expr ")"
577
+ */
578
+ parseTagExpr() {
579
+ return this.parseOrExpr();
580
+ }
581
+ parseOrExpr() {
582
+ let left = this.parseAndExpr();
583
+ while (true) {
584
+ const saved = this.pos;
585
+ this.skipInlineSpaces();
586
+ if (this.text.startsWith("or", this.pos) && !this.isIdentCont(this.text[this.pos + 2] || "")) {
587
+ this.pos += 2;
588
+ this.skipInlineSpaces();
589
+ const right = this.parseAndExpr();
590
+ left = { kind: "Or", left, right };
591
+ } else {
592
+ this.pos = saved;
593
+ break;
594
+ }
595
+ }
596
+ return left;
597
+ }
598
+ parseAndExpr() {
599
+ let left = this.parseTagPrimary();
600
+ while (true) {
601
+ const saved = this.pos;
602
+ this.skipInlineSpaces();
603
+ if (this.text.startsWith("and", this.pos) && !this.isIdentCont(this.text[this.pos + 3] || "")) {
604
+ this.pos += 3;
605
+ this.skipInlineSpaces();
606
+ const right = this.parseTagPrimary();
607
+ left = { kind: "And", left, right };
608
+ } else {
609
+ this.pos = saved;
610
+ break;
611
+ }
612
+ }
613
+ return left;
614
+ }
615
+ parseTagPrimary() {
616
+ if (this.cur() === "(") {
617
+ this.pos++;
618
+ this.skipInlineSpaces();
619
+ const expr = this.parseTagExpr();
620
+ this.skipInlineSpaces();
621
+ this.expect(")");
622
+ return expr;
623
+ }
624
+ const tag = this.parseTag();
625
+ return { kind: "Tag", tag };
568
626
  }
569
627
  parseIfPipeline(...stopKeywords) {
570
628
  const steps = [];
@@ -1118,7 +1176,7 @@ function formatPipelineStep(step, indent = " ") {
1118
1176
  } else if (step.kind === "Dispatch") {
1119
1177
  const lines = [`${indent}|> dispatch`];
1120
1178
  step.branches.forEach((branch) => {
1121
- lines.push(`${indent} case ${formatTag(branch.tag)}:`);
1179
+ lines.push(`${indent} case ${formatTagExpr(branch.condition)}:`);
1122
1180
  branch.pipeline.steps.forEach((branchStep) => {
1123
1181
  lines.push(formatPipelineStep(branchStep, indent + " "));
1124
1182
  });
@@ -1157,6 +1215,19 @@ function formatTag(tag) {
1157
1215
  const args = tag.args.length > 0 ? `(${tag.args.join(",")})` : "";
1158
1216
  return `@${negation}${tag.name}${args}`;
1159
1217
  }
1218
+ function formatTagExpr(expr) {
1219
+ switch (expr.kind) {
1220
+ case "Tag":
1221
+ return formatTag(expr.tag);
1222
+ case "And": {
1223
+ const leftStr = expr.left.kind === "Or" ? `(${formatTagExpr(expr.left)})` : formatTagExpr(expr.left);
1224
+ const rightStr = expr.right.kind === "Or" ? `(${formatTagExpr(expr.right)})` : formatTagExpr(expr.right);
1225
+ return `${leftStr} and ${rightStr}`;
1226
+ }
1227
+ case "Or":
1228
+ return `${formatTagExpr(expr.left)} or ${formatTagExpr(expr.right)}`;
1229
+ }
1230
+ }
1160
1231
  function formatPipelineRef(ref) {
1161
1232
  if (ref.kind === "Named") {
1162
1233
  return [` |> pipeline: ${ref.name}`];
@@ -1184,6 +1255,7 @@ export {
1184
1255
  formatPipelineStep,
1185
1256
  formatStepConfig,
1186
1257
  formatTag,
1258
+ formatTagExpr,
1187
1259
  formatTags,
1188
1260
  formatWhen,
1189
1261
  getPipelineRanges,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpipe-js",
3
- "version": "2.0.11",
3
+ "version": "2.0.12",
4
4
  "description": "Web Pipe parser",
5
5
  "license": "ISC",
6
6
  "author": "William Cotton",